version 1.6.7 対応 原著:まつもとゆきひろ
このリファレンスをよりよいものにするために 随時執筆者募集中です。あなたの参加を待ってます。
Ruby 言語仕様
標準ライブラリ
付録
下の「Link」で参照されるページにRubyリファレンスマニュアルの記述が不完 全な部分が含まれています。
あなたの記述をみんな待ってます。よろしく。
RDというフォーマットで書きます。 RDとは何ぞやという人はWhat is RDを見てみましょう。
記述を追加したいが内容に関していまいち自信がなかったりする場合、以下の いずれかの方法で問い合わせる
MLに参加してない人はあらい宛 に直接問い合わせても構わないです。
その他雑多なことに関しては Manuals styleも参照してください。
作業中のページ
ToDo
これらの課題や方針については rubyist ML で議論されています。
「new は initialize を呼ぶ。そうでないコンストラクタは呼ばない」 ことを明記する
チェック完 -> Proc
Thread は難しいので保留
メソッドの返り値の明記
ENV と ARGF がまだ。疲れたわい。
チェック完 -> Thread, Proc, 組込み関数 Object, Array, Binding, Continuation, Data, Exception, Dir, FalseClass, File::Stat, Hash, IO, File, MatchData, Method, UnboundMethod, Module, Class, Numeric, Integer, Bignum, Fixnum, Float, Proc, Process::Status, Range, Regexp, String, Struct, Symbol, Thread, ThreadGroup, Time, TrueClass, NilClass, Comparable, Enumerable, Errno, File::Constants, FileTest, GC, Kernel, Marshal, Math, ObjectSpace, Precision, Process, Signal, 全例外クラス
索引ページの更新(演算子形式等も索引に載るように)
クラスもオブジェクトであることに言及する。
MethodList 化
このマニュアルの配布条件を決める(?)
2001-04-28: Rubyの終了処理について書く(rubyist:0526)
「Rubyの文法」再構成に伴い、全体の記述の見直しと((<Rubyの文法>)) と参照している箇所を修正する
manual page の参照の仕方のページ
Ruby FAQをここに取り込む
「Rubyの文法」の再編成(検討中)
拡張ライブラリリファレンスマニュアル(書く人いる?)
Ruby
は手軽なオブジェクト指向プログラミングのためのインタプリタ言語です。
Ruby
は(Perlのような)テキスト処理やシステム管理のための豊富な機能を持っています。
また、Ruby
は単純で、分かりやすく、簡単に拡張できます。
もし、簡単なオブジェクト指向のための言語を求めていたり、
Perl
は見にくいと感じていたり、
Lispの考え方は好きだがあの括弧の多さには困ると感じているなら、
Ruby
はまさにぴったりです。
Ruby
の特長は次の通りです。
Ruby
はインタプリタ言語ですので
プログラムを実行するためにコンパイルする必要はありません。
Ruby
の変数はどのような型のデータも格納する事ができますので、
変数の型について心配する必要はありません。
半面、コンパイル時のチェックは弱くなります。
Ruby
では変数を宣言無しで使う事ができます。
変数の種類(ローカル変数、グローバル変数、インスタンス変数など)は
変数名から知る事ができます。
Ruby
の文法はEiffelからわずかに影響を受けた単純なものです。
Ruby
はメモリ管理を自動的に行います。
どこからもアクセスされなくなったオブジェクトは
インタプリタに組込みのガーベージコレクタによって回収されます。
Ruby
ははじめから純粋なオブジェクト指向言語として設計されています。
整数のような基本的なデータ型をはじめとして、
全てのデータをオブジェクトとして統一的に取り扱えます。
Ruby
は
クラス、継承、メソッドのようなオブジェクト指向言語として基本的な機能は
当然持っています。
ある特定のオブジェクトにメソッドを付加することができます。 たとえば、GUIのあるボタンを押された時の動作を メソッドとして記述するような使い方ができますし、 これを応用してプロトタイプベースの オブジェクト指向プログラミングも可能です(やりたければね)。
Ruby
は多重継承は複雑さの源であるという見地から、
意図的に多重継承を持っていませんが、
モジュールを使ってクラス階層を横断して実装を共有できます。
この機能を"Mix-in"と呼びます。
ループの抽象化を行うイテレータという機能があります。
手続きをオブジェクトとして扱う機能があります。 このオブジェクト化された手続きのことをクロージャと呼びます。
Perl
をお手本とした強力な文字列操作や正規表現検索の機能があります。
組込みの多倍長整数機能がありますので、 メモリが許す限り、非常に大きな整数の演算もできます。 たとえば、400の階乗なども簡単に計算できます。
例外処理機能は例外的な状況への対処が簡単に書けます。
Ruby
は(UNIXの)ほとんどのシステムコールの呼び出し機能を持っています。
Ruby
だけでシステムプログラミングも可能です。
OSが許せば、オブジェクトファイルを実行時に読み込む機能が提供されます。
Rubyインタプリタは以下のコマンドラインオプションを受け付けま す。基本的にPerlのものと良く似ています。
ruby [ option ] ... [ -- ] [ programfile ] [ argument ] ...
-0数字
入力レコードセパレータ(`$/')を8進数で指定します。
数字を指定しない場合はヌルキャラクタがセパレータになります ($/ = "\0" と同じ)。 数の後に他のスイッチがあっても構いません。
-00
で, パラグラフモード($/=""と同じ), -0777
で
(そのコードを持つ文字は存在しないので)全ファイルを一度に読み
込むモード($/=nilと同じ)に設定できます。
-a
`-n'や`-p'とともに用いて, オートスプリットモードをONにします。 オートスプリットモードでは各ループの先頭で,
$F = $_.split
が実行されます。`-n'か`-p'オプションが同時に指定されない限り, このオプションは意味を持ちません。
-C directory
スクリプト実行前に指定されたディレクトリに移動します。
-c
スクリプトの内部形式へのコンパイルのみを行い, 実行しません。コンパイル終 了後, 文法エラーが無ければ, "Syntax OK"と出力します。
--copyright
著作権表示をします。
-Kc
Rubyの処理する漢字コードを指定します。 Rubyは指定された文字 が `E'または`e'の場合は文字列やアクセスするファイルの内容の コードがEUCであると仮定します。同様に`S'または`s'の場合は SJIS、'U'または'u'の場合はUTF-8として処理します。 `N'は漢字を処理しません。デフォルトはN(NONE)です。
このオプションは将来文字コードの取扱いが変更された場合等には 変更される可能性があります。
-d
--debug
デバッグモードでスクリプトを実行します。$DEBUG を true にします。
-e script
コマンドラインからスクリプトを指定します。-e
オ
プションを付けた時には引数からスクリプトファイル名を取りませ
ん。
-e
オプションを複数指定した場合、各スクリプトの間に改行を
挟んで解釈します。
以下は等価です。 ruby -e "5.times do |i|" -e "puts i" -e "end" ruby -e "5.times do |i| puts i end" ruby -e "5.times do |i|; puts i; end"
-F regexp
入力フィールドセパレータ($;)の値を文字列にセッ トします。
-h
--help
コマンドラインオプションの概要を表示します。
-i [extension]
引数で指定されたファイルの内容を置き換える(in-place edit)こ とを指定します。元のファイルは拡張子をつけた形で保存されます。 拡張子がなければ、バックアップは行われず、変更されたファイル だけが残ります。
例:
% echo matz > /tmp/junk % cat /tmp/junk matz % ruby -p -i.bak -e '$_.upcase!' /tmp/junk % cat /tmp/junk MATZ % cat /tmp/junk.bak matz
-I directory
ファイルをロードするパスを指定(追加)します。指定されたディレ クトリはRubyの配列変数($:)に追加されます。
-l
行末の自動処理を行います。まず、$\ を
$/ と同じ値に設定し, print
での出力
時に改行を付加するようにします。それから, -n
フラグまたは-p
フラグが指定されていると
gets
で読み込まれた各行の最後に対して
String#chop!
を行います。
-n
このフラグがセットされるとプログラム全体が
sed -n
やawk
のように
while gets ... end
で囲まれているように動作します.
-p
-n
フラグとほぼ同じですが, 各ループの最後に変数 $_
の値を出力するようになります。
例:
% echo matz | ruby -p -e '$_.tr! "a-z", "A-Z"' MATZ
-r ファイル名
スクリプト実行前にファイル名で指定されるファイルを requireします。 `-n'オプション、`-p'オプションとともに使う時に特に有効です。
-s
スクリプト名に続く, `-'で始まる引数を解釈して, 同名のグローバル変数に値 を設定します。`--'なる引数以降は解釈を行ないません。該当する引数は ARGV から取り除かれます。
例:
#! /usr/local/bin/ruby -s # prints "true" if invoked with `-xyz' switch. print "true\n" if $xyz
-S
スクリプト名が`/'で始まっていない場合, 環境変数
PATH
の値を使ってスクリプトを探すことを指定しま
す。 これは、#!
をサポートしていないマシンで、
#!
による実行をエミュレートするために、以下の
ようにして使うことができます:
#!/bin/sh exec ruby -S -x $0 "$@" #! ruby
システムは最初の行により、スクリプトを/bin/sh
に渡します。/bin/sh
は2行目を実行しRubyインタプリタを起動します。
Rubyインタプリタは-x
オプションにより`#!'で始まり, "ruby"という文字列を含む行までを
読み飛ばします。
システムによっては $0は必ずしもフルパスを含まな いので、`-S'を用いてRubyに必要に応じてスクリプトを探すように 指示する必要があります。
-T [level]
不純度チェックを行います。level を指定すると安全度レベルをその
レベルに設定します。level 省略時は 1 を指定したのと同じです。
CGIプログラムなどでは-T1
程度を指定しておく方が良いでしょう。
システム変数$SAFE
に指定したレベルがセットされます。
-v
--verbose
冗長モード。起動時にバージョンの表示を行い, システム変数 $VERBOSEをtrueにセットします。この変数がtrueで ある時, いくつかのメソッドは実行時に冗長なメッセージを出力し ます。`-v'オプションが指定されて, それ以外の引数がない時には バージョンを表示した後, 実行を終了します(標準入力からのスク リプトを待たない).
--version
Rubyのバージョンを表示します。
-w
バージョンの表示を行う事無く冗長モードになります。
-x[directory]
メッセージ中のスクリプトを取り出して実行します。スクリプトを
読み込む時に、`#!'で始まり, "ruby"という文字列を含む行までを
読み飛ばします。スクリプトの終りはEOF
(ファイル
の終り), ^D
(コントロールD), ^Z
(コ
ントロールZ)または予約語__END__
で指定されます。
ディレクトリ名を指定すると、スクリプト実行前に指定されたディ レクトリに移動します。
-y
--yydebug
コンパイラデバッグモード。スクリプトを内部表現にコンパイルす る時の構文解析の過程を表示します。この表示は非常に冗長なので, コンパイラそのものをデバッグする人以外には必要ないと思います。
Rubyインタプリタは以下の環境変数を参照します。
RUBYOPT
Rubyインタプリタにデフォルトで渡すオプションを指定します。
sh系
RUBYOPT='-Ke -rkconv' export RUBYOPT
csh系
setenv RUBYOPT '-Ke -rkconv'
MS-DOS系
set RUBYOPT=-Ke -rkconv
RUBYPATH
-Sオプション指定時に、環境変数
PATH
によるRubyスクリプトの探索に加えて、この環境変数で指
定したディレクトリも探索対象になります。(PATH
の値よりも優
先します)。
sh系
RUBYPATH=$HOME/ruby:/opt/ruby export RUBYPATH
csh系
setenv RUBYPATH $HOME/ruby:/opt/ruby
MS-DOS系
set RUBYPATH=%HOME%\ruby:\opt\ruby
RUBYLIB
Rubyライブラリの探索パス$:のデフォル ト値の前にこの環境変数の値を付け足します。
sh系
RUBYLIB=$HOME/ruby/lib:/opt/ruby/lib export RUBYLIB
csh系
setenv RUBYLIB $HOME/ruby/lib:/opt/ruby/lib
MS-DOS系
set RUBYLIB=%HOME%\ruby\lib:\opt\ruby\lib
RUBYLIB_PREFIX
この環境変数は DJGPP版、Cygwin版、mswin32版、mingw32版のrubyでのみ有効 です。
この環境変数の値は、path1;path2 あるいは path1 path2 という形式で、 Rubyライブラリの探索パス$:の先頭部分 がpath1にマッチした場合に、これをpath2に置き換えます。
MS-DOS系
set RUBYLIB_PREFIX=/usr/local/lib/ruby;d:/ruby
RUBYSHELL
この環境変数は OS2版、mswin32版、mingw32版のrubyでのみ有効 です。
system でコマンドを実行するときに使用するシェル
を指定します。この環境変数が省略されていればCOMSPEC
の値を
使用します。
PATH
systemなどでコマンドを実行するときに検索するパスです。
設定されていないとき(nilのとき)は
"/usr/local/bin:/usr/ucb:/usr/bin:/bin:."
で検索されます。
全てのクラスのスーパークラス。 オブジェクトの一般的な振舞いを定義します。
self == other
self
と other が等しいかどうか判定します。
デフォルトでは equal?
と同じ効果です。
このメソッドは各クラスの性質に合わせて再定義するべきです。
self =~ other
古いタイプの正規表現比較 obj =~ /RE/
をサポートす
るためのメソッドです。デフォルトは
Object#== と同じ働きをします。
*1
self === other
このメソッドは case 文での比較に用いられます。デフォルトは Object#== と同じ働きをしますが、 この挙動はサブクラスで所属性のチェックを実現するため 適宜再定義されます。
class
type
レシーバのクラスを返します。
clone
dup
オブジェクトの複製を作ります。
clone
は freeze
、taint
、特異メソッドなどの情報も
含めた完全な複製を、dup
はオブジェクトの内容のみの複製を
作ります。
clone
や dup
は「浅い(shallow)」コピーであることに注意
してください。オブジェクト自身を複製するだけで、オブジェクトの指し
ている先(たとえば配列の要素など)までは複製しません。
また複製したオブジェクトに対して
obj.equal?(obj.clone)
は一般に成立しませんが *2、
obj == obj.clone
は多くの場合に成立します。
true
, false
, nil
, Symbol オブジェクトなど
を複製しようとすると例外 TypeError が発生します。
ruby 1.7 feature: version 1.7 では、Numeric オブジェクトなど immutable(内容不 変)であるオブジェクトを複製しようとすると例外 TypeError が発 生します。
display([out=$defout])
オブジェクトを out に出力します。以下のように定義できます。
class Object def display(out=$defout) out.print to_s end end
eql?(other)
二つのオブジェクトが等しいかどうかを判定します。このメソッドは Hash でふたつのキーが等しいかどうかを判定するのに使われます。 このメソッドを再定義した時には Object#hash メソッ ドも再定義しなければなりません。
eql?
のデフォルトの定義は equal?
と同じくオブジェクト
の同一性判定になっています。
equal?(other)
other
が self
自身の時、真を返します。
このメソッドを再定義してはいけません。
extend(module ... )
引数で指定したモジュールで定義されているメソッドが self
の
特異メソッドとして追加されます。あるオブジェクトだけにモジュール
の機能を追加したいときに使用します。
module Foo def a 'ok' end end obj = Object.new obj.extend Foo p obj.a #=> "ok"
extend
の機能は、「特異クラスに対する include」と言い替える
こともできます。
freeze
オブジェクトの内容の変更を禁止します。 フリーズされたオブジェクトの変更は例外 TypeError を発生させます。
frozen?
オブジェクトの内容の変更が禁止されているときに真を返します。
hash
オブジェクトのハッシュ値を返します。Hash クラスで
オブジェクトを格納するのに用いられています。A.eql?(B)
が
成立する時は必ず A.hash == B.hash
も成立しなければ
いけません。eql?
を再定義した時には必ずこちらも合わせて
再定義してください。
デフォルトでは、Object#id と同じ値をハッシュ値とし ます。ただし、Fixnum, Symbol, String だけは組込 みのハッシュ関数が使用されます(これを変えることはできません)。
hash を定義する場合は、一様に分布する任意の整数を返すようにします (現在の実装では、返り値の内部表現を 65439 (1.7 なら 536870917) *3 で割った余りをハッシュ値とします*4。
id
__id__
各オブジェクトに対して一意な整数を返します。あるオブジェクトに対し てどのような整数が割り当てられるかは不定です。
id
メソッドの再定義に備えて別名 __id__
が用意されて
おり、ライブラリでは後者の利用が推奨されます。また __id__
を
再定義すべきではありません。
inspect
オブジェクトを人間が読める形式の文字列に変換します。
instance_eval(expr, [fname, [lineno=1]])
instance_eval {|obj| ... }
オブジェクトのコンテキストで文字列 expr を評価してその結果を返 します。 fname、lineno が与えられた場合は、ファイル fname、 行番号 lineno にその文字列があるかのようにコンパイルされ、ス タックトレース表示などのファイル名/行番号を差し替えることができま す。
ブロックが与えられた場合にはそのブロックをオブジェクトのコンテキス
トで評価してその結果を返します。ブロックの引数 obj には
self
が渡されます。
オブジェクトのコンテキストで評価するとは self
をそのオブジェ
クトにして実行するということです。また、文字列/ブロック中でメソッ
ドを定義すれば self
の特異メソッドが定義されます。
ただし、ローカル変数だけは instance_eval
の外側のスコープと
共有します。
instance_of?(klass)
self
がクラス klass の直接のインスタンスである時、
真を返します。obj.instance_of?(c)
が成立する時には、常に
obj.kind_of?(c)
も成立します。
instance_variables
オブジェクトのインスタンス変数名を文字列の配列として返します。
local_variables, global_variables, Module.constants, Module#constants, Module#class_variables も参照してください。
is_a?(mod)
kind_of?(mod)
self
が、クラス mod とそのサブクラス、および
モジュール mod をインクルードしたクラスとそのサブクラス、
のいずれかのインスタンスであるとき真を返します。
module M end class C < Object include M end class S < C end obj = S.new p obj.is_a? S # true p obj.is_a? M # true p obj.is_a? C # true p obj.is_a? Object # true p obj.is_a? Hash # false
method(name)
self
のメソッド name をオブジェクト化した
Method オブジェクトを返します。name は
Symbol または文字列で指定します。
Module#instance_method も参照してください。
method_missing(name, args, ... )
呼びだされたメソッドが定義されていなかった時、Ruby がこのメソッド を呼び出します。呼び出しに失敗したメソッドの名前 (Symbol) とそ の時の引数が name と arg ... に渡されます。
デフォルトではこのメソッドは例外 NameError を発生させます。
methods
public_methods
そのオブジェクトが理解できるpublicメソッド名の一覧を配列とし て返します。
Module#instance_methods, Module#public_instance_methods, も参照してください。
nil?
レシーバが nil
かどうかをチェックします。
private_methods
そのオブジェクトが理解できるprivateメソッド名の 一覧を配列として返します。
Module#private_instance_methods, も参照してください。
protected_methods
そのオブジェクトが応答できる protected メソッド名の 一覧を文字列の配列で返します。
Module#protected_instance_methods, も参照してください。
respond_to?(name[, priv=false])
オブジェクトが public メソッド name を持つとき真。 nameは Symbol または文字列です。priv が 真のときは private メソッドに対しても真を返します。
send(name[, args ... ])
send(name[, args ... ]) { .... }
__send__(name[, args ... ])
オブジェクトのメソッド name を、引数に args を 渡して呼び出します。ブロック付きで呼ばれたときはブロックも そのまま引き渡します。メソッド名 name は文字列か Symbol です。
send
が再定義された場合に備えて別名 __send__
も
用意されており、ライブラリではこちらを使うべきです。また
__send__
は再定義すべきではありません。
singleton_methods([all=false])
そのオブジェクトに対して定義されている特異メソッド名の一覧を 配列として返します。
ruby 1.7 feature: 省略可能な引数 all に真を指定すれば 特異クラスがインクルードしているモジュールのメソッドも対象になります。
obj = Object.new module Foo def foo end end class <<obj include Foo def bar end end p obj.singleton_methods #=> ["bar"] p obj.singleton_methods true #=> ["bar", "foo"]
あるいは、Object#extend は特異クラスに対するイ ンクルードなので以下も同様になります。
obj = Object.new module Foo def foo end end obj.extend(Foo) p obj.singleton_methods #=> [] p obj.singleton_methods true #=> ["foo"]
taint
オブジェクトの「汚染マーク」をセットします。
オブジェクトの汚染に関してはセキュリティモデルを参照してください。
tainted?
オブジェクトの「汚染マーク」がセットされている時真を返します。
オブジェクトの汚染に関してはセキュリティモデルを参照してください。
to_a
オブジェクトを配列に変換します。普通に配列に変換できない オブジェクトは、自身のみを含む長さ 1 の配列に変換されます。
例
p( {'a'=>1}.to_a ) # [["a", 1]] p ['array'].to_a # ["array"] p 1.to_a # [1] p 'str'.to_a # ["str"]
to_ary
オブジェクトの配列への暗黙の変換が必要なときに内部で呼ばれます。 *5
このメソッドが定義されたオブジェクトが単独で多重代入の右辺に 現れた場合にも呼ばれます。
class Foo def to_ary [1, 2, 3] end end a, b, c = Foo.new p [a, b, c] => [1, 2, 3]
to_hash
オブジェクトのハッシュへの暗黙の変換が必要なときに内部で呼ばれます。
to_int
オブジェクトの整数への暗黙の変換が必要なときに内部で呼ばれます。
to_s
オブジェクトの文字列表現を返します。
print や sprintf は文字列以外の オブジェクトが引数に渡された場合このメソッドを使って文字列に変換し ます。
to_str
オブジェクトの文字列への暗黙の変換が必要なときに呼ばれます。
untaint
オブジェクトの「汚染マーク」を取り除きます。汚染マークを取り 除くことによる危険性はプログラマが責任を負う必要があります。
セキュリティレベルが3以上の場合は例外 SecurityError を 発生します。
オブジェクトの汚染に関してはセキュリティモデルを参照してください。
initialize
ユーザ定義クラスのオブジェクト初期化メソッド。このメソッドは
Class#new から新しく生成されたオブジェクトの初期化
のために呼び出されます。デフォルトの動作ではなにもしません。サブク
ラスではこのメソッドを必要に応じて再定義されることが期待されていま
す。initialize
には Class#new に与えられた引
数がそのまま渡されます。
また initialize
という名前を持つメソッドは自動的に private に
設定されます。
remove_instance_variable(name)
オブジェクトからインスタンス変数 name を取り除きます。 name は Symbol か文字列です。
オブジェクトがインスタンス変数 name を持っていない場合は 単に無視します。
Module#remove_class_variable, Module#remove_const も参照してください。
取り除いたインスタンス変数に設定されていた値を返します。
singleton_method_added(name)
特異メソッドが追加された時にインタプリタから呼び出されます。 name には追加されたメソッド名が Symbol で渡されます。
class Foo def singleton_method_added(name) puts "singleton method \"#{name}\" was added" end end obj = Foo.new def obj.foo end => singleton method "foo" was added
通常のメソッドの追加に対するフックには Module#method_addedを使います。
singleton_method_removed(name)
特異メソッドが Module#remove_method に より削除された時にインタプリタから呼び出されます。 name には削除されたメソッド名が Symbol で渡されます。
class Foo def singleton_method_removed(name) puts "singleton method \"#{name}\" was removed" end end obj = Foo.new def obj.foo end class << obj remove_method :foo end => singleton method "foo" was removed
通常のメソッドの削除に対するフックには Module#method_removedを使います。
singleton_method_undefined(name)
特異メソッドが Module#undef_method または undef により未定義にされた時にインタプリタ から呼び出されます。 name には未定義にされたメソッド名が Symbol で渡されます。
class Foo def singleton_method_undefined(name) puts "singleton method \"#{name}\" was undefined" end end obj = Foo.new def obj.foo end def obj.bar end class << obj undef_method :foo end obj.instance_eval {undef bar} => singleton method "foo" was undefined singleton method "bar" was undefined
通常のメソッドの未定義に対するフックには Module#method_undefined を使います。
未定義のローカル変数や定数を使用したときに発生します。
Proc
はブロックをコンテキスト(ローカル変数のスコープやスタックフ
レーム)とともにオブジェクト化した手続きオブジェクトです。Proc
は
ローカル変数のスコープを導入しないことを除いて名前のない関数のように使
えます(ダイナミックローカル変数は Proc
ローカル
の変数として使えます)。
Proc
がローカル変数のスコープを保持していることは以下の例で
変数 var を参照できていることからわかります。
var = 1 $foo = Proc.new { var } var = 2 def foo $foo.call end p foo # => 2
Proc
を生成したメソッドからリターンしてしまった後は Proc
からの return, retry は例外
LocalJumpError を発生させます。
def foo proc { return } end foo.call # => in `call': return from proc-closure (LocalJumpError)
イテレータに対して Proc
オブジェクトを `&' を指定して
渡すとイテレータブロックのように動作しますが、厳密には以下の
違いがあります*6。
# 問題なし (1..5).each { break } # LocalJumpError proc = Proc.new { break } (1..5).each(&proc) # => break from proc-closure (LocalJumpError)
これは、Proc
オブジェクトがイテレータブロックとして振舞う際の制
限です。
Proc.new
Proc.new { ... }
ブロックをコンテキストとともにオブジェクト化して返します。
ブロックを指定しなければ、このメソッドを呼び出したメソッドがブロッ
クを伴うときに、それを Proc
オブジェクトとして生成して返しま
す。
def foo pr = Proc.new pr.call(1,2,3) end foo {|args| p args } # => [1, 2, 3]
これは以下と同じです(厳密には引数の解釈の仕方が異なります。 Proc#yield を参照してください)。
def foo yield(1,2,3) end foo {|args| p args } # => [1, 2, 3]
呼び出し元のメソッドがブロックを伴わなければ、例外 ArgumentError が発生します。
def foo Proc.new end foo # => -:2:in `new': tried to create Proc object without a block (ArgumentError) from -:2:in `foo' from -:4
Proc.new
は、Proc#initialize
が定義されていれば
オブジェクトの初期化のためにこれを呼び出します。このことを
除けば、proc と同じです。
self[arg ...]
call(arg ... )
手続きオブジェクトを実行してその結果を返します。引数はブロックの引 数にそのまま(多重代入のルールに従い)代入されます。
arity
Proc
オブジェクトの引数の数を返します。self
が引数の数
を可変長で受け取れる場合
-(最低限必要な数+1)
を返します。
yield(arg ... )
Proc#call と同じですが、引数の数のチェックを行いません。
pr = Proc.new {|a,b,c| p [a,b,c]} pr.yield(1) #=> [1, nil, nil] pr.yield(1,2,3,4) #=> [1, 2, 3] pr.call(1) #=> wrong # of arguments (4 for 3) (ArgumentError)
これは yield と同じ動作です。
def foo yield(1) end foo {|a,b,c| p [a,b,c]}
ローカル変数のテーブルと self
、モジュールのネストなどの情報を保
持するオブジェクトのクラス。組み込み関数 binding によっ
てのみ生成され、eval の第 2 引数に使用します。
またトップレベルの Binding オブジェクトとして組み込み定数 TOPLEVEL_BINDING が用意されています。
スコープを出てしまった Proc からの return, break, next, redo, retry で発生します。
Proc の例を参照してください。
exitstatus ((<ruby 1.7 feature>))
例外 LocalJumpError
を発生させた break や return に指定した
戻り値を返します。
def foo proc { return 10 } end begin foo.call rescue LocalJumpError p $!.exitstatus end => ruby 1.7.2 (2002-02-14) [i586-linux] 10 pr = proc { break 5 } def bar(&pr) pr.yield end begin bar(&pr) rescue LocalJumpError p $!.exitstatus end => ruby 1.7.2 (2002-02-14) [i586-linux] 5
nil
のクラス。偽変数(の値) nil
は NilClass
クラスの
唯一のインスタンスです。nil
は false
オブジェクトとともに
偽を表し、その他の全てのオブジェクトは真です。
self & other
常に false
を返します。
self | other
self ^ other
other が真なら true を偽なら false
を返します。
nil?
常に true
を返します。
to_a
空の配列[]
を返します。
to_i
0 を返します。
to_s
空文字列""
を返します。
true
のクラス。true
は TrueClass
クラスの唯一のイン
スタンスです。true
は真を表す代表のオブジェクトです。
self & other
other が真なら true
を偽なら false
を返します。
self | other
常に true
を返します。
self ^ other
other が真なら false
を偽なら true
を返します。
false
のクラス。false
は FalseClass
クラスの唯一のイ
ンスタンスです。false
は nil
オブジェクトとともに偽を表し、
その他の全てのオブジェクトは真です。
self & other
常に false
を返します。
self | other
self ^ other
other が真なら true
を偽なら false
を返します。
Ruby はスクリプトの終端に達した場合や捕捉していない例外が発生した場 合に終了します(関数 exit や abort 、メインスレッドに対する Thread.kill などは SystemExit 例外を発生させます)。終了時には以下 の処理が順に実行されます。
ObjectSpace.define_finalizer により、ファイナ ライザが登録されていればそれらを実行する(実行順序は不定)
ファイナライザ実行中に発生した大域脱出はそのファイナライザの処理 を中断するが、スクリプトはまだ終了しない。
ただし、関数 exit! による終了は、_exit(2) を実行するだけで、上記の処理はいずれも行われません。
Ruby のスレッドを表現するクラスです。
Thread
を使うことで並行プログラミングが可能になります。スレッド
はメモリ空間を共有して同時に実行される制御の流れです。ただし、現在の実
装では Ruby インタプリタは時分割でスレッドを実行しますので、スレッドを
使うことで実行速度が速くなることはありません。
プログラムの開始と同時に生成されるスレッドをメインスレッド と呼 びます。なんらかの理由でメインスレッドが終了する時には、他の全てのスレッ ドもプログラム全体も終了します。ユーザからの割込みによって発生した例外 はメインスレッドに送られます。
スレッドの起動時に指定したブロックの実行が終了するとスレッドの実行も終 了します。ブロックの終了は正常な終了も例外などによる異常終了も含みます。
Ruby のスレッドスケジューリングは優先順位付のラウンドロビンです。一定 時間毎、あるいは実行中のスレッドが権利を放棄したタイミングでスケジュー リングが行われ、その時点で実行可能なスレッドのうち最も優先順位が高いも のにコンテキストが移ります。
あるスレッドで例外が発生し、そのスレッド内で rescue で捕捉されなかっ
た場合、通常はそのスレッドだけがなにも警告なしに終了されます。ただ
しその例外で終了するスレッドを Thread#join
で待っている他の
スレッドがある場合、その待っているスレッドに対して、同じ例外が再度
発生します。
begin t = Thread.new do Thread.pass # メインスレッドが確実にjoinするように raise "unhandled exception" end t.join rescue p $! # => "unhandled exception" end
また、以下の 3 つの方法により、いずれかのスレッドが例外によって終 了した時に、インタプリタ全体を中断させるように指定することができま す。
上記3つのいずれかが設定されていた場合、インタプリタ全体が中断されます。
個々のスレッドは、以下の実行状態を持ちます。これらの状態は Object#inspect や Thread#status によって見ることができます。
p Thread.new {sleep 1} # => #<Thread:0xa039de0 sleep>
生成されたばかりのスレッドや run や wakeup で起こされたスレッドはこの状態です。 join でスレッドの終了を待っているスレッドもスレッドの 終了によりこの状態になります。
この状態のスレッドは「生きて」います。
Thread.stop や join により停止されたスレッ ドはこの状態になります。
この状態のスレッドは「生きて」います。
kill 等で終了されるスレッドは一時的にこの状態になりま す。この状態から停止状態(stop)になることもあります。
この状態のスレッドはまだ「生きて」います。
kill 等で終了したスレッドはこの状態になります。この状 態のスレッドはどこからも参照されていなければ GC によりメモリ上から なくなります。
この状態のスレッドは「死んで」います。
Thread.abort_on_exception
いずれかのスレッドが例外によって終了した時に、インタプリタ全体を中 断させるかどうかのフラグの値を返します。
Thread.abort_on_exception = yes_no
いずれかのスレッドが例外によって終了した時に、インタプリタ全体を中 断させるかどうかのフラグを設定します。通常あるスレッドで起こった例 外は、Thread#join などで検出されない限りそのスレッ ドだけをなにも警告を出さずに終了させます。
yes_no を返します。
Thread.critical
Thread.critical = yes_no
真である間、スレッドの切替えを行いません。カレントスレッドが停止
(stop)した場合やシグナルに割り込まれた場合には、自動的に
false
になります。
ただし、Thread.new によりスレッドを生成した場合にはそ のスレッドは実行されます。また、Thread.pass により明 示的に切替えることもできます。
yes_no を返します。
注意: I/O や GC、拡張ライブラリがからむとこのフラグは無視さ れることもあります。排他制御を行うにはこのメソッドに頼らず Mutex や Monitor を使うべきです。
Thread.current
現在実行中のスレッド(カレントスレッド)を返します。
Thread.exit
カレントスレッドの実行を終了します。
カレントスレッドを返します。
カレントスレッドが唯一のスレッドであるなら、exit(0) により終了します。
Thread.kill(thread)
指定したスレッドの実行を終了させます。既に終了しているスレッドに対 しては何もしません。
thread を返します。*13
Thread.list
生きているスレッドのうち、実行中(run)または停止中(stop)のスレッド の配列を返します。
Thread.main
メインスレッドを返します。
Thread.new([arg, ...]) { ... }
Thread.start([arg, ...]) { ... }
Thread.fork([arg, ...]) { ... }
スレッドを生成して、ブロックの評価を開始します。
引数はそのままブロックに渡されます。スレッドの開始と同時にその スレッド固有のローカル変数に値を渡すために使用します。
生成したスレッドを返します。
例えば、以下のコードは間違いです。スレッドの実行が開始される前に 変数 i が書き変わる可能性があるからです。
for i in 1..5 Thread.start { p i } end
上の例は以下のように書き直すべきです。
for i in 1..5 Thread.start(i) {|t| p t } end
Thread.pass
他のスレッドに実行権を譲ります。実行中のスレッドの状態を変えずに、 他の実行可能状態のスレッドに制御を移します(明示的なスケジューリン グ)。
nil
を返します。
Thread.stop
他のスレッドから run メソッドで再起動されるまで、カレ ントスレッドの実行を停止します。
nil
を返します。
self[name]
name に対応したスレッドに固有のデータを取り出しま す。name は文字列か Symbol で指定します。
name に対応するスレッド固有データがなければ nil
を返し
ます。
self[name] = val
val を name に対応するスレッド固有のデータとして格納し
ます。name は文字列か Symbol で指定します。
val に nil
を指定するとそのスレッド固有データは削除さ
れます。
val を返します。
abort_on_exception
そのスレッドが例外によって終了した時に、インタプリタ全体を中断する かどうかのフラグの値を返します。
abort_on_exception = yes_no
そのスレッドが例外によって終了した時に、インタプリタ全体を中断させ るかどうかのフラグを設定します。
yes_no を返します。
alive?
スレッドが「生きている」時、true
を返します。
Thread#status が真を返すなら、このメソッドも真 です。
exit
kill
スレッドの実行を終了させます。
self
を返します。
join
スレッド self
の実行が終了するまで、カレントスレッドを停止し
ます。self
が例外により終了していれば、その例外がカレントス
レッドに対して発生します。
self
を返します。
以下は、生成したすべてのスレッドの終了を待つ例です。
threads = [] threads.push(Thread.new { n = rand(5); sleep n; n }) threads.push(Thread.new { n = rand(5); sleep n; n }) threads.push(Thread.new { n = rand(5); sleep n; n }) threads.each {|t| t.join}
key?(name)
name に対応したスレッドに固有のデータが定義されていれば
true
を返します。name は文字列か Symbol で指定し
ます。
keys ((<ruby 1.7 feature>))
スレッド固有データに関連づけられたキーの配列を返します。キーは Symbol で返されます。
th = Thread.current th[:foo] = 'FOO' th['bar'] = 'BAR' p th.keys #=> [:bar, :foo]
priority
スレッドの優先度を返します。優先度のデフォルト値は 0 で、この値の 大きいスレッドは小さいスレッドよりも優先度が高くなります。
priority = val
スレッドの優先度を設定します。負の値も指定できます。
val
を返します。
*14
raise([error_type,][message][,traceback])
そのスレッドで強制的に例外を発生させます。
引数の意味については組込み関数 raise を参照してく ださい。
Thread.new { sleep 1 Thread.main.raise "foobar" } begin sleep rescue p $!, $@ end => #<RuntimeError: foobar> ["-:3"]
run
停止状態(stop)のスレッドを再開させます。 Thread#wakeup と異なりすぐにスレッドの切り替え を行います。死んでいるスレッドに対して実行すると ThreadError が発生します。
self
を返します。
safe_level
self
のセーフレベルを返します。カレントスレッドの
safe_level
は、$SAFE と同じです。
セーフレベルについてはセキュリティモデルを参照してください。
status
生きているスレッドの状態を文字列 "run"、"sleep", "aborting" のいず
れかで返します。正常終了したスレッドに対して false
、例外によ
り終了したスレッドに対して nil
を返します。
*15
Thread#alive? が真を返すなら、このメソッドも真です。
stop?
スレッドが終了(dead)あるいは停止(stop)している時、true
を返
します。
value
スレッド self
が終了するまで待ち(join と同じ)、
そのスレッドのブロックが返した値を返します。スレッド実行中に例外が
発生した場合には、その例外を再発生させます。
以下は、生成したすべてのスレッドの終了を待ち結果を出力する例です。
threads = [] threads.push(Thread.new { n = rand(5); sleep n; n }) threads.push(Thread.new { n = rand(5); sleep n; n }) threads.push(Thread.new { n = rand(5); sleep n; n }) threads.each {|t| p t.value}
最後の行で、待ち合わせを行っていることがわかりにくいと思うなら以下 のように書くこともできます。
threads.each {|t| p t.join.value}
wakeup
停止状態(stop)のスレッドを実行可能状態(run)にします。死んでいるス レッドに対して実行すると ThreadError が発生します。
self
を返します。
ruby
を終了させます。*16
status ((<ruby 1.7 feature>))
exit により終了したとき、その引数(終了ステータス) を返します。
begin exit(1) rescue SystemExit p $! p $!.status end => #<SystemExit: exit> 1
SystemExit の例外を故意に発生させた場合の値は nil
です。
begin raise SystemExit, "bogus exit" rescue SystemExit p $! p $!.status end => #<SystemExit: bogus exit> nil
全てのオブジェクトを操作するためのモジュール。
ObjectSpace._id2ref(id)
オブジェクト ID(Object#id)からオブジェクトを得ます。 対応するオブジェクトが存在しなければ例外 RangeError が発生し ます。
ObjectSpace.define_finalizer(obj, proc)
ObjectSpace.define_finalizer(obj) {|id| ...}
obj が解放されるときに実行されるファイナライザ proc を 登録します。同じオブジェクトについて複数回呼ばれたときは置き換えで はなく追加登録されます。
proc には、ファイナライザとして Proc オブジェクトを渡 します。ブロックを指定した場合は、そのブロックが proc になり ます(しかし、後述の問題があるのでブロックでファイナライザを登録す るのは難しいです)。
ファイナライザ proc には引数として obj の ID(Object#id) が渡されます。
以下は、define_finalizer
の使い方の悪い例です。
class Foo def initialize ObjectSpace.define_finalizer(self) { puts "foo" } end end Foo.new GC.start
これは、渡された proc の self
が obj を参照しつ
づけるため。そのオブジェクトが GC の対象になりません。
ruby-src:ruby/lib/tempfile.rb は、ファイナライザの使い方の 良い例になっています。これは、クラスのコンテキストで Proc を 生成することで上記の問題を回避しています。
class Bar def Bar.callback proc { puts "bar" } end def initialize ObjectSpace.define_finalizer(self, Bar.callback) end end Bar.new GC.start
proc の呼び出しで発生した大域脱出(exitや例外)は無視されます。 これは、スクリプトのメイン処理が GC の発生によって非同期に中断され るのを防ぐためです。不安なうちは -d オプションで事前に例外の発生の有無を確認しておいた方が良いでしょう。
class Baz def initialize ObjectSpace.define_finalizer self, eval %q{ proc { raise "baz" rescue puts $! raise "baz2" puts "baz3" } }, TOPLEVEL_BINDING end end Baz.new GC.start # => baz
ObjectSpace.each_object([class_or_module]) {|object| ...}
class_or_module と kind_of? の関係にある全ての オブジェクトに対して繰り返します。引数が省略された時には全てのオブ ジェクトに対して繰り返します。
class_or_module に Fixnum や Symbol を指定しても 何も繰り返しません。
繰り返した数を返します。
ObjectSpace.garbage_collect
どこからもアクセスされなくなったオブジェクトを回収します。 GC#start と同じです。
nil
を返します。
ObjectSpace.undefine_finalizer(obj)
obj に対するファイナライザをすべて解除します。
obj を返します。
以下は、ファイナライザの古いインタフェースです。使用すると警告メッセー ジが出力されます。
ObjectSpace.add_finalizer(proc)
proc をファイナライザとして設定します。
call_finalizer で指定したオブジェクトが開放され る時、そのオブジェクトの ID(c.f Object#id)を引数に ファイナライザが評価されます。
proc を返します。
このメソッドは、obsolete です。代わりに ObjectSpace.define_finalizer を使用してください
ObjectSpace.call_finalizer(obj)
obj をファイナライザの対象オブジェクトとして設定します。
obj を返します。
このメソッドは、obsolete です。
ObjectSpace.finalizers
現在登録されているファイナライザの配列を返します。
このメソッドは、obsolete です。
ObjectSpace.remove_finalizer(proc)
指定した proc をファイナライザから取り除きます。
proc を返します。
このメソッドは、obsolete です。代わりに ObjectSpace.undefine_finalizer を使用してくださ い。
foo(1)
という記述はマニュアルページの参照を示します(Unixでの話)。
$ man 1 foo
などとして参照します。
数字はセクション番号を示します。例えば
などと分類わけされています。各セクションの意味は intro(1)
などに
説明がありますのでそちらも参照してください。
環境によってはシステムコールがライブラリ関数として実装されている
場合もあるので socket(2)
が
$ man 2 socket
でなく
$ man 3 socket
の場合もあります。大抵セクションは省略して
$ man socket
として参照すれば良いでしょう。
詳細は man(1)
を参照してください。
UNIX 環境を触れない人は
などを参照してください(この他にも情報があれば教えてください)。
RubyにはCGI等のプログラミングを安全に行うことを助ける為に、セキュリティ 機構が備わっています。
Rubyのセキュリティモデルは「オブジェクトの汚染」と「セーフレベル」という 仕組みによってなりたっています。
Rubyではオブジェクトは「汚染されている」とみなされることがあります。この しくみは大きく分けて二つの使われ方をします。
ひとつ目は、信用できない入力をもとに作られたオブジェクトを「汚染されてい る」とみなし、「危険な操作」の引数として使えないようにすることです。悪意 あるデータによって、プログラムが意図しない動作をする事を防ぐことを目的と しています。
もうひとつは、信用しているオブジェクト(汚染されていないオブジェクト)を 信用できないプログラムから守るという使い方です。セーフレベル4で汚染されて いないオブジェクトへの操作が大幅に制限されるのはこの事を意図しています。
オブジェクトの汚染に関連するメソッド
オブジェクトを汚染する
オブジェクトが汚染されている場合に真を返す
オブジェクトの汚染を取り除く
各スレッドは固有の「セーフレベル」を持っています。セーフレベルが高くなるほ ど、行える操作は制限されます。セーフレベルはスレッドローカル変数$SAFEで 設定します。
$SAFEに関するルール
原則として、各セキュリティレベルにはそれ以下のセキュリティレベルの制限も 適用されます。たとえばレベル1で許されない操作はレベル2でも行えません。
デフォルトのセーフレベルです。
IOや環境変数、コマンドライン引数(ARGV)から得られた文字列
(環境変数PATHだけは特別)
環境変数PATHだけは例外で、値に危険なパスを含む場合のみ汚染されます。
ここでは危険なパスとは誰でも変更/書き込みが可能なパスをいいます。 ルートディレクトリから階層が順番にチェックされ、一箇所でも誰でも 変更可能な個所があればそのパスは危険とみなされます。
汚染された文字列を引数とした以下の操作
信用しているプログラムで信用できないデータを処理する為のレベルです。 CGI等でユーザからの入力を処理するのに適しています。
レベル1の制限に加え、以下の操作が禁止されます。
生成される全てのオブジェクトが汚染されます。レベル4でプログラムを実行す る環境を作り上げるのに適しています。
レベル2の制限に加え、以下の操作が禁止されます。
信用することのできないプログラムを実行するためのレベルです。
このレベルではレベル3では禁止されている「汚染された文字列のeval」が許可 されています。(evalで実行すると危険な操作は全て禁止されているからです。)
レベル3の制限(上記のとおりevalは除く)に加え、以下の操作が禁止されます。
Level 1以上では起動時に以下の違いがある
一端高くした$SAFEレベルを低く変更する事はできませんが、以下のようにスレッ ドを使うことで、プログラムの一部だけを高いセーフレベルで実行することが可 能です。
例:
def safe(level) result = nil Thread.start { $SAFE = level result = yield }.join result end safe(4) { puts "hello" } # $SAFEなので例外 puts "world" # 外側は影響を受けない
セキュリティ上の問題が起きたときに発生します。 セキュリティモデル も参照してください。
致命的なエラー(内部的なエラー)のときに発生します。 例えば:
などです。fatal
というオブジェクトは通常の方法では見えません。
以下は、ruby がサポートする正規表現記号の一覧です。
という規則があります。
以下の説明の中で「多バイト文字に対応した正規表現」とは、 $KCODE が設定されているか、あるいは明示的に漢字オプショ ン(正規表現リテラルを参照)を指定するなどで多バイト文字 にマッチする正規表現を指します。
^
行頭。文字列の先頭や改行文字の直後の位置にマッチします。
$
行末。文字列の末尾や改行文字の直前の位置にマッチします。
.
改行を除く任意の 1 文字にマッチします。正規表現オプション m (複数行 モード。正規表現リテラルを参照)では、改行を含む任意の 1 文字にマッチします。
多バイト文字に対応した正規表現では、その 1 文字(1 バイトでなく)とマッ チします。
また、不完全な多バイト文字の一部(その文字だけでは多バイト文字かバイ ナリかASCIIか判断が付かない場合)とはマッチしません。
p /./e =~ "あ"[0,1] # => nil
\w
英数字。[0-9A-Za-z_]
と同じ。
多バイト文字に対応した正規表現では、日本語のいわゆる全角文字にもマッ チします。
\W
非英数字。\w
以外の一文字。
\s
空白文字。[ \t\n\r\f]
と同じ
\S
非空白文字。[ \t\n\r\f]
以外の一文字。
\d
数字。[0-9]
と同じ
\D
非数字
\A
文字列先頭。^
とは異なり改行の有無には影響しません。
\Z
文字列末尾。文字列が改行で終っていればその改行の直前にマッチします。
\z
文字列末尾。$
や \Z
とは異なり改行の有無には影響しません。
\b
文字クラス指定の外では語境界 (\w
と \W
のあいだにマッチ)。
文字クラス指定内ではバックスペース (0x08)。
\B
非語境界
\G
前回マッチした箇所(の直後)にマッチ (幅を持たない)。 初回だけは先頭位置にマッチします(\Aと同じ)。
scan や、gsub で使用できます。前回マッチし た場所の後からマッチさせたい場合に使用します。
簡単な(あまり役に立たない)例は以下。 *20
# 先頭から3桁ずつの数値を(数値が続く限り)取り出す。 str = "123456 789" str.scan(/\G\d\d\d/) {|m| p m }
[ ]
文字クラス指定。文字クラスを参照。
*
直前の表現の 0 回以上の繰り返し。できるだけ長くマッチしようとする。
*?
直前の表現の 0 回以上の繰り返し (最短一致)
+
直前の表現の 1 回以上の繰り返し
+?
直前の表現の 1 回以上の繰り返し (最短一致)
{m}
{m,}
{m,n}
それぞれ直前の正規表現の
の繰り返し。{,n}
や、{,}
に対するマッチは必ず失敗する。
str = "foofoofoo" p str[/(foo){1}/] # => "foo" p str[/(foo){2,}/] # => "foofoofoo" p str[/(foo){1,2}/] # => "foofoo"
正規表現 ?
, *
, +
はそれぞれ {0,1}
, {0,}
{1,}
と同じです。
{m}?
{m,}?
{m,n}?
それぞれ直前の正規表現の
の繰り返し(最短一致)。
?
直前の正規表現の 0 または 1 回の繰り返し。
??
直前の正規表現の 0 または 1 回の繰り返し(最短一致)
|
選択
( )
正規表現のグループ化。括弧の中の正規表現にマッチした文字列は後方参照 のために記憶されます。
\1
, \2
... \n
後方参照(back reference)。後方参照を参照。
(?# )
コメント。括弧の中の任意の文字列は無視されます。
(?: )
後方参照を伴わないグループ化。
(?= )
先読み(lookahead)。 パターンによる位置指定(幅を持たない)
(?=re1)re2
という表現は、re1 と re2 の両方にマッチする正規表現です。
re1(?=re2)
という表現は、後に re2 とマッチする文字列が続く、正規表現 re1 です。
p /foo(?=bar)/ =~ "foobar" # => 0 p $& # => "foo" (bar の部分の情報はない)
(?! )
否定先読み(negative lookahead)。 パターンの否定による位置指定(幅を持たない)
(?!re1)re2
という表現は、re1 にマッチしないが re2 にはマッチする正規表現です。
# 000 を除く 3 桁の数字 re = /(?!000)\d\d\d/ p re =~ "000" # => nil p re =~ "012" # => 0 p re =~ "123" # => 0 # C 言語の識別子 ([A-Za-z_] で始まり、[0-9A-Za-z_] が続く文字列) /\b(?![0-9])\w+\b/
(?> )
バックトラックを抑止する。
この表現はまだ試験実装中です。将来なくなる可能性もありますので、 そのつもりで使ってください。特に汎用ライブラリなどで使ってはいけません。
(?ixm-ixm)
正規表現中でのiオプション、xオプション、mオプションのon/off。オプショ ンについては正規表現リテラルを参照。
re = /A(?i)a(?-i)A/ p re =~ "AaA" # => 0 p re =~ "AAA" # => 0 p re =~ "AAa" # => nil
(?ixm-ixm: )
括弧内のiオプション、xオプション、mオプションのon/off。括弧の範囲内 で設定
re = /A(?i:a)A/ p re =~ "AaA" # => 0 p re =~ "AAA" # => 0 p re =~ "AAa" # => nil
正規表現 \1 \2 ... \n
は、後方参照です。n 番目の括弧(正規
表現 ( )
グルーピング)にマッチした文字列にマッチします。
/((foo)bar)\1\2/
は、
/((foo)bar)foobarfoo/
と同じです。
例:
re = /(foo|bar|baz)\1/ p re =~ 'foofoo' # => 0 p re =~ 'barbar' # => 0 p re =~ 'bazbaz' # => 0 p re =~ 'foobar' # => nil
対応する括弧は、後方参照よりも左側にないといけません。
対応する括弧の中に後方参照があれば常にマッチに失敗します。 また、対応する括弧がない 1 桁の後方参照も常にマッチに失敗します。
p /(\1)/ =~ "foofoofoo" # => nil p /(foo)\2/ =~ "foo\2" # => nil
2 桁以上の後方参照も指定できますが、バックスラッシュ記法
の \nnn
(8進 nnn に対応する文字)と混同しないように注意する必要が
あります。2 桁以上の指定では、対応する括弧がなければ 8 進コードと見な
されます。
また、逆に正規表現中に 8 進で 1 桁のコードを記述するには \01 など 0 で 始める必要があります(\0 という後方参照はないので)。
p /\1/ =~ "\1" # => nil # 対応する括弧のない後方参照 p /\01/ =~ "\1" # => 0 8 進コード p /\11/ =~ "\11" # => 0 8 進コード # 8 進コード (対応する括弧がないので) p /(.)\10/ =~ "1\10" # => 0 # 後方参照 (対応する括弧があるので p /((((((((((.))))))))))\10/ =~ "aa" # => 0 # 8 進コード(ただし、"\0" + "8" になっている # \08 という 8 進コードはないので) p /(.)\08/ =~ "1\0008" # => 0 # 後方参照に続けて数字を書きたいなら括弧でグループ化して区切る # などするしかない。 p /(.)(\1)1/ =~ "111" # => 0
正規表現 [ ]
は、文字クラス指定です。[] 内に列挙したいずれかの一
文字にマッチします。
例えば、/[abc]/ は、"a", "b", "c" いずれか一文字にマッチします。 ASCIIコード順で連続する文字列は間に `-' を置いて /[a-c]/ のように書 くこともできます。また、先頭が `^' であれば指定した文字以外の一文字 とマッチします。
先頭以外にある `^' はその文字そのものとマッチします。また、先頭、末 尾にある `-' は、その文字そのものとマッチします。
p /[a^]/ =~ "^" # => 0 p /[-a]/ =~ "-" # => 0 p /[a-]/ =~ "-" # => 0 p /[-]/ =~ "-" # => 0
空の文字クラスはエラーになります。
p /[]/ =~ "" p /[^]/ =~ "^" # => invalid regular expression; empty character class: /[^]/
先頭(あるいは否定の "^" の直後)にある "]" は、文字クラスの終りではなく "]" そのものを表します。
p /[]]/ =~ "]" # => 0 p /[^]]/ =~ "]" # => nil
"^", "-", "]" そして "\\"(バックスラッシュ)は、バックスラッシュでエス ケープして、その文字にマッチさせることができます。
p /[\^]/ =~ "^" # => 0 p /[\-]/ =~ "-" # => 0 p /[\]]/ =~ "]" # => 0 p /[\\]/ =~ "\\" # => 0
[] 内には文字列と同じバックスラッシュ記法と、 正規表現 \w, \W, \s, \S, \d, \D (これらは文字クラスの略記法です)が 使用できます。 *21
否定による以下のような文字クラスは改行文字にもマッチすることに 注意してください(正規表現 \W,\D も同様)。
p /[^a-z]/ =~ "\n" # => 0
文字クラスの中では以下の特殊な指定が使用できますが、この機能は将来に渡っ てサポートされるとは約束されていません(なのでここでは詳細は書きません *22)。
[:alnum:] 数字とアルファベット 0-9a-zA-Z [:alpha:] アルファベット a-zA-Z [:blank:] 空白類 [:cntrl:] コントロール文字 [:digit:] 数字 [:graph:] 空白を除く印字可能な可視文字 [:lower:] 小文字 [:print:] 可視文字 [:punct:] 記号 [:space:] 空白文字 [:upper:] 大文字 [:xdigit:] 16進文字
例: ("[]" を含めて "[:...:]" が1文字を表していることに注意。 文字クラスの "[]" ではない)
p /[[:alnum:][:cntrl:]]/ =~ "a\x01" # => 0
注: 全角文字は考慮されません。正規表現が漢字にマッチするように指定さ れていても [:alpha:] などは、全角のアルファベットとはマッチしません。
p /[[:alpha:]]/e =~ "A" # => nil
(?> )
という特殊な括弧で正規表現をかこむと、その括弧の中の表現に
マッチした部分ではバックトラックが起こりません。その意味を例を挙げて
見てみます。
例えば通常の正規表現では
p /(a*)ab/ === 'aaab'
はマッチします。その過程は以下のようになります。
a*
がインデックス 0 で a
みっつにマッチするa
がマッチに失敗a*
がマッチした分を少し「あきらめさせて」、
a
ふたつにマッチさせる (バックトラックする)a
が a
にマッチするb
が b
にマッチするしかしこの正規表現の括弧を (?> )
に変えるとマッチしなくなります。
その過程は以下のようになります。
a*
がインデックス 0 で a
みっつにマッチするa
がマッチに失敗a*
がマッチした分をすこし減らして試したいが、
抑止指定されているのですぐに失敗するa*
がインデックス 1 で a
ふたつにマッチする以下同じように失敗して、最終的にマッチ全体が失敗します。
ひらたく言うと、通常の正規表現の基本が「欲張りマッチ」なのに対して、
(?> )
は一回取ったものは絶対に離さない「超欲張りマッチ」を行います。
文字列クラス。任意の長さのバイト列を扱うことができます。
このクラスのメソッドのうち名前が !
で終るものは文字列の中身を
直接変更します。このような場合は !
のついていない同じ名前の
メソッドを使うほうが概して安全です。たとえば以下のような場合に問題に
なることがあります。
def foo(arg) arg.sub!(/good/, 'bad') arg end s = 'verygoodname' p foo(s) # => 'verybadname' p s # => 'verybadname'
また日本語文字列を正しく処理するためには組込み変数 $KCODE を 文字コードにあわせて設定しておく必要があります。 *24 *25 String クラスは自身をバイト列として扱います。例えば str[1] は str の内 容がなんであれ 2 バイト目の文字コードを返します。日本語文字列に対して (バイト単位でなく)文字単位の処理を行わせたい場合は jcode.rb を使 用します。*26 *27
String.new(string)
string と同じ内容の新しい文字列を作成して返します。
ruby 1.7 feature: 引数を省略した場合は空文字列を 生成して返します。
self + other
文字列を連結した新しい文字列を返します。
例:
p 'abc' + 'def' #=> 'abcdef'
self * times
文字列の内容を times 回だけ繰り返した新しい文字列を作成して 返します。
例:
p "abc" * 4 #=> "abcabcabcabc"
self % args
文字列のフォーマット。引数をフォーマット文字列(self
)で書式化
した文字列を返します。
args が配列であれば
sprintf(self, *args)
と同じです。それ以外の場合は、
sprintf(self, args)
と同じです。詳細は sprintfフォーマットを参照してください。
p "%#x" % 10 # => "0xa" p "%#x,%#o" % [10, 10] # => "0xa,012"
self == other
self > other
self >= other
self < other
self <= other
文字列の比較。変数 $= の値が真である時、比較はア
ルファベットの大文字小文字を無視して行われます。
($=
変数はいずれ廃止されることになっています obsolete
を参照)
self << other
concat(other)
文字列 other の内容を self
に連結します。
other が 0 から 255 の範囲の Fixnum である場合は
その 1 バイトを末尾に追加します。
self
を返します。
self =~ other
正規表現 other とのマッチを行います。マッチが成功すればマッ
チした位置のインデックスを、そうでなければ nil
を返します。
other が文字列であった場合にはこれを正規表現にコンパイルして
self
に対するマッチを行います。
いずれの場合も組込み変数 $~ にマッチに関する情報 が設定されます。
other が正規表現でも文字列でもない場合は
other =~ self
を行います。
~ self
self
を正規表現にコンパイルして、組込み変数 $_
に対して
マッチを行いマッチした位置のインデックスを返します。
$_ =~ self
と同じです。
$_
が文字列でなければ nil
を返します。
self[nth]
nth 番目のバイトを整数(文字コード)で返します(逆に文字コード から文字列を得るには Integer#chr を使います)。 nth が負の場合は文字列の末尾から数えます。
nth が範囲外を指す場合は nil
を返します。
例:
p 'bar'[2] # => 114 p 'bar'[2] == ?r # => true p 'bar'[-1] # => 114 p 'bar'[3] # => nil p 'bar'[-4] # => nil
self[nth, len]
nth バイト番目から長さ len バイトの部分文字列を返しま す。nth が負の場合は文字列の末尾から数えます。
nth が範囲外を指す場合は nil
を返します。
self[substr]
self
が substr を含む場合、一致した文字列を生成して
返します。
*28
substr を含まなければ nil
を返します。
substr = "bar" result = "foobar"[substr] p result # => "bar" p substr.equal? result # => true (将来のリリースでは false かも # しれない。実際、version 1.7.2 # では false になる)
self[regexp]
self[regexp, nth] ((<ruby 1.7 feature>))
regexp にマッチする最初の部分文字列を返します。組込み変数 $~ にマッチに関する情報が設定されます。
regexp にマッチしない場合 nil
を返します。
p "foobar"[/bar/] # => "bar" p $~.begin(0) # => 3
ruby 1.7 feature:
引数 nth を指定した場合は、regexp の、nth 番目の
括弧にマッチする最初の部分文字列を返します。nth が 0 の場合
は、マッチした部分文字列全体を返します。マッチしなかった場合や
nth に対応する括弧がなければ nil
を返します。
p "foobar"[/bar/] # => "bar" p $~.begin(0) # => 3 p "def getcnt(line)"[ /def\s*(\w+)/, 1 ] # => "getcnt"
self[first..last]
インデックス first から last までのバイトを含む 新しい文字列を作成して返します。
. 0 1 2 3 4 5 (インデックス) -6 -5 -4 -3 -2 -1 (負のインデックス) | a | b | c | d | e | f | |<--------->| 'abcdef'[0..2] # => 'abc' |<----->| 'abcdef'[4..5] # => 'ef' |<--------->| 'abcdef'[2..4] # => 'cde'
last が文字列の長さ以上のときは(文字列の長さ - 1)を指定 したものとみなされます。
first が 0 より小さいか文字列の長さより大きいとき、
および first > last + 1
であるときは nil
を
返します。ただし first および last のどちらか
または両方が負の数のときは一度だけ文字列の長さを足して
再試行します。
例:
'abcd'[ 2 .. 1] # => "" 'abcd'[ 2 .. 2] # => "c" 'abcd'[ 2 .. 3] # => "cd" 'abcd'[ 2 .. 4] # => "cd" 'abcd'[ 2 .. -1] # => "cd" # str[f..-1] は「f 文字目から 'abcd'[ 2 .. -2] # => "c" # 文字列の最後まで」を表す慣用句 'abcd'[ 1 .. 2] # => "bc" 'abcd'[ 2 .. 2] # => "c" 'abcd'[ 3 .. 2] # => "" 'abcd'[ 4 .. 2] # => nil 'abcd'[-3 .. 2] # => "bc" 'abcd'[-4 .. 2] # => "abc" 'abcd'[-5 .. 2] # => nil
self[first...last]
文字列先頭を 0 番目の隙間、末尾を self.length 番目の隙間として、 first 番目の隙間から last 番目の隙間までに含まれる バイト列を含んだ新しい文字列を作成して返します。
文字列と「隙間」の模式図 0 1 2 3 4 5 6 (隙間番号) -6 -5 -4 -3 -2 -1 (負の隙間番号) | a | b | c | d | e | f | |<--------->| 'abcdef'[0...3] # => 'abc' |<----->| 'abcdef'[4...6] # => 'ef' |<--------->| 'abcdef'[2...5] # => 'cde'
last が文字列の長さよりも大きいときは文字列の長さを 指定したものとみなされます。
first
が 0 より小さいか文字列の長さより大きいとき、
および first > last
であるときは nil
を返します。
ただし first と last のどちらかまたは両方が負の数
であるときは一度だけ文字列の長さを足して再試行します。
例:
'abcd'[ 2 ... 3] # => "c" 'abcd'[ 2 ... 4] # => "cd" 'abcd'[ 2 ... 5] # => "cd" 'abcd'[ 1 ... 2] # => "b" 'abcd'[ 2 ... 2] # => "" 'abcd'[ 3 ... 2] # => nil 'abcd'[-3 ... 2] # => "b" 'abcd'[-4 ... 2] # => "ab" 'abcd'[-5 ... 2] # => nil
self[nth]=val
nth 番目のバイトを文字列 val で置き換えます。 val が 0 から 255 の範囲の整数である場合、文字コード とみなしてその文字で置き換えます。
val を返します。
self[nth, len]=val
nth バイト番目から長さ len バイトの部分文字 列を文字列 val で置き換えます。nth が負の場 合は文字列の末尾から数えます。
val を返します。
self[substr]=val
文字列中の substr に一致する最初の部分文字列を文字列 val で置き換えます。
val を返します。
self[regexp]=val
self[regexp, nth]=val ((<ruby 1.7 feature>))
正規表現 regexp にマッチする最初の部分文字列を文字列 val で置き換えます。
正規表現がマッチしなければ例外 IndexError が発生します。
val を返します。
ruby 1.7 feature: 引数 nth を指定した場合は、正規表現 regexp の nth 番目の括弧にマッチする最初の部分文字列を文字列 val で置き換えます。nth が 0 の場合は、マッチした部分文字列全体 を val で置き換えます。
正規表現がマッチしない場合や nth に対応する括弧が なければ例外 IndexError が発生します。
self[first..last]=val
self[first...last]=val
first から last までの部分文字列を文字列 val で 置き換えます。
val を返します。
self <=> other
self
と other を ASCII コード順で比較して、self
が大きい時に正、等しい時に 0、小さい時に負の整数を返します。
変数 $= の値が真である時、比較は常にアルファベッ
トの大文字小文字を無視して行われます。
($=
変数はいずれ廃止されることになっています obsolete
を参照)
capitalize
capitalize!
先頭の文字を(アルファベットであれば)大文字に、残りを小文字に変更します。
capitalize
は変更後の文字列を生成して返します。
capitalize!
は self
を変更して返しますが、変更が起こら
なかった場合は nil
を返します。
p "foobar".capitalize # => "Foobar"
$KCODE
が適切に設定されていなければ、漢字コードの一部も変換
してしまいます(これは、ShiftJIS コードで起こり得ます)。
逆に、$KCODE
を設定してもマルチバイト文字のアルファベット
は処理しません。
# -*- Coding: shift_jis -*- $KCODE ='n' puts "帰".capitalize # => 蟻
casecmp(other) ((<ruby 1.7 feature>))
String#<=> と同様に文字列の順序を比較しますが、アル ファベットの大文字小文字の違いを無視します。
このメソッドの動作は $= には影響されません。
p 'a' <=> 'A' #=> 1 p 'a'.casecmp('A') #=> 0
center(width)
ljust(width)
rjust(width)
それぞれ中央寄せ、左詰め、右詰めした文字列を返します。
p "foo".center(10) # => " foo " p "foo".ljust(10) # => "foo " p "foo".rjust(10) # => " foo"
文字列の長さが width より長い時には元の文字列をそのまま返し ます*29。
s = "foo" p s.center(1).id == s.id # => true
chomp([rs])
chomp!([rs])
文字列の末尾から rs で指定する行区切りを取り除きます。 rsのデフォルト値は変数$/の値です。
rs に nil
を指定した場合、このメソッドは何もしません。
rsが空文字列(パラグラフモード)の場合、末尾の連続する改行はす
べて取り除かれます。
chomp
は改行を取り除いた文字列を生成して返します。
chomp!
は self
を変更して返しますが、取り除く改行が
なかった場合は nil
を返します。
ruby 1.7 feature: rs が "\n"(デフォルト)のとき、システムによらず "\r", "\r\n", "\n" のいずれでも行区切りの文字とみなして取り除きます。
p "foo\r".chomp # => "foo" p "foo\r\n".chomp # => "foo" p "foo\n".chomp # => "foo" p "foo\n\r".chomp # => "foo\n"
chop
chop!
文字列の最後の文字を取り除きます(終端が"\r\n"であれば2文字取 り除きます)。
chop
は最後の文字を取り除いた文字列を生成して返します。
chop!
は self
を変更して返しますが、取り除く文字がなかった
場合は nil
を返します。
clone
dup
文字列と同じ内容を持つ新しい文字列を返します。フリーズした文字列の
clone
はフリーズされた文字列を返しますが、dup
は内容の
等しいフリーズされていない文字列を返します。
count(str[, str2[, ... ]])
文字列中にある、str に含まれる文字の数を返します。
str の形式は tr(1) と同じです。つまり、
`a-c
' は a
から c
を意味し、"^0-9"
のように
文字列の先頭が `^
' の場合は指定文字以外を意味します。
`-
' は文字列の両端にない場合にだけ範囲指定の意味になります。
同様に、`^
' もその効果は文字列の先頭にあるときだけです。また、
`-
', `^
', `\
' はバックスラッシュ(`\
')によ
りエスケープすることができます。
引数を複数指定した場合は、すべての引数の積集合を意味します。
p 'abcdefg'.count('c') # => 1 p '123456789'.count('2378') # => 4 p '123456789'.count('2-8', '^4-6') # => 4
以下はこのメソッドの典型的な使用例で、ファイルの行数を返します (ただしファイルの末尾に改行が必要です)。
n_lines = File.open("foo").read.count("\n")
crypt(salt)
self
と salt から暗号化された文字列を生成して返します。
salt には英数字、ドット(.)、スラッシュ(/)から構成される、
2 バイト以上の文字列を指定します。
salt には、以下の様になるべくランダムな文字列を選ぶべきです。 *30
salt = [rand(64),rand(64)].pack("C*").tr("\x00-\x3f","A-Za-z0-9./") passwd.crypt(salt)
暗号化された文字列から暗号化前の文字列 (self
) を求めることは
一般に難しいとされ、self
を知っている者のみが同じ暗号化
された文字列を生成できます。このことから self
を知っているか
どうかの認証に使うことが出来ます。
例えば UNIX パスワードの認証は以下のようにして行われます。 (この例は Etc.getpwnam で暗号化文字列が得られることを仮定しています)。
require 'etc' user = "foo" passwd = "bar" ent = Etc.getpwnam(user) p passwd.crypt(ent.passwd) == ent.passwd
注意:
delete(str[, str2[, ... ]])
delete!(str[, str2[, ... ]])
文字列から str に含まれる文字を取り除きます。
str の形式は tr(1) と同じです。つまり、
`a-c
' は a
から c
を意味し、"^0-9"
のように
文字列の先頭が `^
' の場合は指定文字以外を意味します。
`-
' は文字列の両端にない場合にだけ範囲指定の意味になります。
同様に、`^
' もその効果は文字列の先頭にあるときだけです。また、
`-
', `^
', `\
' はバックスラッシュ(`\
')によ
りエスケープすることができます。
引数を複数指定した場合は、すべての引数の積集合を意味します。
p "123456789".delete("2-8", "^4-6") #=> "14569" p "123456789".delete("2378") #=> "14569"
delete
は変更後の文字列を生成して返します。
delete!
は self
を変更して返しますが、変更が起こら
なかった場合は nil
を返します。
downcase
downcase!
文字列中のアルファベット大文字をすべて小文字に置き換えます。
downcase
は変更後の文字列を生成して返します。
downcase!
は self
を変更して返しますが、置換が起こら
なかった場合は nil
を返します。
$KCODE
が適切に設定されていなければ、漢字コードの一部も変換
してしまいます(これは、ShiftJIS コードで起こり得ます)。
逆に、$KCODE
を設定してもマルチバイト文字のアルファベット
は処理しません。
# -*- Coding: shift_jis -*- $KCODE ='n' puts "帰".downcase # => 蟻
upcase, swapcase, capitalize も参照してください。
dump
文字列中の非表示文字をバックスラッシュ記法に置き換えた文字列を
返します。str == eval(str.dump)
となることが保証されています。
puts "abc\r\n\f\x00\b10\\\"".dump #=> "abc\r\n\f\000\01010\\\""
each([rs]) {|line| ... }
each_line([rs]) {|line| ... }
文字列中の各行に対して繰り返します。行の区切りは rs に指定 した文字列で、そのデフォルトは変数 $/ の値です。 各 line には区切りの文字列も含みます。
rs に nil
を指定すると行区切りなしとみなします。
空文字列 ""
を指定すると連続する改行を行の区切りとみなします
(パラグラフモード)。
self
を返します。
each_byte {|byte| ... }
文字列の各バイトに対して繰り返します。
self
を返します。
empty?
文字列が空(つまり長さ 0)の時、真を返します。
gsub(pattern, replace)
gsub!(pattern, replace)
gsub(pattern) {|matched| .... }
gsub!(pattern) {|matched| .... }
文字列中で pattern にマッチする部分全てを replace で
置き換えます。置換文字列 replace 中の \&
と
\0
はマッチした部分文字列に、\1 ... \9
は n 番
目の括弧の内容に置き換えられます。置換文字列内では \`
、
\'
、\+
も使えます。これらは $`、
$'、$+ に対応します。
p 'abcabc'.gsub(/b/, '(\&)') #=> "a(b)ca(b)c"
引数 replace を省略した時にはイテレータとして動作し、 ブロックを評価した結果で置換を行います。ブロックには引数として マッチした部分文字列が渡されます。 またブロックなしの場合と違い、ブロックの中からは組込み変数 $<digits> を参照できます。
p 'abcabc'.gsub(/b/) {|s| s.upcase } #=> "aBcaBc" p 'abcabc'.gsub(/b/) { $&.upcase } #=> "aBcaBc"
gsub
は置換後の文字列を生成して返します。
gsub!
は self
を変更して返しますが、置換が起こらなかっ
た場合は nil
を返します。
p 'abcdefg'.gsub(/cd/, 'CD') #=> "abCDefg" str = 'abcdefg' str.gsub!(/cd/, 'CD') p str #=> "abCDefg" p 'abbbxabx'.gsub(/a(b+)/, '\1') #=> "bbbxbx"
注意: 引数 replace の中で $<digits>
を使うことはできません。この文字列が評価される時点ではまだマッチが
行われていないからです。また replace は \
を 2 重にエ
スケープしなければなりません(trap::\の影響参照)。
# 第二引数の指定でよくある間違い p 'abbbcd'.gsub(/a(b+)/, "#{$1}") # これは間違い p 'abbbcd'.gsub(/a(b+)/, "\1") # これも間違い p 'abbbcd'.gsub(/a(b+)/, "\\1") # これは正解 p 'abbbcd'.gsub(/a(b+)/, '\1') # これも正解 p 'abbbcd'.gsub(/a(b+)/, '\\1') # これも正解(より安全) p 'abbbcd'.gsub(/a(b+)/) { $1 } # これも正解(もっとも安全)
sub も参照してください。
hex
文字列を 16 進数表現と解釈して、整数に変換します。
p "10".hex # => 16 p "ff".hex # => 255 p "0x10".hex # => 16 p "-0x10".hex # => -16
接頭辞 "0x", "0X" は無視されます。[_0-9a-fA-F]
以外の
文字があればそこまでを変換対象とします。変換対象が空文字列であれば
0 を返します。
p "xyz".hex # => 0 p "10z".hex # => 16 p "1_0".hex # => 16
oct, to_i, to_f, Integer, Float も参照してください。
逆に、数値を文字列に変換するには sprintf, %, Integer#to_s を使用します。
include?(substr)
文字列中に部分文字列 substr が含まれていれば真を返します。
substr が 0 から 255 の範囲の Fixnum の場合、文字コー ドとみなして、その文字が含まれていれば真を返します。
index(pattern[, pos])
部分文字列の探索を左端から右端に向かって行います。見つかった部分文
字列の左端の位置を返します。見つからなければ nil
を返します。
引数 pattern には探索する部分文字列の指定を文字列、文字コー ドを示す 0 から 255 の整数、正規表現のいずれかで指定します。
pos が与えられた時にはその位置から探索します。pos の省 略時の値は 0 です。
p "astrochemistry".index("str") # => 1 p "character".index(?c) # => 0 p "regexpindex".index(/e.*x/, 2) # => 3
pos が負の場合、文字列の末尾から数えた位置から探索します。
p "foobarfoobar".index("bar", 6) # => 9 p "foobarfoobar".index("bar", -6) # => 9
rindex も参照してください。
insert(nth, other) ((<ruby 1.7 feature>))
nth 番目の文字の直前に文字列 other を挿入します。 以下と(戻り値を除いて)同じです。
self[nth, 0] = other
self
を返します。
str = "foobaz" p str.insert(3, "bar") # => "foobarbaz"
intern
文字列に対応するシンボル値(Symbol)を返します。ナルキャラクタ
('\0')を含む文字列は intern
できません(例外
ArgumentError が発生します).
シンボルに対応する文字列を得るには Symbol#to_s (またはSymbol#id2name)を使います。
p "foo".intern => :foo p "foo".intern.to_s == "foo" => true
length
size
文字列のバイト数を返します。
match(regexp) ((<ruby 1.7 feature>))
regexp.match(self) と同じです (Regexp#match 参照)。 regexp が文字列の場合は、正規表現にコンパイルします。
next
next!
succ
succ!
以下のような次の文字列を返します。
"aa".succ => "ab" "99".succ => "100" "a9".succ => "b0" "Az".succ => "Ba" "zz".succ => "aaa"
succ!
, next!
は文字列の内容を破壊的に修正します。
oct
文字列を 8 進文字列であると解釈して、整数に変換します。
p "10".oct # => 8 p "010".oct # => 8 p "8".oct # => 0
oct
は文字列の接頭辞("0", "0b", "0B", "0x", "0X")に応じて 8
進以外の変換も行います。
p "0b10".oct # => 2 p "10".oct # => 8 p "010".oct # => 8 p "0x10".oct # => 16
整数とみなせない文字があればそこまでを変換対象とします。変換対象が 空文字列であれば 0 を返します。 *31
p "1_0_1x".oct # => 65
hex, to_i, to_f, Integer, Float も参照してください。
逆に、数値を文字列に変換するには sprintf, %, Integer#to_s を使用します。
replace(other)
文字列の内容を other の内容で置き換えます。
s = "foo" id = s.id s.replace "bar" p s # => "bar" p id == s.id # => true
self
を返します。
reverse
reverse!
文字列をひっくり返します。
p "foobar".reverse # => "raboof"
reverse
は変更後の文字列を生成して返します。
reverse!
は self
を変更してそれを返します。
rindex(pattern[, pos])
部分文字列の探索を右端から左端に向かって行います。見つかった部分文
字列の左端の位置を返します。見つからなければ nil
を返します。
引数 pattern には探索する部分文字列の指定を文字列、文字コー ドを示す 0 から 255 の整数、正規表現のいずれかで指定します。
pos が与えられた時にはその位置から探索します。pos の省
略時の値は self
.size (右端)です。
p "astrochemistry".rindex("str") # => 10 p "character".rindex(?c) # => 5 p "regexprindex".rindex(/e.*x/, 2) # => 1
pos が負の場合、文字列の末尾から数えた位置から探索します。
p "foobarfoobar".rindex("bar", 6) # => 3 p "foobarfoobar".rindex("bar", -6) # => 3
index と完全に左右が反転した動作をするわけではありま せん。探索はその開始位置を右から左にずらしながら行いますが、部分文 字列の照合は左から右に向かって行います。以下の例を参照してください。 *32
# String#index の場合 p "foobar".index("bar", 2) # => 3 # bar <- ここから探索を行う # bar <- 右にずらしてここで見つかる # String#rindex の場合 p "foobar".rindex("bar", -2) # => 3 # bar <- ここ(右端が末尾から 2 番目)ではなく # bar <- ここから探索を行う(左端が末尾から2番目) # bar <- 左にずらしてここで見つかる
scan(re)
scan(re) {|s| ... }
self
に対して正規表現 re で繰り返しマッチを行い、マッ
チした部分文字列の配列を返します。
p "foobar".scan(/./) # => ["f", "o", "o", "b", "a", "r"] p "foobarbazfoobarbaz".scan(/ba./) # => ["bar", "baz", "bar", "baz"]
正規表現が括弧を含む場合は、括弧で括られたパターンにマッチした部分 文字列の配列の配列を返します。
p "foobar".scan(/(.)/) # => [["f"], ["o"], ["o"], ["b"], ["a"], ["r"]] p "foobarbazfoobarbaz".scan(/(ba)(.)/) # => [["ba", "r"], ["ba", "z"], ["ba", "r"], ["ba", "z"]]
ブロックを指定して呼び出した場合は、マッチした部分文字列(括弧を含
む場合は括弧で括られたパターンにマッチした文字列の配列)をブロック
のパラメータとします。ブロックを指定した場合は self
を返しま
す。
"foobarbazfoobarbaz".scan(/ba./) {|s| p s} # => "bar" "baz" "bar" "baz" "foobarbazfoobarbaz".scan(/(ba)(.)/) {|s| p s} # => ["ba", "r"] ["ba", "z"] ["ba", "r"] ["ba", "z"]
slice(nth[, len])
slice(substr)
slice(first..last)
slice(first...last)
slice(regexp[, nth])
self[] と同じです。
ruby 1.7 feature: slice(regexp, nth) は、version 1.7 以降で 使用できます。
slice!(nth[, len])
slice!(substr)
slice!(first..last)
slice!(first...last)
slice!(regexp[, nth])
指定した範囲(self[] 参照)を文字列から取り除いたう えで取り除いた部分文字列を返します。
ruby 1.7 feature: slice!(regexp, nth) は、version 1.7 以降で 使用できます。
split([sep[, limit]])
文字列を sep で指定されたパターンによって分割して配列に格納 します。sep が 1 バイトの文字列ならその文字を区切りとして分 割します。2 バイト以上の文字列なら正規表現にコンパイルされます。 sep が省略された時のデフォルトは変数 $; の 値が用いられます。
sep が 1 つの空白(' '
)の時、または sep を省略し
た場合で $;
の値が nil
の時には先頭の空白を除いて空白
で分割を行います。
p " a \t b \n c".split(/\s+/) # => ["", "a", "b", "c"] p " a \t b \n c".split # => ["a", "b", "c"] ($;のデフォルト値はnilです) p " a \t b \n c".split(' ') # => ["a", "b", "c"]
limit が省略された時(または 0 の時)には配列末尾の空文字列は 取り除かれます。 limit が指定されて、その値が負でない時には最大 limit 個のフィールドに分割します。 limit の値が負の時には無限に大きい limit が指定された かのように分割します。
p "a,b,c,,,".split(/,/) # => ["a", "b", "c"] p "a,b,c,,,".split(/,/, 0) # => ["a", "b", "c"] p "a,b,c,,,".split(/,/, 6) # => ["a", "b", "c", "", "", ""] p "a,b,c,,,".split(/,/, -1) # => ["a", "b", "c", "", "", ""]
sep で指定されたパターンが空文字列とマッチする場合は文字列が 1 文字ずつに分割されます($KCODE が適切に設定されて いれば漢字を認識して文字単位で分割します)。例えば:
p 'hi there'.split(/ */).join(':') # => "h:i:t:h:e:r:e"
sep で指定されたパターンに括弧が含まれている場合には、各括弧 のパターンにマッチした文字列も配列に含まれます。括弧が複数ある場合 は、マッチしたものだけが配列に含まれます。例えば:
p '1-10,20'.split(/([-,])/) # => ["1", "-", "10", ",", "20"] p '1-10,20'.split(/(-)|(,)/) # => ["1", "-", "10", ",", "20"]
squeeze([str[,str2[, ... ]]])
squeeze!([str[,str2[, ... ]]])
str に含まれる同一の文字の並びをひとつにまとめます。
str の形式は tr(1) と同じです。つまり、
`a-c
' は a
から c
を意味し、"^0-9"
のように
文字列の先頭が `^
' の場合は指定文字以外を意味します。
`-
' は文字列の両端にない場合にだけ範囲指定の意味になります。
同様に、`^
' もその効果は文字列の先頭にあるときだけです。また、
`-
', `^
', `\
' はバックスラッシュ(`\
')によ
りエスケープすることができます。
引数を複数指定した場合は、すべての引数の積集合を意味します。
p "112233445566778899".squeeze =>"123456789" p "112233445566778899".squeeze("2-8") =>"11234567899" p "112233445566778899".squeeze("2-8", "^4-6") =>"11234455667899" p "112233445566778899".squeeze("2378") =>"11234455667899"
squeeze
は変更後の文字列を生成して返します。
squeeze!
は self
を変更して返しますが、変更が起こらな
かった場合は nil
を返します。
strip
strip!
lstrip ((<ruby 1.7 feature>))
lstrip! ((<ruby 1.7 feature>))
rstrip ((<ruby 1.7 feature>))
rstrip! ((<ruby 1.7 feature>))
先頭と末尾の空白(whitespace)を取り除きます。
strip
は変更後の文字列を生成して返します。
strip!
は self
を変更して返しますが、取り除く空白が
なかった場合は nil
を返します。
ruby 1.7 feature:
lstrip
は先頭部分だけ、rstrip
は末尾部分だけの空白を取
り除きます。
sub(pattern, replace)
sub!(pattern, replace)
sub(pattern) {|matched| ... }
sub!(pattern) {|matched| ... }
文字列中で pattern に最初にマッチする部分を replace で 置き換えます。
ブロックを指定して呼び出された時には、最初にマッチした部分をブロッ クを評価した値で置き換えます。
sub
は置換後の文字列を生成して返します。
sub!
は self
を変更して返しますが、置換が起こら
なかった場合は nil
を返します。
マッチを一度しか行わない点を除けば gsub と同じです。
sum([bits=16])
文字列の bits ビットのチェックサムを計算します。 以下と同じです。
sum = 0 str.each_byte {|c| sum += c} sum = sum & ((1 << bits) - 1) if bits != 0
例えば以下のコードで System V の sum(1) コマンドと 同じ値が得られます。
sum = 0 while gets sum += $_.sum end sum %= 65536
swapcase
swapcase!
全ての大文字を小文字に、小文字を大文字に変更します。
swapcase
は置換後の文字列を生成して返します。
swapcase!
は self
を変更して返しますが、置換が起こら
なかった場合は nil
を返します。
$KCODE
が適切に設定されていなければ、漢字コードの一部も変換
してしまいます(これは、ShiftJIS コードで起こり得ます)。
逆に、$KCODE
を設定してもマルチバイト文字のアルファベット
は処理しません。
# -*- Coding: shift_jis -*- $KCODE ='n' puts "蟻".swapcase # => 帰
upcase, downcase, capitalize も参照してください。
to_f
文字列を 10 進数表現と解釈して、浮動小数点数 Float に変換します。
p "10".to_f # => 10.0 p "10e2".to_f # => 1000.0 p "1e-2".to_f # => 0.01 p ".1".to_f # => 0.1 p "nan".to_f # => NaN p "INF".to_f # => Infinity p "-Inf".to_f # => -Infinity p (("10" * 1000).to_f) # => Infinity p "0xa.a".to_f # => 10.625 # 16 進も許される(システム依存) p " \n10".to_f # => 10.0 # 先頭の空白は無視される p "1_0_0".to_f # => 1.0 # `_' は数値要素とみなされない
浮動小数点数とみなせなくなったところで、そこまでを変換対象とします。 変換対象が空文字列であれば 0.0 を返します。 *33
hex, oct, to_i, Integer, Float も参照してください。
逆に、数値を文字列に変換するには sprintf, %, Integer#to_s を使用します。
to_i
to_i(base) ((<ruby 1.7 feature>))
文字列を 10 進数表現と解釈して、整数に変換します。
p " 10".to_i # => 10 p "010".to_i # => 10 p "-010".to_i # => -10
整数とみなせない文字があればそこまでを変換対象とします。変換対象が 空文字列であれば 0 を返します。
p "0x11".to_i # => 0
hex, oct, to_f, Integer, Float も参照してください。
逆に、数値を文字列に変換するには sprintf, %, Integer#to_s を使用します。
ruby 1.7 feature: 基数を指定することでデフォルトの 10 進以外に 2, 8, 16 進数への変換 を行うことができます。これら以外の引数を指定した場合、例外 ArgumentError が発生します。
to_s
to_str
self
を返します。
tr(search, replace)
tr!(search, replace)
文字列の中に search 文字列に含まれる文字が存在したら、 それを replace 文字列の対応する文字に置き換えます。
search の形式は tr(1) と同じです。つまり、
`a-c
' は a
から c
を意味し、"^0-9"
のように
文字列の先頭が `^
' の場合は指定文字以外が置換の対象になります。
replace に対しても `-
' による範囲指定が可能です。
例えば、String#upcase を tr
で書くと、
p "foo".tr('a-z', 'A-Z') => "FOO"
となります。
`-
' は文字列の両端にない場合にだけ範囲指定の意味になります。
同様に、`^
' もその効果は文字列の先頭にあるときだけです。また、
`-
', `^
', `\
' はバックスラッシュ(`\
')によ
りエスケープすることができます。
replace の範囲が search の範囲よりも小さい場合は、 replace の最後の文字が無限に続くものとして扱われます。
tr
は置換後の文字列を生成して返します。
tr!
は self
を変更して返しますが、置換が起こら
なかった場合は nil
を返します。
tr_s(search, replace)
tr_s!(search, replace)
文字列の中に search 文字列に含まれる文字が存在したら、 replace 文字列の対応する文字に置き換えます。さらに、 置換した部分内に同一の文字の並びがあったらそれを 1 文字に圧縮します。
search の形式は tr(1) と同じです。つまり、
`a-c
' は a
から c
を意味し、"^0-9"
のように
文字列の先頭が `^
' の場合は指定文字以外が置換の対象になります。
replace に対しても `-
' による範囲指定が可能です。
p "foo".tr_s('a-z', 'A-Z') => "FO"
`-
' は文字列の両端にない場合にだけ範囲指定の意味になります。
同様に、`^
' もその効果は文字列の先頭にあるときだけです。また、
`-
', `^
', `\
' はバックスラッシュ(`\
')によ
りエスケープすることができます。
replace の範囲が search の範囲よりも小さい場合、 replace の最後の文字が無限に続くものとして扱われます。
tr_s
は置換後の文字列を生成して返します。
tr_s!
は self
を変更して返しますが、置換が起こら
なかった場合は nil
を返します。
注意: このメソッドと tr(search, replace).squeeze(replace)
とでは挙動が異なります。tr と squeeze の組みあわせが置換後の文字列全体を
squeeze の対象にするのに対して、tr_s
は置換された部分だけを
squeeze の対象とします。
p "foo".tr_s("o", "f") # => "ff" p "foo".tr("o", "f").squeeze("f") # => "f"
unpack(template)
パックされた (おそらくは Array#pack で生成された) 文字列を template 文字列にしたがってアンパックし、それらの要 素を含む配列を返します。template 文字列のフォーマットについ てはpackテンプレート文字列を参照してください。
upcase
upcase!
ASCII 文字列の範囲内でアルファベットを全て大文字にします
upcase
は置換後の文字列を生成して返します。
upcase!
は self
を変更して返しますが、置換が起こら
なかった場合は nil
を返します。
$KCODE
が適切に設定されていなければ、漢字コードの一部も変換
してしまいます(これは、ShiftJIS コードで起こり得ます)。
逆に、$KCODE
を設定してもマルチバイト文字のアルファベット
は処理しません。
# -*- Coding: shift_jis -*- $KCODE ='n' puts "蟻".upcase # => 帰
downcase, swapcase, capitalize も参照してください。
upto(max) {|s| ... }
self
から始めて max まで「次の文字列」を順番にブロックに
与えて繰り返します。「次」の定義については String#succ を
参照してください。
このメソッドは文字列の Range の内部で使用されます。 *34
たとえば以下のコードは a, b, c, ... z,aa, ... az, ..., za
を
出力します。*35
("a" .. "za").each do |str| puts str end
Rubyの現在の実装はASCIIキャラクタセットを用いています。アル ファベットの大文字と小文字は区別されます。識別子と一部のリテ ラルの途中を除いては任意の場所に空白文字やコメントを置くこと ができます。空白文字とはスペース、タブ、垂直タブ、バックスペー ス、キャリッジリターン、改ページです。改行は行が明らかに次の 行に継続する時だけ、空白文字として、それ以外では文の区切りと して解釈されます。
例:
foobar ruby_is_simple
Rubyの識別子は英文字またはアンダースコア('_'
)か
ら始まり、英文字、アンダースコア('_'
)または数字
からなります。識別子の長さに制限はありません。
例:
# this is a comment line
スクリプト言語の習慣にならい、文字列中や数値リテラル
(?#
)以外の#
から行末までをコメント
と見なします。
例:
=begin the everything between a line beginning with `=begin' and that with `=end' will be skipped by the interpreter. =end
Rubyのソースコードにドキュメントを埋め込む事ができます。文が
始まる部分の行頭の=begin
から、=end
で始まる行までが
埋め込みドキュメントです。Rubyインタプリタとしては内容に縛りは
かけませんが、通常はRD形式でドキュメントを埋め込むことを
期待しています。
予約語は以下のものです。
BEGIN class ensure nil self when END def false not super while alias defined for or then yield and do if redo true begin else in rescue undef break elsif module retry unless case end next return until
予約語はクラス名、変数名などに用いることはできません。ただし
接頭辞$
, @
、@@
が先頭についたものは予約語
とは見なされません。また、def
のあとやメソッド呼び出しの
ピリオドのあとなどメソッド名であるとはっきり分かる場所では
メソッド名として用いることができます。
プログラムは式を並べたものです。式と式の間はセミコロ ン(;)または改行で区切ります。ただし、バックスラッシュに続く改行は文 の区切りにならず、次の行へ継続します。
例:
print "hello world!\n"
例:
true (1+2)*3 foo() if test then ok else ng end
式は括弧によってグルーピングすることができます。
Rubyインタプリタはプログラムを読みこんでいる際に以下のものに出あうとそこ で読みこみを終了します。
^D
(コントロールD) 、^Z
(コントロールZ)__END__
のみの行(前後に空白があると認識されません)Ruby の変数と定数の種別は変数名の最初の一文字によって、
ローカル変数、
インスタンス変数、
クラス変数、
グローバル変数、
定数
のいずれかに区別されます。
通常の変数の二文字目以降は英数字または
_
ですが、システム変数の一部には
「`$
'+1文字の記号」という変数があります(組込み変数を参照)。変数名
の長さにはメモリのサイズ以外の制限はありません。
例:
foobar
小文字または`_
'で始まる識別子はローカル変数また
はメソッド呼出しです。ローカル変数スコープ(クラス、モジュー
ル、メソッド定義の本体)における小文字で始まる識別子への最初
の代入はそのスコープに属するローカル変数の宣言になります。宣
言されていない識別子の参照は引数の無いメソッド呼び出しとみな
されます。
ローカル変数のスコープは、宣言した位置からその変数が宣 言されたブロック、メソッド定義、またはクラス/モジュール定義 の終りまでです。寿命もそのブロックの終りまで(トップレベルの ローカル変数はプログラムの終了まで)ですが、例外としてブロッ クが手続きオブジェクト化された場合は、そのオブジェクトが消滅 するまで存在します。同じスコープを参照する手続きオブジェクト 間ではローカル変数は共有されます。
# (A) の部分はスコープに入らない 2.times { p defined?(v) # (A) v = 1 # ここ(宣言開始)から p v # ここ(ブロックの終り)までが v のスコープ } # => nil 1 nil <- これが nil であることに注意 1
宣言は、例え実行されなくても宣言とみなされます。
v = 1 if false # 代入は行われないが宣言は有効 p defined?(v) # => "local-variable" p v # => nil
またあまり推奨はされませんが-Kオプショ ンを指定すれば日本語文字の識別子も使用でき、それはローカル変数とみなさ れます。
例:
@foobar
`@
'で始まる変数はインスタンス変数であり、特定の
オブジェクトに所属しています。インスタンス変数はそのクラスま
たはサブクラスのメソッドから参照できます。初期化されていない
インスタンス変数を参照した時の値はnil
です。
例:
class Foo @@foo = 1 def bar puts @@foo end end
@@
で始まる変数はクラス変数です。クラス変数はクラス定義
の中で定義され、クラスの特異メソッド、インスタンスメソッドなどから参照/
代入ができます。
クラス変数と定数の違いは以下の通りです。
クラス変数はクラス自身のインスタンス変数とは以下の点で異なります。
クラス変数は、そのクラスやサブクラス、それらのインスタンスで共有される グローバル変数であるとみなすことができます。
例:
$foobar $/
`$
'で始まる変数はグローバル変数で、プログラムの
どこからでも参照できます(その分、利用には注意が必要です)。
グローバル変数には宣言は必要ありません。
初期化されていないグローバル変数を参照した時の値は
nil
です。
通常の変数以外に疑似変数と呼ばれる特殊な変数があります。
self
現在のメソッドの実行主体
nil
NilClassクラスの唯一のインスタンス
true
TrueClassクラスの唯一のインスタンス。真の代表値
false
FalseClassクラスの唯一のインスタンス。nilとfalseは偽を表します。
__FILE__
現在のソースファイル名
__LINE__
現在のソースファイル中の行番号
疑似変数の値を変更することはできません。 擬似変数へ代入すると文法エラーになります。
例:
FOOBAR
アルファベット大文字 ([A-Z]
) で始まる識別子は定数です。
定数の定義 (と初期化) は代入によって行われますが、メソッドの
中では定義できません。一度定義された定数に再び代入を行おうと
すると警告メッセージが出ます。定義されていない定数にアクセス
すると例外 NameError が発生します。
定数はその定数が定義されたクラス/モジュール定義の中(メソッド 本体やネストしたクラス/モジュール定義中を含みます)、クラスを 継承しているクラス、モジュールをインクルードしているクラスま たはモジュールから参照することができます。クラス定義の外で定 義された定数は Object に所属することになります。
例:
class Foo FOO = 'FOO' # クラス Foo の定数 FOO を定義(Foo::FOO) end class Bar < Foo BAR = 'BAR' # クラス Bar の定数 BAR を定義(Bar::BAR) # 親クラスの定数は直接参照できる p FOO # => "FOO" class Baz # ネストしたクラスはクラスの継承関係上は無関係であるがネス # トの外側の定数も直接参照できる p BAR # => "BAR" end end
またクラス定義式はクラスオブジェクトの生 成を行うと同時に、名前がクラス名である定数にクラスオブジェクトを代入す る動作をします。クラス名を参照することは文法上は定数を参照していること になります。
class C end p C # => C
あるクラスまたはモジュールで定義された定数を外部から参照する
ためには`::
'演算子を用います。またObject
クラスで
定義されている定数(トップレベルの定数と言う)を確実に参照する
ためには左辺無しの`::
'演算子が使えます。
ただしこれらの `::
' 演算子を用いて定数に代入すること
はできません。
例:
module M I = 35 class C end end p M::I #=> 35 p M::C #=> M::C p ::M #=> M M::NewConst = 777 # error--> parse error
親クラスとネストの外側のクラスで同名の定数が定義されているとネストの外 側の定数の方を先に参照します。つまり、定数参照時の定数の探索順序は、最 初にネスト関係を外側に向かって探索し、次に継承関係を上位に向かって探索 します。
例:
class Foo CONST = 'Foo' end class Bar CONST = 'Bar' class Baz < Foo p CONST # => "Bar" 外側の定数 # この場合、親クラスの定数は明示的に指定しなければ見えない p Foo::CONST # => "Foo" end end
トップレベルの定数定義はネストの外側とはみなされません。したがってトッ プレベルの定数は、継承関係を探索した結果で参照されるので優先順位は低い と言えます。
例:
class Foo CONST = 'Foo' end CONST = 'Object' class Bar < Foo p CONST # => "Foo" end # 以下のように明示的にネストしていれば規則通り Object の定数 # (ネストの外側)が先に探索される class Object class Bar < Foo p CONST # => "Object" end end
上位のクラス(クラスの継承関係上、およびネストの関係上の上位クラス)の定 数と同名の定数(下の例で CONST) に代入を行うと、上位の定数への代入では なく、そのクラスの定数の定義になります。
例:
class Foo CONST = 'Foo' end class Bar < Foo p CONST # => "Foo" CONST = 'Bar' # Bar の定数 CONST を*定義* p CONST # => "Bar" (Foo::CONST は隠蔽される) p Foo::CONST # => "Foo" (:: 演算子で明示すれば見える) end
数字の1や文字列"hello world"のようにRubyのプログラムの中に直接 記述できる値の事をリテラルといいます。
123
整数
-123
符号つき整数 trap::Numeric
123.45
浮動小数点数
1.2e-3
浮動小数点数
0xffff
16進整数
0b1011
2進整数
0377
8進整数
?a
文字a
のコード(97)
?\C-a
コントロール a のコード(1)
?\M-a
メタ a のコード(225)
?\M-\C-a
メタ-コントロール a のコード(129)
?
表現では全てのバックスラッシュ記法が有効です。
文字コード以外の数値リテラルには、`_
' を含めることができます。
ruby インタプリタは `_
' を単に無視し、特別な解釈は何もしません。
これは、大きな数値の桁数がひと目でわかるように記述するのに便利です。
リテラルの最初と、最後には _
を書くことはできません。(リテラルの
前(符号(+,-)の直後を含む)に _
を置くとローカル変数やメソッド呼び
出しと解釈されます)
*36
1_000_000_000 => 1000000000 0xffff_ffff => 0xffffffff
例:
"this is a string expression\n" 'this is a string expression\n' %q!I said, "You said, 'She said it.'"! %!I said, "You said, 'She said it.'"! %Q('This is it.'\n)
文字列はダブルクォートまたはシングルクォートで囲まれています。
ダブルクォートで囲まれた文字列ではバックスラッシュによるエス
ケープと式展開(後述)が有効になります。シングルクォートで囲ま
れた文字列では、\\
(バックスラッシュそのもの)と
\'
(シングルクォート)、行末の\
(改行を無視します)
を除いて文字列の中身の解釈は行われません。
空白を間に挟んだ文字列リテラルは、コンパイル時に1つの文字列 リテラルと見倣されます。
p "foo" "bar" => "foobar"
%記法 による別形式の文字列表現もあります。
\t
タブ(0x09)
\n
改行(0x0a)
\r
キャリッジリターン(0x0d)
\f
改ページ(0x0c)
\b
バックスペース (0x08)
\a
ベル (0x07)
\e
エスケープ (0x1b)
\s
空白 (0x20)
\nnn
8 進数表記 (n は 0-7)
\xnn
16 進数表記 (n は 0-9,a-f)
\cx
\C-x
コントロール文字 (x は ASCII 文字)
\M-x
メタ x (c | 0x80)
\M-\C-x
メタ コントロール x
\x
文字 x そのもの
文字列式は評価されるたびに毎回新しい文字列オブジェクトを生成 します。
例:
($ruby = "RUBY"の場合) "my name is #{$ruby}" #=> "my name is RUBY" 'my name is #{$ruby}' #=> "my name is #{$ruby}"
ダブルクォート("
)で囲まれた文字列式、コマンド文
字列および正規表現、の中では#{式}
という形式で式
の内容(を文字列化したもの)を埋め込むことができます。式が変数
記号($
,@
)で始まる変数の場合には
{}
を省略して、#変数名
という形式で
も展開できます。文字#
に続く文字が
{
,$
,@
でなければ、その
まま文字#
として解釈されます。明示的に式展開を止
めるには#
の前にバックスラッシュを置きます。
例:
`date` %x{ date }
バッククォート(`
)で囲まれた文字列は、ダブルクォー
トで囲まれた文字列と同様にバックスラッシュ記法
の解釈と式展開
が行なわれた後、コマンドとして実行され、その標準出力が文字列
として与えられます。コマンドは評価されるたびに実行されます。
コマンドの終了ステータスを得るには、$? を
参照します。
%記法 による別形式のコマンド出力もあります。
Unixのシェルのような行指向の文字列リテラルの表現もあります。このよ
うな文字列リテラルを「ヒアドキュメント」と呼びます。
<<
に続いて、引用終了記号になる文字列また
は識別子を指定します。文字列を指定した場合は、その文字列の種
別(""、''、``
)が文字列全体の性質を決定します。
種別のデフォルトはダブルクォートです.
<<
の後ろには空白を置くことはできません。
print <<EOF The price is #{$Price}. EOF print <<"EOF" # 上と同じ The price is #{$Price}. EOF print <<`EOC` # コマンドを実行 echo hi there echo lo there EOC print <<"foo", <<"bar" # 連ねられます I said foo. foo I said bar. bar myfunc(<<"THIS", 23, <<'THAT') Here's a line or two. THIS and here's another. THAT
識別子または文字列の前に -
が置かれた場合、区切り
文字列の前の空白文字 (タブとスペース) が取り除かれます。
これによって区切り文字をインデントに合わせることが出来ます。
if need_define_foo eval <<-EOS # 区切り文字列をインデントできます def foo print "foo\n" end EOS end
例:
/^Ruby the OOPL/ /Ruby/i /my name is #{myname}/o %r|Ruby|
/
で囲まれた文字列は正規表現です。正規表現として解釈される
メタ文字については正規表現を参照してください。
終りの/
の直後の文字は正規表現に対するオプションになります。
オプションの機能は以下の通りです。
i
正規表現はマッチ時に大文字小文字の区別を行わない
o
一番最初に正規表現の評価が行われた時に 一度だけ式展開を行う
x
正規表現中の空白(改行も含む)を無視する。また、バックスラッシュでエス
ケープしない`#
' から改行までをコメントとみなして無視する(ただ
し、コメント中に /
を含めると構文解析に失敗するので注意)
/foo # コメント bar/x
これは /foobar/
と同じ。
空白を含めるには \
のようにエスケープします。
m
複数行モード。正規表現 "." が改行にもマッチするようになる
Ruby は日本語化されているので、$KCODE の値に従って正
規表現中の日本語文字を正しく扱います。$KCODE = "n"
の場合、日本
語文字を一切認識せずにバイト列として扱います。これはデフォルトの動作で
す。
オプションとして n
, e
, s
, u
のいずれかを指定す
ることで正規表現の文字コードを $KCODE の値に関係なく
個々の正規表現リテラルに指定することもできます。
%記法 による別形式の正規表現も指定できます。
正規表現の中では文字列と同じバックスラッシュ記法や 式展開も有効です。
例:
[1, 2, 3] %w(a b c)
文法:
`[' 式`,' ... `]'
それぞれの式を評価した結果を含む配列を返します。 配列はArrayクラスのインスタンスです。
要素が文字列リテラルの場合に限り、%記法 による別形式の 配列表現も指定できます。
例:
{1=>2, 2=>4, 3=>6}
文法:
`{' 式 `=>' 式 `,' ... `}' `{' 式 `,' 式 `,' ... `}'
それぞれの式を評価した結果をキーと値とするハッシュオブジェク トを返します。ハッシュとは任意のオブジェクトをキー(添字)として持 つ配列で、Hashクラスのインスタンスです。
ハッシュ式の要素が1つ以上あり、曖昧でなければ {
, }
は
省略しても構いません。この形式はメソッド呼び出しの引数でよく使われます。
*37
*38
例:
do_something('task'=>'resolve', 'timeout'=>10)
範囲式を参照
例:
(シンボルの例) :class :lvar :method! :andthisis? :$gvar :@ivar :@@cvar :+
文法:
`:' 識別子 `:' 変数名 `:' 演算子
Symbolクラスのインスタンス。
ある文字列とSymbol
オブジェクトは一対一に対応します。
Symbol リテラルに指定できる演算子はメソッドとして再定義できる演算子だ けです。演算子式 を参照して下さい。
文字列リテラル、
コマンド出力、
正規表現リテラル、
配列式
では、%
で始まる形式の記法を用いることができます。
文字列や正規表現では、`"', `/' など(通常のリテラルの区切り文字)を要素
に含めたい場合にバックスラッシュの数をコードから減らす効果があります。
また配列式では文字列の配列を簡単に表現できます。それぞれ以下のように対
応します。
%!STRING!
: ダブルクォート文字列%Q!STRING!
: 同上%q!STRING!
: シングルクォート文字列%x!STRING!
: コマンド出力%r!STRING!
: 正規表現%w!STRING!
: 要素が文字列の配列(空白区切り)!
の部分には改行を含めた任意の非英数字を使うことができます。始ま
りの区切り文字が括弧(`(',`[',`{',`<')である時には、終りの区切り文字は
対応する括弧になります。括弧を区切り文字にした場合、対応が取れていれば
区切り文字と同じ括弧を要素に含めることができます。
%(()) => "()"
配列式の%記法はシングルクォートで囲んだ文字列を空白文字で分割したのと 同じです。たとえば、
%w(foo bar baz)
は['foo', 'bar', 'baz']
と等価です。
バックスラッシュを使って空白を要素に含むこともできます。
%w(foo\ bar baz) => ["foo bar", "baz"]
リテラルの符号は、単項演算子 `-
', `+
' のメソッド呼び出しでは
ありません。
class Fixnum def -@ "negative #{self}" end end p -10 # => -10 n = 10 p -n # => "negative 10"
この違いは結合強度にも影響します。
p -10.abs # => 10 n = 10 p -n.abs # => -10
配列クラス。配列の要素は任意の Ruby オブジェクトです。 一般的には配列は配列式を使って
[1, 2, 3]
のように生成します。
Array[item, ...]
引数を要素として持つ配列を生成します。
Array.new([size[, val]])
Array.new(ary) ((<ruby 1.7 feature>))
Array.new(size) {|index| ... } ((<ruby 1.7 feature>))
配列を生成します。size を指定したときにはその大きさの配列を
生成し nil
で初期化します。第二引数 val も指定したとき
には nil
の代わりにそのオブジェクトを全要素にセットします。
(要素毎に val が複製されるわけではないことに注意してください。
全要素が同じオブジェクト val を参照しますtrap::Array)。
ruby 1.7 feature: 二番目の形式では引数に指定した配列を複製し て返します。
p Array.new([1,2,3]) # => [1,2,3]
三番目の形式では、ブロックの評価結果で値を設定します。ブロックは要 素毎に実行されるので、全要素をあるオブジェクトの複製にすることがで きます。
p Array.new(5) {|i| i } # => [0, 1, 2, 3, 4] ary = Array.new(3, "foo") ary.each {|obj| p obj.id } # => 537774036 537774036 537774036 ary = Array.new(3) { "foo" } ary.each {|obj| p obj.id } # => 537770448 537770436 537770424
self[nth]
nth 番目の要素を返します。先頭の要素が 0 番目になります。
nth の値が負の時には末尾からのインデックスと見倣します(末尾
の要素が -1 番目)。nth 番目の要素が存在しない時には
nil
を返します。
self[start..end]
start 番目の要素から end 番目の要素までの部分配列を返
します。start の値が負の時には末尾からのインデックスと見倣し
ます(末尾の要素が -1 番目)。start の値が配列の範囲に収まらな
い場合 nil
を返します。end の値が配列の長さを越える時
には、越えた分の長さは無視されます。また、範囲の始点が終点よりも大
きい時には nil
を返します。
self[start, length]
start 番目から length 個の要素を含む部分配列を返します。
start の値が負の時には末尾からのインデックスと見倣します(末
尾の要素が -1 番目)。length が start 番目からの配列の
長さより長い時には、越えた分の長さは無視されます。length が
負の時には nil
を返します。
self[nth]=val
nth 番目の要素を val に設定します。nth が配列の
範囲を越える時には配列の長さを自動的に拡張し、拡張した領域を
nil
で初期化します。
val を返します。
self[start..end]=val
start 番目の要素から end 番目の要素までを配列 val の内容に置換します。val の値が配列でないときには val で置換します。val の要素の数の方が多い時には、後ろ の要素がずれます。
val が nil
か 空の配列 []
なら start から
end までの要素が削除されます。
例:
ary = [0, 1, 2, 3, 4, 5] ary[0..2] = ["a", "b"] p ary # => ["a", "b", 3, 4, 5] ary[2..4] = nil p ary # => ["a", "b"]
val を返します。
self[start, length]=val
インデックス start から length 個の要素を配列
val の内容で置き換えます。val が配列でないときには
val.to_ary
もしくは [val]
の内容で置換します。
val を返します。
例:
ary = [0, 1, 2, 3] ary[1, 2] = ['a', 'b', 'c'] p ary # => [0, "a", "b", "c", 3] ary[2, 1] = 99 p ary # => [0, "a", 99, "c", 3] ary[1, 0] = ['inserted'] p ary # => [0, "inserted", "a", 1, 2, 3]
self + other
self
と other の内容を繋げた新しい配列を返します。
other が配列でなければ other.to_ary
の返り値を用います。
その返り値がまた配列でなかった場合は例外 TypeError が発生し
ます。
例:
a = [1, 2] b = [8, 9] p a + b #=> [1, 2, 8, 9] p a #=> [1, 2] (変化なし) p b #=> [8, 9] (こちらも変化なし)
self * times
配列の内容を繰り返した新しい配列を作成し返します。 値はコピーされないことに注意してくださいtrap::Array。
例:
p [1, 2, 3] * 3 #=> [1, 2, 3, 1, 2, 3, 1, 2, 3]
times が文字列なら、self.join(times) と同じ 動作をします。
p [1,2,3] * "," # => "1,2,3"
self - other
集合の差演算。self
から other の要素を
取り除いた内容の新しい配列を返します。重複する要素は取り除かれ
ます。
other が配列でなければ to_ary
メソッドによる
暗黙の型変換を試みます。
self & other
集合の積演算。両方の配列に含まれる要素からなる新しい配列を返
します。重複する要素は取り除かれます。
other が配列でなければ to_ary
メソッドによる
暗黙の型変換を試みます。
要素の重複判定は、Object#eql? により行われます。 *39
self | other
集合の和演算。両方の配列にいずれかに含まれる要素を全て含む新し
い配列を返します。重複する要素は取り除かれます。
other が配列でなければ to_ary
メソッドによる
暗黙の型変換を試みます。
要素の重複判定は、Object#eql? により行われます。
self << obj
obj を配列の末尾に追加します。Array#push
と同じ効果です。
ary = [1] ary << 2 p ary # [1, 2]
またこのメソッドは self
を返すので、以下のように連続して
書くことができます。
ary = [1] ary << 2 << 3 << 4 p ary #=> [1, 2, 3, 4]
self <=> other
self
と other
の各要素をそれぞれ順に <=>
で比較
して、self
が大きい時に正、等しい時に 0、小さい時に負の整数
を返します。各要素が等しいまま、一方だけ配列の末尾に達した時は、よ
り短い配列の方が小さいとみなします。
self == other
self
と other
の各要素をそれぞれ順に ==
で比較し
て、全要素が等しければ真を返します。
assoc(key)
配列の配列を検索して、その 0 番目の要素が key に等しい最初の
要素を返します。比較は ==
演算子を使って行われます。
該当する要素がなければ nil
を返します。
例:
ary = [[1,15], [2,25], [3,35]] p ary.assoc(2) # => [2, 25] p ary.assoc(100) # => nil p ary.assoc(15) # => nil
Array#rassoc も参照してください。
at(pos)
配列の pos の位置にある要素を返します。 self[pos] と同じです。
clear
配列の要素をすべて削除して空にします。
self
を返します。
例:
ary = [1, 2] ary.clear p ary #=> []
clone
dup
レシーバと同じ内容を持つ新しい配列を返します。clone
は
frozen tainted singleton-class の情報も含めてコピーしますが、
dup
は内容だけをコピーします。
またどちらのメソッドも要素それ自体のコピーはしません。 つまり「浅い(shallow)」コピーを行います。
例:
ary = ['string'] p ary #=> ["string"] copy = ary.dup p copy #=> ["string"] ary[0][0...3] = '' p ary #=> ["ing"] p copy #=> ["ing"]
collect! {|item| ..}
map! {|item| ..}
各要素を順番にブロックに渡して評価し、その結果で要素を 置き換えます。Enumerable#collect も参照。
self
を返します。
例:
ary = [1, 2, 3] ary.map! {|i| i * 3 } p ary #=> [3, 6, 9]
compact
compact!
compact
は self
から nil
である要素を取り除いた
新しい配列を返します。compact!
は変更を破壊的に行い、変更が
行われた場合は self
を、そうでなければ nil
を返します。
例:
ary = [1, nil, 2, nil, 3, nil] p ary.compact #=> [1, 2, 3] p ary #=> [1, nil, 2, nil, 3, nil] ary.compact! p ary #=> [1, 2, 3] p ary.compact! #=> nil
concat(other)
配列 other を self
の末尾に(破壊的に)連結します。
self
を返します。
例:
array = [1, 2] a = [3, 4] array.concat a p array # => [1, 2, 3, 4] p a # => [3, 4] # こちらは変わらない
delete(val)
delete(val) { ... }
val と ==
で等しい要素をすべて取り除きます。
val と等しい要素が見つかった場合は、val を返します。
valと等しい要素がなければ nil
を返しますが、ブロックが
指定されていればブロックを評価してその結果を返します。
例:
array = [1, 2, 3, 2, 1] p array.delete(2) #=> 2 p array #=> [1, 3, 1] # ブロックなしの引数に nil を渡すとその戻り値から削除が # 行われたかどうかの判定をすることはできない ary = [nil,nil,nil] p ary.delete(nil) #=> nil p ary #=> [] p ary.delete(nil) #=> nil
delete_at(pos)
pos で指定された位置にある要素を取り除きそれを返します。
pos が範囲外であったら nil
を返します。
at と同様に負のインデックスで末尾から位置を指定するこ とができます。
例:
array = [0, 1, 2, 3, 4] array.delete_at 2 p array #=> [0, 1, 3, 4]
delete_if {|x| ... }
reject! {|x| ... }
要素を順番にブロックに渡して評価し、その結果が真になった要素を すべて削除します。
delete_if
は常に self
を返しますが、reject!
は要
素が 1 つも削除されなければ nil
を返します。
each {|item| .... }
各要素に対してブロックを評価します。self
を返します。
例:
# 1、2、3 が順番に表示される [1, 2, 3].each do |i| puts i end
each_index {|index| .... }
各要素のインデックスに対してブロックを評価します。 以下と同じです。
(0 ... ary.size).each {|index| .... }
self
を返します。
empty?
配列の要素数が 0 の時真を返します。
eql?(other)
self
と other
の各要素をそれぞれ順に
Object#eql? で比較して、全要素が等しければ真を返
します。
fetch(nth) ((<ruby 1.7 feature>))
fetch(nth, ifnone) ((<ruby 1.7 feature>))
fetch(nth) {|nth| ... } ((<ruby 1.7 feature>))
Array#[nth] と同様 nth 番目の要素を返しますが、 Array#[nth] とは nth 番目の要素が存在しない場合の振舞いが異 なります。
最初の形式では、例外 IndexError が発生します。 二番目の形式では、引数 ifnone を返します。 三番目の形式では、ブロックを評価した結果を返します。
Array#[nth] は、Array#fetch(nth, nil) と同じです。
fill(val)
fill(val, start[, length])
fill(val, start..end)
fill {|index| ... } ((<ruby 1.7 feature>))
fill(start[, length]) {|index| ... } ((<ruby 1.7 feature>))
fill(start..end) {|index| ... } ((<ruby 1.7 feature>))
配列の、指定された範囲すべてに val をセットします。二番目の 形式で length が省略された時は配列の終りまでの長さを意味しま す。指定された部分配列が元の配列の範囲を越える時は長さを自動的に拡 張し、拡張した部分を val で初期化します。
このメソッドが val のコピーでなく val 自身をセットする ことに注意してください(trap::Array)。
val の代わりにブロックを指定するとブロックの評価結果を値とし ます。ブロックは要素毎に実行されるので、セットする値のそれぞれをあ るオブジェクトの複製にすることができます。
ary = [] p ary.fill(0,3) {|i| i} # => [0, 1, 2] p ary.fill { "foo" } # => ["foo", "foo", "foo"] p ary.collect {|v| v.id } # => [537770124, 537770112, 537770100]
first
配列の先頭の要素を返します。要素がなければ nil
を返します。
例:
p [0, 1, 2].first #=> 0 p [].first #=> nil
flatten
flatten!
ネストした配列を平滑化してそれを返します。flatten!
は
配列それ自体を破壊的に平滑化し、配列がネストしていないとき
には nil
を返します。
例:
p [1, [2, 3, [4], 5]].flatten #=> [1, 2, 3, 4, 5] array = [[[1, [2, 3]]]] array.flatten! p array #=> [1, 2, 3]
include?(val)
配列が val と ==
において等しい要素を持つ時に真を返し
ます。
index(val)
val と ==
で等しい最初の要素の位置を返します。
等しい要素がひとつもなかった時には nil
を返します。
indexes(index_1, ... , index_n)
indices(index_1, ... , index_n)
各引数の値をインデックスとする要素の配列を返します。範囲外の
インデックス指定に対しては nil
が対応します。
例:
ary = %w( a b c d e ) p ary.indexes( 0, 2, 4 ) #=> ["a", "c", "e"] p ary.indexes( 3, 4, 5, 6, 35 ) #=> ["d", "e", nil, nil] p ary.indexes( 0, -1, -2 ) #=> ["a", "e", "d"] p ary.indexes( -4, -5, -6, -35 ) #=> ["b", "a", nil, nil]
ruby 1.7 feature: このメソッドは version 1.7 では、obsolete です。 使用すると警告メッセージが表示されます。 代わりに Array#select を使用します。
insert(nth, val[, val2 ...])
インデックス nth の要素の直前に第 2 引数以降の値を挿入します。
self
を返します。以下のように定義されます。
class Array def insert( n, *vals ) self[n, 0] = vals self end end
例:
ary = %w( foo bar baz ) ary.insert 2, 'a', 'b' p ary # => ["foo", "bar", "a", "b", "baz"]
join([sep])
配列の要素を文字列 sep を間に挟んで連結した文字列を返します。
文字列でない配列要素に対しては to_s
した結果を連結します。配
列要素が配列であれば再帰的に(同じ sep を利用して) join した
文字列を連結します。
sep が省略された場合には変数 $, の値が使われます。
注: 配列要素が自身を含むような無限にネストした配列に対しては、以下 のような結果になります。
ary = [1,2,3] ary.push ary p ary # => [1, 2, 3, [...]] p ary.join # => "123123[...]"
last
配列の末尾の要素を返します。配列が空のときは nil
を返します。
length
size
配列の長さを返します。配列が空のときは 0 を返します。
nitems
nil
でない要素の数を返します。
pack(template)
配列の内容を template で指定された文字列にしたがって、
バイナリとしてパックした文字列を返します。テンプレートは
型指定文字列とその長さ(省略時は1)を並べたものです。長さと
して *
が指定された時は「残りのデータ全て」の長さを
表します。型指定文字はpackテンプレート文字列の通りです。
pop
末尾の要素を取り除いてそれを返します。空配列の時は
nil
を返します。
push, shift, unshift も参照し てください。
例:
array = [1, [2, 3], 4] p array.pop # => 4 p array.pop # => [2, 3] p array # => [1] p array.pop # => 1 p array.pop # => nil p array # => []
push(obj1[, obj2 ...])
obj1, obj2 ... を順番に配列の末尾に追加します。
pop, shift, unshift も参照して ください。
self
を返します。
例:
array = [1, 2, 3] array.push 4 array.push [5, 6] array.push 7, 8 p array # => [1, 2, 3, 4, [5, 6], 7, 8]
rassoc(obj)
self
が配列の配列であると仮定して、要素の配列でインデックス
1 の要素が obj に等しいものを検索し見つかった最初の要素を返
します。比較は ==
演算子を使って行われます。
該当する要素がなければ nil
を返します。
例:
a = [[15,1], [25,2], [35,3]] p a.rassoc(2) # => [25, 2]
Array#assoc も参照してください。
replace(another)
配列の内容を配列 another の内容で置き換えます。
self
を返します。
例:
a = [1, 2, 3] a.replace [4, 5, 6] p a #=> [4, 5, 6]
reverse
reverse!
reverse
は全ての要素を逆順に並べた新しい配列を返します。
reverse!
は配列の要素を逆順に(破壊的に)並べ替えます。
reverse
は、常に新しい配列を返しますが、reverse!
は、
1 要素の配列に対して nil
を返しそれ以外では self
を返
します*40。
reverse_each {|item| ... }
各要素に対して逆順にブロックを評価します。self
を返します。
rindex(val)
val と ==
において等しい最後の要素のインデックスを
返します。等しい要素がひとつもなかった時には nil
を返します。
例:
p [1, 0, 0, 1, 0].rindex(1) #=> 3 p [1, 0, 0, 0, 0].rindex(1) #=> 0 p [0, 0, 0, 0, 0].rindex(1) #=> nil
select(index_1, ... , index_n)
select {|item| ... }
最初の形式では、引数で指定されたインデックスに対応する要素を配列で 返します。インデックスに対応する値がなければ nil が要素になります。 (indexes, indices と同じです)
例:
ary = %w( a b c d e ) p ary.select( 0, 2, 4 ) #=> ["a", "c", "e"] p ary.select( 3, 4, 5, 6, 35 ) #=> ["d", "e", nil, nil, nil] p ary.select( 0, -1, -2 ) #=> ["a", "e", "d"] p ary.select( -4, -5, -6, -35 ) #=> ["b", "a", nil, nil]
ブロック付きでイテレータとして呼び出した場合は Enumerable#select と同じです。つまり、ブロッ クに要素を順に渡し、ブロックが真を返した要素の配列を返します。
ary = %w(a b c d e) p ary.select {|v| v > "b"} # => ["c", "d", "e"]
shift
配列の先頭の要素を取り除いてそれを返します。残りの要素はひとつずつ
前に詰められます。空配列に対してはnil
を返します。
slice(pos[, len])
slice(start..last)
self[] と同じです。
slice!(pos[, len])
slice!(start..last)
指定した要素を取り除いて返します。取り除く要素がなければ nil
を返します。
sort
sort!
sort {|a, b| ... }
sort! {|a, b| ... }
配列の内容をソートします。ブロックとともに呼び出された時には
ブロックに 2 引数を与えて評価し、その結果で比較します。
ブロックがない時には <=>
演算子を使って比較します。
sort
はソートされた新しい配列を返し、sort!
は
self
を破壊的に変更します。
ruby 1.7 feature:
sort!
は、バージョン 1.6 以前には要素の数が 2 より小さい場合には
nil
を返していました。一方バージョン 1.7 では常に self
を
返します。
to_a
to_ary
self
をそのまま返します。
to_s
uniq
uniq!
uniq
は配列から重複した要素を取り除いた新しい配列を返します。
取り除かれた要素の部分は前に詰められます。uniq!
は削除を破壊
的に行い、削除が行われた場合は self
を、そうでなければ
nil
を返します。
要素の重複判定は、Object#eql? により行われます。
例:
p [1, 1, 1].uniq #=> [1] p [1, 4, 1].uniq #=> [1, 4] p [1, 3, 2, 2, 3].uniq #=> [1, 3, 2]
unshift(obj)
obj を配列の先頭に挿入します。self
を返します。
例:
arr = [1,2,3] arr.unshift 0 p arr #=> [0, 1, 2, 3] arr.unshift [0] p arr #=> [[0], 0, 1, 2, 3]
ハッシュテーブル(連想配列とも呼ぶ)のクラス。ハッシュは任意の種類のオブ ジェクトから任意の種類のオブジェクトへの関連づけを行うことができます。 ハッシュ生成は以下のようなハッシュ式で行われます。
{a=>b, ... }
ハッシュの格納に用いられるハッシュ値の計算には、 Object#hash メソッドが使われ、キーの同一性判定には、 Object#eql? メソッドが使われます。
キーとして与えたオブジェクトの内容が変化し、メソッド hash
の返す
値が変わるとハッシュから値が取り出せなくなりますから、Array、
Hash などのインスタンスはキーに向きません。文字列をキーとして与
えると、文字列をコピーし、コピーを更新不可に設定(freeze)してキーとして
使用します。キーとして使われている文字列を更新しようとすると例外
TypeError が発生します。
Hash[key, value ...]
新しいハッシュを生成します。引数は必ず偶数個指定しなければな りません(奇数番目がキー、偶数番目が値)。
Hash.new([ifnone])
Hash.new {|hash, key| ...} ((<ruby 1.7 feature>))
空の新しいハッシュを生成します。ifnone はキーに対 応する値が存在しない時のデフォルト値です。 デフォルト値の扱いには注意が必要です( trap::Hash )。
ruby 1.7 feature: ブロックを指定した場合は、ブロックの評価結果がデフォルト値になりま す。値が設定されていないハッシュ要素を参照するとその都度ブロックを 実行し、その結果を返します。ブロックにはそのハッシュとハッシュを参 照したときのキーが渡されます。
# ブロックではない場合デフォルト値の変更により # 他の値も変更されたように見える h = Hash.new("foo") p h[1] # => "foo" p h[1] << "foo" # => "foobar" p h[1] # => "foobar" p h[2] # => "foobar" # ブロックを使うとうまく行く h = Hash.new {|hash, key| hash[key] = "foo"} p h[1] # => "foo" p h[1] << "bar" # => "foobar" p h[1] # => "foobar" p h[2] # => "foo" # 値が設定されたないときに(fetchのように)例外をあげるようにもできる h = Hash.new {|hash, key| raise(IndexError, "hash[#{key}] has no value") } h[1] # => hash[1] has no value (IndexError)
self[key]
key に関連づけられた値を返します。該当するキーが登
録されていない時には、デフォルト値(設定されていない時には
nil
) を返します。
値としての nil
と区別する必要がある場合は fetch
を使ってください。
self[key]=value
store(key,value)
key に対して value を関連づけます。value を返し ます。
clear
ハッシュの中身を空にします。self
を返します。
clone
dup
レシーバと同じ内容を持つ新しいハッシュを返します。フリーズしたハッ
シュの clone
は同様にフリーズされたハッシュを返しますが、
dup
は内容の等しいフリーズされていないハッシュを返します。
default
default(key) ((<ruby 1.7 feature>))
ハッシュのデフォルト値を返します。
ruby 1.7 feature:
2 番目の形式はハッシュがデフォルト値としてブロックを持つ場合
(Hash.new参照)に指定できます。self
と 引数
key を引数にブロックを実行してその結果を返します。
default=value
ハッシュのデフォルト値を value に設定します。対応する値が存 在しないキーで検索した時にはこの値を返します。
value を返します。
delete(key)
delete(key) {|key| ... }
key に対する関連を取り除きます。取り除かれた値を返しますが、
key に対応する値が存在しない時には nil
を返します。
ブロックが与えられた時には key にマッチするものがな かった時に評価し、その結果を返します。
reject {|key, value| ... }
self
を複製して、ブロックを評価した値が真になる要
素を削除したハッシュを返します。
ハッシュを返すことを除けば Enumerable#reject と同じです。
delete_if {|key, value| ... }
reject! {|key, value| ... }
key と value を引数としてブロックを評価した値が真であ
る時、その要素を self
から削除します。self
を返します。
reject! は、要素を削除しなければ nil
を返します。
each {|key, value| ... }
each_pair {|key, value| ... }
key と value を引数としてブロックを評価します。
self
を返します。
each_key {|key| ... }
key を引数としてブロックを評価します。
self
を返します。
each_value {|value| ... }
valueを引数としてブロックを評価します。
self
を返します。
empty?
ハッシュが空の時真を返します。
fetch(key[, default])
fetch(key) {|key| ... }
key に関連づけられた値を返します。該当するキーが登録されてい ない時には、引数 default が与えられていればその値を、ブロッ クが与えられていればそのブロックを評価した値を返します。そのいずれ でもなければ例外 IndexError が発生します。
has_key?(key)
include?(key)
key?(key)
member?(key)
ハッシュが key をキーとして持つ時真を返します。
has_value?(value)
value?(value)
ハッシュが value を値として持つ時真を返します。
値の一致判定は ==
で行われます。
index(val)
val に対応するキーを返します。対応する要素が存在しない時には
nil
を返します。
該当するキーが複数存在する場合、どのキーを返すかは不定です。
indexes(key_1, ... , key_n)
indices(key_1, ... , key_n)
引数で指定されたキーを持つ値の配列を返します。
ruby 1.7 feature: このメソッドは version 1.7 では、obsolete です。 使用すると警告メッセージが表示されます。 代わりに Hash#select を使用します。
invert
値からキーへのハッシュを返します。 異なるキーに対して等しい値が登録されている場合の結果は不定であることに 注意してください、そのような場合にこのメソッドを利用することは意図され ていません。
h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 } h.invert #=> {200=>"d", 300=>"y", 0=>"a", 100=>"n"}
keys
全キーの配列を返します。
length
size
ハッシュの要素の数を返します。
rehash
キーのハッシュ値を再計算します。キーになっているオブジェクトのハッシュ 値が変わってしまった場合、このメソッドを使ってハッシュ値を再計算しない 限り、そのキーに対応する値を取り出すことができなくなります。
replace(other)
ハッシュの内容を other の内容で置き換えます。
self
を返します。
select(key_1, ... , key_n)
select {|key, value| ... }
ruby 1.7 feature: 最初の形式では、引数で指定されたキーを持つ値の配列を返します。 キーに対応する値がなければ default の戻り値が使用 されます。 indexes と indices と同じです。
h = {1=>"a", 2=>"b", 3=>"c"} p h.select(1,3,4) => ["a", "c", nil]
ブロック付きでイテレータとして呼び出した場合は Enumerable#select と同じです。つまり、ブロッ クにキーと値の組を順に渡し、ブロックが真を返した要素(キーと値の配 列)の配列を返します。
h = {1=>"a", 2=>"b", 3=>"c"} p h.select {|k,v| k % 2 == 1} => [[1, "a"], [3, "c"]]
shift
ハッシュから要素をひとつ取り除き、[key,value]
という配列とし
て返します。
to_a
[key,value]
からなる 2 要素の配列の配列を生成して返します。
to_hash
self
を返します。
update(other)
update(other) {|key, self_val, other_val| ... } ((<ruby 1.7 feature>))
ハッシュの内容をマージします。重複するキーに対応する値は other の内容で上書きされます。
ruby 1.7 feature:
ブロックが与えられた場合は、重複するキーごとにブロックを評価してそ
の結果をそのキーに対応する値にします。ブロックには引数としてキーと
self[key]
、other[key]
が渡されます。
foo = {1 => 'a', 2 => 'b', 3 => 'c'} bar = {1 => 'A', 2 => 'B', 3 => 'C'} p foo.dup.update(bar) # => {1=>"A", 2=>"B", 3=>"C"} p foo.dup.update(bar) {|k,v| v} # => {1=>"a", 2=>"b", 3=>"c"}
self
を返します。
values
ハッシュの全値の配列を返します。
シンボルを表すクラス。シンボルは任意の文字列と一対一に対応するオブジェ クトです。Ruby スクリプトからは
:symbol
'symbol'.intern
のようにして得られます。リテラルでシンボルを表す場合、`:
' の後に
は識別子、メソッド名(`!
',`?
' などの接尾辞を含む)、変数名
(`$
'などの接頭辞を含む)、再定義できる演算子のいずれかに適合する
ものしか書くことはできません(そうでなければ文法エラーになります)。
Symbol.all_symbols
定義済みの全てのシンボルオブジェクトの配列を返します。
p Symbol.all_symbols # => [:RUBY_PLATFORM, :RUBY_VERSION, ...]
シンボルの生成はコンパイル時に行われるので以下のようにしても結果に 差はありません。
a = Symbol.all_symbols :foo b = Symbol.all_symbols p b - a # => []
intern
ruby 1.7 feature:
self
を返します。
id2name()
to_s
シンボルに対応する文字列を返します。
逆に、文字列に対応するシンボルを得るには String#intern を使います。
p :foo.id2name.intern == :foo => true
to_i
シンボルに対応する整数を返します。
逆にこの整数から対応するシンボルを得るには Fixnum#id2name を使って一旦文字列を得る必要が あります。
id = :foo.to_i p id # => 8881 p id.id2name.intern # => :foo
Rubyの実装では予約語、変数名、メソッド名などをこの整数で管理してい ます。オブジェクトに対応する整数(Object#id で得ら れます)と Symbol に対応する整数は別のものです。
例:
1+2*3/4
プログラミングの利便のために一部のメソッド呼び出しと制御構造は演算子形 式をとります。Rubyには以下にあげる演算子があります。
高い :: [] ** -(単項) +(単項) ! ~ * / % + - << >> & | ^ > >= < <= <=> == === != =~ !~ && || .. ... ?:(条件演算子) =(+=, -= ... ) not 低い and or
左の「高い」「低い」は演算子の優先順位です。 例えば「&&」は「||」より優先順位が高いので、以下のように 解釈されます。
a && b || c #=> (a && b) || c a || b && c #=> a || (b && c)
ほとんどの演算子は特別な形式のメソッド呼び出しですが、一部の ものは言語に組み込みで、再定義できません。
再定義できる演算子(メソッド):
+@
, -@
は単項演算子 +
, -
を表しメソッド定義
などではこの記法を利用します。
| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= `
再定義できない演算子(制御構造):
演算子の組合せである自己代入演算子と !=
, !~
も再定義できません。
= ?: .. ... ! not && and || or ::
例:
foo = bar foo[0] = bar foo.bar = baz
文法:
変数 '=' 式 定数 '=' 式 式`['expr..`]' '=' 式 式`.'識別子 '=' 式
代入式は変数などに値を設定するために用いられます。代入はロー カル変数や定数の宣言としても用いられます。代入式の左辺は以 下のいずれかでなければなりません。
変数
変数 `=' 式
左辺値が変数の場合、式を評価した値が変数に代入されます。
配列参照
式1`[' 式2 ... `]' `=' 式n
式1を評価して得られるオブジェクトに対しての、式 2 から式 n までを
引数とする []=
メソッド呼出しに変換されます。
例:
class C def initialize @ary = [0,1,2,3,4,5,6,7] end def [](i) @ary[i * 2] end def []=( i, v ) @ary[i * 2] = v end end c = C.new p c[3] # c.[]( 3 ) に変換され、その結果は 6 p c[3] = 1 # c.[]=(3,1) に変換され、その結果は 1
属性参照
式1 `.' 識別子 `=' 式2
式 1 を評価して得られるオブジェクトに対して、
識別子=
というメソッドを、式 2 を引数にして呼び出します。
例:
class C def foo @foo end def foo=( v ) @foo = v end end c = C.new c.foo = 5 # c.foo=( 5 ) のように変換される p c.foo # => 5
属性は attr を使って同じように定義できます。
例:
class C attr :foo, true end c = C.new c.foo = 5 # c.foo=( 5 ) のように変換される p c.foo # => 5
例:
foo += 12 # foo = foo + 12 a ||= 1 # a が偽か未定義ならば1を代入。初期化時のイディオムの一種。
文法:
式1 op= 式2 # 式1は通常の代入の左辺のいずれか
op は以下のいずれかです。演算子と=
の間にスペースを
空けてはいけません。
+, -, *, /, %, **, &, |, ^, <<, >>, &&, ||
この形式の代入は 式1 = 式1 op 式2
と同様に評価されます。
ただし、式1は一度しか評価されません。*42
例:
foo, bar, baz = 1, 2, 3 foo, = list() foo, *rest = list2()
文法:
式 [`,' [式 `,' ... ] [`*' [式]]] = 式 [, 式 ... ][`*' 式] `*' [式] = 式 [, 式 ... ][`*' 式]
多重代入は複数の式または配列から同時に代入を行います。左辺の
各式はそれぞれ代入可能でなければなりません。右辺の式が一つし
か与えられなかった場合、式を評価した値は配列に変換されて、各
要素が左辺のそれぞれの式に代入されます。左辺の要素の数よりも
配列の要素の数の方が多い場合には、余った要素は無視されます。
配列の要素が足りない場合には対応する要素の無い左辺には
nil
が代入されます。
左辺の最後の式の直前に *
がついていると、対応する
左辺のない余った要素が配列として代入されます。余った要素が
無い時には空の配列が代入されます。
例:
foo, bar = [1, 2] # foo = 1; bar = 2 foo, bar = 1, 2 # foo = 1; bar = 2 foo, bar = 1 # foo = 1; bar = nil foo, bar, baz = 1, 2 # foo = 1; bar = 2; baz = nil foo, bar = 1, 2, 3 # foo = 1; bar = 2 foo = 1, 2, 3 # foo = [1, 2, 3] *foo = 1, 2, 3 # foo = [1, 2, 3] foo,*bar = 1, 2, 3 # foo = 1; bar = [2, 3]
多重代入は括弧により、ネストした配列の要素を代入することもできます。
(foo, bar), baz = [1, 2], 3 # foo = 1; bar = 2; baz = 3
特殊な形式の代入式も多重代入にすることができます。
class C def foo=( v ) @foo = v end def []=(i,v) @bar = ["a", "b", "c"] @bar[i] = v end end obj = C.new obj.foo, obj[2] = 1, 2 # @foo = 1; @bar = ["a", "b", 2]
左辺が `,
' で終る場合や、`*
' の直後の式を省略した場合にも
余った要素は無視されます。
例:
foo,* = 1, 2, 3 # foo = 1 foo, = 1, 2, 3 # foo = 1 * = 1, 2, 3
特に最後の単体の `*
' はメソッド呼出しにおいて引数を完全に無視
したいときに使用できます。(メソッド呼出しの引数の受け渡しは
多重代入とほぼ同じルールが適用されます)
例:
def foo(*) end foo(1,2,3)
多重代入の値は配列に変換された右辺です。
例:
1 .. 20 /first/ ... /second/
文法:
式1 `..' 式2 式1 ` ... ' 式2
条件式以外の場所では式1から式2までの範囲オブジェクトを返しま
す。範囲オブジェクトはRangeクラス
のインスタンスです。 ...
で生成された範囲オブジェクトは
終端を含みません。
条件式として範囲指定式が用いられた場合には、式1が真になるま
では偽を返し、その後は式2が真を返すまでは真を返します。式2が
真になれば状態は偽に戻ります。..
は式1が真になっ
た時にすぐに式2を評価し(awkのように)、 ...
は次の
評価まで式2を評価しません(sedのように)。
例:
test && set test and set
文法:
式 `&&' 式 式 `and' 式
まず、左辺を評価して、結果が真であった場合には右辺も評価しま
す。and
は同じ働きをする優先順位の低い演算子です。
例:
demo || die demo or die
文法:
式 `||' 式 式 or 式
まず左辺を評価して、結果が偽であった場合には右辺も評価します。
or
は同じ働きをする優先順位の低い演算子です。
例:
! me not me i != you
文法:
`!' 式 not 式
式の値が真である時偽を、偽である時真を返します。
式 `!=' 式
!(式 == 式)
と同じ。
式 `!~' 式
!(式 =~ 式)
と同じ。
例:
obj == 1 ? foo : bar
文法:
式1 ? 式2 : 式3
式1の結果によって式2または式3を返します。
if 式1 then 式2 else 式3 end
とまったく同じです。
モジュールのクラス。
Module.constants
このメソッドを呼び出した時点で参照可能な定数名の配列を返します。
class Foo FOO = 1 end p Module.constants # 出力中に FOO は現われない => ["RUBY_PLATFORM", "STDIN", ..., "Foo", ... ]
Module#constants や、 local_variables, global_variables, Object#instance_variables, Module#class_variables も参照してください。
Module.nesting
このメソッドを呼び出した時点でのクラス/モジュールのネスト情 報を配列に入れて返します。
module Foo module Bar module Baz p Module.nesting end end end # => [Foo::Bar::Baz, Foo::Bar, Foo]
Module.new
Module.new {|mod| ... } ((<ruby 1.7 feature>))
新しく名前の付いていないモジュールを生成して返します。
名前のないモジュールは、最初に名前を求める際に代入されている定数名 を検索し、見つかった定数名をモジュール名とします。
p foo = Module.new # => #<Module 0lx40198a54> p foo.name # => "" Foo = foo # ここで p foo すれば "Foo" 固定 Bar = foo p foo.name # => "Bar" ("Foo" になるか "Bar" になるかは不定)
ruby 1.7 feature: ブロックが与えられると生成したモジュールをブロックの引数に渡し、モ ジュールのコンテキストでブロックを実行します。この場合も生成したモ ジュールを返します。
mod = Module.new mod.module_eval {|m| ... } mod
と同じです。ブロックの実行は Module#initialize が行います。
self <=> other
self
と other
を比較して、
self
が other
の子孫であるとき -1、
同一のクラス/モジュールのとき 0、
self
が other
の先祖であるとき 1
を返します。
親子関係にないクラス同士の比較ではその動作は不定です *44
module Foo end class Bar include Foo end class Baz < Bar end class Qux end p Bar <=> Foo # => -1 p Baz <=> Bar # => -1 p Baz <=> Foo # => -1 p Baz <=> Qux # => 1 (version 1.7 では ArgumentError) p Qux <=> Baz # => 1 (version 1.7 では ArgumentError)
self < other
self <= other
self > other
self >= other
比較演算子。self
が other の子孫である時、
self < other
が成立します。
親子関係にないクラス同士の比較ではいずれの関係も false を返します。
module Foo end class Bar include Foo end class Baz < Bar end class Qux end p Bar < Foo # => true p Baz < Bar # => true p Baz < Foo # => true p Baz < Qux # => false p Baz > Qux # => false
self === obj
このメソッドは主に case 文での比較に用いられます。
obj が self
と Object#kind_of?
の関係がある時、真になります。つまり、case ではクラ
ス、モジュールの所属関係をチェックすることになります。
str = String.new case str when String # String === str を評価する p true # => true end
ancestors
クラス、モジュールのスーパークラスとインクルードしているモジュール を優先順位順に配列に格納して返します。
module Foo end class Bar include Foo end class Baz < Bar p ancestors p included_modules p superclass end # => [Baz, Bar, Foo, Object, Kernel] # => [Foo, Kernel] # => Bar
class_eval(src[,fname[,lineno]])
class_eval { ... }
Module#module_eval の別名。
class_variables
クラス/モジュールに定義されているクラス変数の配 列を返します。スーパークラスやインクルードしているモジュールのクラ ス変数も含みます。
local_variables, global_variables, Object#instance_variables, Module.constants, Module#constants も参照してください。
const_defined?(name)
モジュールに name で指定される名前の定数が定義されている時真 を返します。name は Symbol か文字列で指定します。
const_get(name)
モジュールに定義されている name で指定される名前の定数の値を 取り出します。定数が定義されていない時には例外 NameError が 発生します。 name は Symbol か文字列で指定します。
const_set(name, value)
モジュールに name で指定された名前の定数を value とい う値として定義します。そのモジュールにおいてすでにその名前の定数が 定義されている場合、警告メッセージが出力されます。 name は Symbol か文字列で指定します。
constants
そのモジュール(またはクラス)で定義されている定数名の配列を返 します。 スーパークラスやインクルードしているモジュールの定数も含みます。
Module.constants や local_variables, global_variables, Object#instance_variables, Module#class_variables も参照してください。
例: Module.constnats と Module#constnats の違い
# 出力の簡略化のため起動時の定数一覧を取得して後で差し引く $clist = Module.constants class Foo FOO = 1 end class Bar BAR = 1 # 出力に FOO は含まれない p constants - $clist # => ["BAR", "Bar", "Foo"] # Module.constants も同様 p Module.constants - $clist # => ["BAR", "Bar", "Foo"] class Baz p constants - $clist # => ["Bar", "Foo"] # ネストしたクラスでは、外側のクラスで定義した定数は # 参照可能なので、BAR は、Module.constants には含まれる # (クラス Baz も Bar の定数なので同様) p Module.constants - $clist # => ["BAR", "Baz", "Bar", "Foo"] end end
include?(mod) ((<ruby 1.7 feature>))
self
が モジュール mod をインクルードしていれば
真を返します。
Foo = Module.new class Bar include Foo end class Baz < Bar end p Bar.include? Foo #=> true p Baz.include? Foo #=> true
included_modules
インクルードされているモジュールの配列を返します。 Module#ancestors の例も参照してください
instance_method(name)
self
のインスタンスメソッドをオブジェクト化した
UnboundMethod を返します。name は Symbol か文字
列です。
Object#method も参照してください。
method_defined?(name)
モジュールにインスタンスメソッド name が定義されているとき真 を返します。name は Symbol か文字列です。
module_eval(expr, [fname, [lineno=1]])
module_eval {|mod| .... }
モジュールのコンテキストで文字列 expr を評価してその結果を返 します。 fname、lineno が与えられた場合は、ファイル fname、 行番号 lineno にその文字列があるかのようにコンパイルされ、ス タックトレース表示などのファイル名/行番号を差し替えることができま す。
ブロックが与えられた場合にはそのブロックをモジュールのコンテキスト
で評価してその結果を返します。ブロックの引数 mod には
self
が渡されます。
モジュールのコンテキストで評価するとは、実行中そのモジュールが
self
になるということです。つまり、そのモジュールの定義文の
中にあるかのように実行されます。
*45
*46
ただし、ローカル変数だけは module_eval
の外側のスコープと共
有します。
name
クラス、モジュールの名前を返します。名前のないクラス、モジュール については空文字列を返します(Module.new の例を参照)。
public_instance_methods([inherited_too])
instance_methods([inherited_too])
そのモジュールで定義されているメソッド名の一覧を配列で返します。
inherited_too が真であれば(デフォルトは偽)、スーパー クラスのメソッドも探索します。
Object#methods, Object#public_methods, も参照してください。
private_instance_methods([inherited_too])
そのモジュールで定義されている private メソッド名の一覧を配列で返 します。
inherited_too が真であれば(デフォルトは偽)、スーパー クラスのメソッドも探索します。
Object#private_methods, も参照してください。
protected_instance_methods([inherited_too])
そのモジュールで定義されている protected メソッド名の一覧を配列で 返します。
inherited_too が真であれば(デフォルトは偽)、スーパー クラスのメソッドも探索します。
Object#protected_methods, も参照してください。
private_class_method(name, ... )
public_class_method(name, ... )
name で指定したクラスメソッド(クラスの特異メソッド) の可視性 を変更します。
self
を返します。
alias_method(new, old)
メソッドの別名を定義します。 alias との違いは以下の通りです。
alias
は構文なのでメソッドの中では使えないself
を返します。
append_features(module_or_class)
モジュール(あるいはクラス)に self
の機能を追加します。
このメソッドは Module#include
の実体であり、include
を
Ruby で書くと以下のように定義できます。
*47
def include(*modules) modules.each {|mod| # append_features はプライベートメソッドなので # 直接 mod.append_features(self) とは書けない mod.__send__ :append_features, self # 1.7 以降は以下の行も実行される # mod.__send__ :included, self } end
self
を返します。
attr(name[, assignable])
属性読み込みのためのインスタンスメソッド name を定義します。
name は Symbol か文字列で指定します。返り値は常に
nil
です。
このメソッドで定義されるアクセスメソッドの定義は次の通りです。
def name @name end
省略可能な第 2 引数 assignable が指定されその値が真である
場合には、属性の書きこみ用メソッド name=
も同時に定義されます。
その定義は次の通りです。
def name=(val) @name = val end
attr_accessor(name, ... )
属性 name に対する読み込みメソッドと書きこみメソッドの両方を
定義します。name は Symbol か文字列で指定します。返り値
は常に nil
です。
このメソッドで定義されるメソッドの定義は以下の通りです。
def name @name end def name=(val) @name = val end
attr_reader(name, ... )
属性 name の読み出しメソッドを定義します。
name は Symbol か文字列で指定します。
返り値は常に nil
です。
このメソッドで定義されるメソッドの定義は以下の通りです。
def name @name end
attr_writer(name, ... )
属性 name への書き込みメソッド (name=
) を定義します。
name は Symbol か文字列で指定します。返り値は常に
nil
です。
このメソッドで定義されるメソッドの定義は以下の通りです。
def name=(val) @name = val end
define_method(name, method)
define_method(name) { ... }
インスタンスメソッド name を定義します。 method には Proc、Method あるいは UnboundMethod のいずれかのインスタンスを指定します。 引数 method を与えたときはそれを、ブロック付きで 呼びだしたときはブロックを Proc 化したオブジェクトを、 それぞれ返します。
例:
class Foo def foo() p :foo end define_method(:bar, instance_method(:foo)) end Foo.new.bar # => :foo
ブロックを与えた場合、Ruby 1.7 以降では、定義したメソッド の実行時にブロックがレシーバクラスのインスタンスの上で instance_eval されます。 一方 Ruby 1.6 ではブロックとメソッドの関連づけを行うだけで、 メソッドの実行時にはブロックは生成時のコンテキストのままで 実行されます。たとえば以下の例を参照してください。
class C end # インスタンスメソッド print_self を定義。 # ただし define_method はプライベートメソッド # なので直接は呼べない。__send__ を介して呼ぶ。 C.__send__(:define_method, :print_self) { p self } # 1.6 の場合 C.new.print_self #=> main # 1.7 の場合 C.new.print_self #=> #<C:0x4015b490>
extend_object(object)
Object#extend の実体です。オブジェクトに
モジュールの機能を追加します。Object#extend
は、Ruby で
書くと以下のように定義できます。
def extend(*modules) modules.each {|mod| mod.__send__ :extend_object, self } end
extend_object のデフォルトの実装では、self
に定義されて
いるメソッドを object の特異メソッドとして追加します。
*48
object を返します*49。
include(module ... )
指定されたモジュールの性質(メソッドや定数、クラス変数)を追加します。
self
を返します。
include
は多重継承の代わりに用いられる Mix-in を実現するため
に使われます。
class C include FileTest include Math end p C.ancestors # => [C, Math, FileTest, Object, Kernel]
モジュールの機能追加は、クラスの継承関係の間にそのモジュールが挿入 されることで実現されています。従って、メソッドの探索などはスーパー クラスに優先されて追加したモジュールから探索されます(上の例の ancestors の結果がメソッド探索の順序です)。
同じモジュールを二回以上 include すると二回目以降は無視されます。
module Foo; end class Bar; include Foo; end class Baz < Bar; include Foo; end # <- この include は無効 p Baz.ancestors # => [Baz, Bar, Foo, Object, Kernel]
モジュールの継承関係が循環してしまうような include を行うと、例外 ArgumentError が発生します。
module Foo; end module Bar; include Foo; end module Foo; include Bar; end => -:3:in `append_features': cyclic include detected (ArgumentError) from -:3:in `include' from -:3
included(class_or_module) ((<ruby 1.7 feature>))
self
が include
されたときに対象のクラスまたはモジュー
ルを引数にインタプリタから呼び出されます。
module Foo def self.included(mod) p "#{mod} include #{self}" end end class Bar include Foo end # => "Bar include Foo"
method_added(name)
メソッド name が追加された時にインタプリタから呼び出されます。 name には追加されたメソッドの名前が Symbol で渡されます。
class Foo def Foo.method_added(name) puts "method \"#{name}\" was added" end def foo end define_method :bar, instance_method(:foo) end => method "foo" was added method "bar" was added
特異メソッドの追加に対するフックには Object#singleton_method_added を使います。
method_removed(name) ((<ruby 1.7 feature>))
メソッドが Module#remove_method により削 除された時にインタプリタから呼び出されます。 name には削除されたメソッド名が Symbol で渡されます。
class Foo def Foo.method_removed(name) puts "method \"#{name}\" was removed" end def foo end remove_method :foo end => method "foo" was removed
特異メソッドの削除に対するフックには Object#singleton_method_removed を使います。
method_undefined(name) ((<ruby 1.7 feature>))
メソッドが Module#undef_method または undefにより未定義にされた時にインタプリタ から呼び出されます。 name には未定義にされたメソッド名が Symbol で渡されます。
class Foo def Foo.method_undefined(name) puts "method \"#{name}\" was undefined" end def foo end def bar end undef_method :foo undef bar end => method "foo" was undefined method "bar" was undefined
特異メソッドの未定義に対するフックには Object#singleton_method_undefined を使います。
module_function(name ... )
name で指定されたメソッドをモジュール関数に します。
モジュール関数とはプライベートメソッドであると同時にモジュール(ま たはクラス)の特異メソッドでもあるようなメソッドです。例えば Math モジュールで定義されているメソッドがモジュール関数です。
モジュール関数を alias する場合は
module Foo def foo p "foo" end module_function :foo alias :bar :foo end Foo.foo # => "foo" Foo.bar # => undefined method `bar' for Foo:Module (NoMethodError)
としても、プライベートメソッド foo の別名ができるだけで、Foo の特 異メソッド Foo.foo の別名は定義されません。このようなことをしたい場合 は、先に別名を定義してからそれぞれをモジュール関数として定義するの が簡単です。
module Foo def foo p "foo" end alias :bar :foo module_function :foo, :bar end Foo.foo # => "foo" Foo.bar # => "foo"
self
を返します。
private([name ... ])
引数なしのときは今後このクラスまたはモジュール定義内で新規に定義さ れるメソッドを関数形式でだけ呼び出せるように(private)設定します。
引数が与えられた時には引数によって指定されたメソッドを private に 設定します。
例:
class Foo def foo1() 1 end # デフォルトでは public private # 可視性を private に変更 def foo2() 2 end # foo2 は private メソッド end foo = Foo.new p foo.foo1 # => 1 p foo.foo2 # => private method `foo2' called for #<Foo:0x401b7628> (NoMethodError)
self
を返します。
protected([name ... ])
引数なしのときは今後このクラスまたはモジュール定義内で新規に定義さ れるメソッドを protected に設定します。protected とはそのメソッド が定義されているクラスまたはそのサブクラスからしか呼び出すことがで きないという意味です。
引数が与えられた時には引数によって指定されたメソッドを protected に設定します。
self
を返します。
public([name ... ])
引数なしのときは今後このクラスまたはモジュール定義内で新規に定義さ れるメソッドをどんな形式でも呼び出せるように(public)設定します。
引数が与えられた時には引数によって指定されたメソッドを public に設 定します。
例:
def foo() 1 end p foo # => 1 # the toplevel default is private p self.foo # => private method `foo' called for #<Object:0x401c83b0> (NoMethodError) def bar() 2 end public :bar # visibility changed (all access allowed) p bar # => 2 p self.bar # => 2
self
を返します。
remove_class_variable(name)
name で指定したクラス変数を取り除きます。もし指定したクラス 変数がそのモジュール(またはクラス)で定義されていない時、 例外 NameError が発生します。
class Foo @@foo = 1 remove_class_variable(:@@foo) # => 1 p @@foo # => uninitialized class variable @@foo in Foo (NameError) end
Module#remove_const, Object#remove_instance_variable も参照してください。
取り除いたクラス変数に設定されていた値を返します。
remove_const(name)
name で指定した定数を取り除きます。指定したメソッドが数がそ のモジュール(またはクラス)で定義されていない場合は例外 NameError が発生します。
class Foo FOO = 1 p remove_const(:FOO) # => 1 p FOO # => uninitialized constant FOO at Foo (NameError) end
Module#remove_class_variable, Object#remove_instance_variable も参照してください。
取り除いた定数に設定されていた値を返します。
remove_method(name)
name で指定したインスタンスメソッドをモジュールから取り除き ます。もし指定したメソッドが定義されていないときには例外 NameError が発生します。
class Foo def foo() end remove_method(:foo) end
self
を返します。
undef_method の例も参照してください。
undef_method(name)
インスタンスに対して name というメソッドを呼び出すことを禁止 します。もし指定したメソッドが定義されていないときには例外 NameError が発生します。
undef との違いは、メソッド名を文字列または Symbol で与える、メソッド内でも使用できる、の二点です。
また remove_method とはスーパークラスの定義が継承され るかどうかで区別されます。以下の挙動を参照してください。
class A def ok() puts 'A' end end class B < A def ok() puts 'B' end end B.new.ok # => B # undef_method の場合はスーパークラスに同名のメソッドがあっても # その呼び出しはエラーになる class B undef_method :ok end B.new.ok # => NameError # remove_method の場合はスーパークラスに同名のメソッドがあると # それが呼ばれる class B remove_method :ok end B.new.ok # => A
self
を返します。
範囲オブジェクトのクラス。範囲オブジェクトは範囲演算子 ..
または
...
によって生成されます。..
演算子によって生成された範囲
オブジェクトは終端を含み、...
演算子によって生成された範囲オブジェ
クトは終端を含みません。
例:
for i in 1..5 ... end
これは 1 から 5 までの範囲オブジェクトを生成して、それぞれの値に対して 繰り返すと言う意味です。
範囲演算子のオペランドは互いに <=>
で比較できる必要があります。
さらに Range#each を実行するためには succ
メソッ
ドを実行できるものでなければいけません。
*50
Range.new(first,last[, exclude_end])
first から last までの範囲オブジェクトを生成して返しま す。exclude_end は終端を含むかどうかを指定します。省略時には 終端を含みます。
生成時に、引数の正当性チェックとして
first <=> last
を実行する。これが例外を返す場合、例外 ArgumentError を発生 させる。(ruby 1.7 feature: version 1.7 ではさらに first.succ を実行して例外が発生しないか確認する)
self === other
このメソッドは主に case 文での比較に用いられます。 other が範囲内に含まれている時に真を返します。
begin
first
最初の要素を返します。
each {|item| ... }
範囲内の要素に対して繰り返します。
end
last
終端を返します。範囲オブジェクトが終端を含むかどうかは関係ありませ ん。
p (1..5).end # => 5 p (1...5).end # => 5
exclude_end?
範囲オブジェクトが終端を含まないとき真を返します。
length
size
範囲の長さ(last - first + (exclude_end? ? 0 : 1))を返します。 *51
step(s) {|item| ... }
範囲内の要素を s おきに繰り返します。 *52
("a" .. "f").step(2) {|v| p v} # => "a" "c" "e"
to_ary
to_a と同じです。範囲内の個々の値を要素とする配列 を返します。多重代入などで暗黙の型変換(配列化)が起こります。
a,b,c = (1..3) p [a,b,c] #=> [1, 2, 3]
Rubyでは(Cなどとは異なり)制御構造は式であって、何らかの値を 持ちます。 *53 *54 RubyはC言語やPerlから引き継いだ制御構造を持ちますが、 その他にイテレータというループ抽象化の機 能があります。イテレータは繰り返しを始めとする制御構造をユー ザが定義する事が出来るものです.
例:
if age >= 12 then print "adult fee\n" else print "child fee\n" end gender = if foo.gender == "male" then "male" else "female" end
文法:
if 式 [then] 式 ... [elsif 式 [then] 式 ... ] ... [else 式 ... ] end
条件式を評価した結果が真である時、then
以下の式を実行します。
if
の条件式が偽であれば elsif
の条件を評価します。
elsif
節は複数指定できます。全ての if
および elsif
の条件式が偽であったときは else
節があればその式が実行されます。
if
式は、条件が成立した節(あるいは else
節)の最後に実行し
た式の結果を返します。else
節がなくいずれの条件も成り立たなけれ
ば nil
を返します。
Ruby では false
または nil
だけが偽で、それ以外は 0 や空文
字列も含め全て真です。
Ruby では if を繋げるのは elsif
であり、else if
(C のように)でも elif
(sh のように)でもないことに注意してください。
また if
の条件式が正規表現のリテラルである時には
$_ =~ リテラル
であるかのように評価されます。
例:
print "debug\n" if $DEBUG
文法:
式 if 式
右辺の条件が成立する時に、左辺の式を評価してその結果を返します。
条件が成立しなければ nil
を返します。
例:
unless baby? feed_meat else feed_milk end
文法:
unless 式 [then] 式 ... [else 式 ... ] end
unless
は条件実行を行いますが、条件が if
と反対で、条件が偽の時に実行を行います。unless
式に
elsif
を指定することはできません。
例:
print "stop\n" unless valid(passwd)
文法:
式 unless 式
右辺の条件が成立しない時に、左辺の式を評価してその結果を返します。
条件が成立しなければ nil
を返します。
例:
case $age when 0 .. 2 "baby" when 3 .. 6 "little child" when 7 .. 12 "child" when 13 .. 18 "youth" else "adult" end
文法:
case [式] [when 式 [, 式] ... [then] 式..].. [else 式..] end
case
は一つの式に対する一致判定による分岐を行います。when
節で指定された値と最初の式を評価した結果とを演算子 ===
を用いて
比較して、一致する場合には when
節の本体を実行します。
つまり、
case 式0 when 式1, 式2 stmt1 when 式3, 式4 stmt2 else stmt3 end
は以下の if
式とほぼ等価です。
_tmp = 式0 if 式1 === _tmp || 式2 === _tmp stmt1 elsif 式3 === _tmp || 式4 === _tmp stmt2 else stmt3 end
===
がどのような条件で真になるかは、各クラスの ===
メソッ
ドの動作についてのドキュメントを参照して下さい。
case
の「式」を省略した場合、when
の条件式が偽でない最初の
式を評価します。
$bar = "true" case when $foo; p :foo when $bar; p :bar when $baz; p :baz end => :bar
case
は、条件が成立した when
節、(あるいは else
節)
の最後に実行した式の結果を返します。いずれの条件も成り立たなければ
nil
を返します。
例:
while sunshine work() end
文法:
while 式 [do] ... end
式を評価した値が真の間、本体を繰り返して実行します。
while
は、値を返しません。
例:
sleep while idle
文法:
式 while 式
右辺の式を評価した値が真の間、左辺を繰り返して実行します。
左辺の式が begin
である場合には、それを最低一度は
評価します。
例:
begin sleep end while idle
while
修飾した式は値を返しません。
例:
until sunrise sleep end
文法:
until 式 [do] ... end
式を評価した値が真になるまで、本体を繰り返して実行します。
until
は、値を返しません。
例:
work until tired
文法:
式 until 式
右辺の式を評価した値が真になるまで、左辺を繰り返して実行しま す。
左辺の式が begin
である場合には、左辺を最低一度は
評価します。
例:
begin sleep end until sunrise
until
修飾した式は値を返しません。
例:
for i in [1, 2, 3] print i*2, "\n" end
文法:
for lhs ... in 式 [do] 式.. end
式を評価した結果のオブジェクトの各要素に対して本体を繰り返し て実行します。これは以下の式とほぼ等価です。
(式).each `{' `|' lhs..`|' 式.. `}'
「ほぼ」というのは、do ... end
または{ }
による
ブロックは新しいローカル変数の有効範囲を導入するのに対し、
for
文はローカル変数のスコープに影響を及ぼさない点が
異なるからです。
for
は、in
に指定したオブジェクトの each
メソッドの戻り値を返します。
例:
i=0 while i<3 print i, "\n" break end
文法:
break
break
はもっとも内側のループを脱出します。ルー
プとは
のいずれかを指します。Cと違い、break
はループを
脱出する作用だけを持ち、case
を抜ける作用は持ち
ません。
break
によりループを抜けた、for
やイテレータは、nil
を返します。
例:
next
文法:
next
next
はもっとも内側のループの次の繰り返しにジャンプします。
イテレータでは、yield 呼出し
の脱出になります。
next
により抜けた yield
式は nil
を返します。
例:
redo
文法:
redo
ループ条件のチェックを行なわず、現在の繰り返しをやり直します。
例:
retry
文法:
retry
イテレータ、ブロックまたはfor文の中で使われた場合には、そのイテレータ を起動しなおします。イテレータの引数も再評価されます。
for i in 1..5 retry if some_condition # i == 1 からやり直し end # ユーザ定義の "untilループ" def UNTIL(cond) yield retry unless cond end
retry
は、ループ以外に後述の rescue
節でも使えます。この場
合は、begin
式を始めからもう一度実行します。retry
を使うこ
とである処理が成功するまで処理を繰り返すようなループを作ることができます。
begin do_something # exception raised rescue # handles error retry # restart from beginning end
rescue
節やイテレータ、ブロック for 文以外で retry
が用い
られた場合には例外 LocalJumpError が発生します。
*55
イテレータ呼び出しにおける break
, next
, redo
,
retry
をまとめると以下のようになります。
def iter (a) : (b) yield (c) : (d) end iter { retry } -> (a) へ飛ぶ iter { redo } -> (b) へ飛ぶ iter { next } -> (c) へ飛ぶ iter { break } -> (d) へ飛ぶ
(a) は、厳密には引数評価から始まります。(b) は yield 実行の直前を 指しています。(d) は、メソッドの終了です。
def iter(var = p("(a)")) p " : " # p "(b)" yield p "(c)" p " : " ensure p "(d)" end iter { p "(b)"; retry } # => (a) .. (b)(d)(a) .. (b)(d)(a) ... iter { p "(b)"; redo } # => (a) .. (b)(b)(b)(b) ... iter { p "(b)"; next } # => (a) .. (b)(c) .. (d) iter { p "(b)"; break } # => (a)..(b)(d)
例:
raise "you lose" # 例外 RuntimeError を発生させる # 以下の二つは SyntaxError を発生させる raise SyntaxError, "invalid syntax" raise SyntaxError.new("invalid syntax") raise # 最後の例外の再発生
文法:
raise raise messageまたはexception raise error_type, message raise error_type, message, traceback
例外を発生させます。第一の形式では直前の例外を再発生させます。 第二の形式では、引数が文字列であった場合、その文字列をメッセー ジとする RuntimeError 例外を発生させます。引数が例外 オブジェクトであった場合にはその例外を発生させます。第三の形式 では第一引数で指定された例外を、第二引数をメッセージとして発生さ せます。第四の形式の第三引数は $@または callerで得られる スタック情報で、例外が発生した場所を示します。
発生した例外は後述の begin
式の rescue
節で捕らえることができます。
その場合 rescue error_type => var
の形式を使えば
例外オブジェクトを得られます。このオブジェクトは組み込み
変数 $! でも得られます。また例外が
発生したソースコード上の位置は変数 $@ に格納されます。
raise は Ruby の予約語ではなく、Kernel モジュールで 定義されている関数的メソッドです。
例:
begin do_something rescue recover ensure must_to_do end
文法:
begin 式.. [rescue [error_type,..] [=> evar] [then] 式..].. [else 式..] [ensure 式..] end
本体の実行中に例外が発生した場合、rescue
節(複数指定できます)が
与えられていれば例外を捕捉できます。発生した例外と一致する
rescue
節が存在する時には rescue
節の本体が実行されます。
発生した例外は $! を使って参照することができます。また、
指定されていれば変数 evar にも $!
と同様に発生した例外が格
納されます。
begin raise "error message" rescue => evar p $! p evar end # => #<RuntimeError: error message> #<RuntimeError: error message>
例外の一致判定は例外のクラスが rescue
節で指定したクラスと同じか
またはサブクラスであるかどうか Object#kind_of? を用いて判
定されます*57。
error_type が省略された時は StandardError のサブクラスであ る全ての例外を捕捉します。Rubyの組み込み例外は(SystemExit や Interrupt のような脱出を目的としたものを除いて) StandardError のサブクラスです。
例外クラスのクラス階層については 例外クラス を参照してください。
rescue
では error_type は通常の引数と同じように評価され、
そのいずれかが一致すれば本体が実行されます。error_type を評価し
た値がクラスやモジュールでない場合には例外 TypeError が発生しま
す。
省略可能な else
節は、本体の実行によって例外が発生しなかった場合
に評価されます。
ensure
節が存在する時は begin
式を終了する直前に必ず
ensure
節の本体を評価します。
begin
式が返す値は ensure
が実行される直前に評価された式で
す。
例:
open("nonexistent file") rescue STDERR.puts "Warning: #$!"
文法:
式1 rescue 式2
式1で例外が発生したとき、式2を評価します。 以下と同じ意味です。捕捉する例外クラスを指定することはできません。 (つまり、StandardError 例外クラスのサブクラスだけしか捕捉できません)
begin 式1 rescue 式2 end
rescue修飾子を伴う式の値は例外が発生しなければ式1、例外が発生すれば式2 です。ただし、大抵の場合、優先順位の都合により式全体を括弧で囲む必要が あります。
var = open("nonexistent file") rescue false p var => nil # 値を持たない変数 var が定義されただけ var = (open("nonexistent file") rescue false) p var => false
特にメソッドの引数に渡す場合は二重に括弧が必要となります。
p(open("nonexistent file") rescue false) => parse error p((open("nonexistent file") rescue false)) => false
例:
return return 12 return 1,2,3
文法:
return [式[`,' 式 ... ]]
式の値を戻り値としてメソッドの実行を終了します。式が2つ以上
与えられた時には、それらを要素とする配列をメソッドの戻り値と
します。式が一つもない場合には nil
が戻り値とな
ります。
例:
BEGIN { ... }
文法:
BEGIN '{' 文.. '}'
初期化ルーチンを登録します。BEGIN
直後の
{ }
内部(BEGIN
ブロック)で指定した文
は当該ファイルのどの文が実行されるより前に実行されます。複数
のBEGIN
が指定された場合には指定された順に実行さ
れます。
BEGIN
ブロックは独立したローカル変数のスコープを
導入するため、ローカル変数を外部と共有する事はありません。情
報の伝達にはグローバル変数を使う必要があります。
BEGIN
はトップレベルにしか置く事はできません。
例:
END { ... }
文法:
END '{' 文.. '}'
「後始末」ルーチンを登録します。END
ブロックで指
定した文はインタプリタが終了する時に実行されます。
複数の END
ブロックを登録した場合、その実行順序は
登録とは逆順です。
END
ブロックは、BEGIN
ブロックとは異
なり、イテレータと同様のスコープを持ち、周囲とスコープを共有
します。
END
ブロックは最初の1回だけしか評価
されないので以下のようにループの中で実行しても複数のEND
ブロックを登録できません。同一の後始末処理を複数登録する必要がある場合には
at_exitを使ってください。
5.times {|i| END { p i } } # => 0
END
もトップレベルにしか置く事はできません*58。
それと、END
で登録された実行文を取り除く事はで
きません。
END
ブロックの中で発生した例外はそのEND
ブロックを中断しますが、すべての後始末ルーチンが実
行されるようインタプリタを終了させずにメッセージだ
けが出力されます。
例:
END { p "FOO" } END { raise "bar"; p "BAR" } END { raise "baz"; p "BAZ" } => baz (RuntimeError) bar (RuntimeError) "FOO"
実行時例外です。例外を指定しない raise の呼び出しはこ の例外を発生させます。
全てのクラスから参照できるメソッドを定義しているモジュール。
Object
クラスはこのモジュールをインクルードしています。
組込み関数の項で解説されているメソッドはこのモジュールで定義され
ています。
Object
クラスのメソッドは実際にはこのモジュールで定義されていま
す。これはトップレベルでのメソッドの再定義に対応するためです。
この例外クラスとそのサブクラスは、rescue節でクラ スを省略したときにも捕捉できます。
trap されていない SIGINT
を受け取ると発生します。
SIGINT
以外のシグナル受信による例外は SignalException を参
照してください。
不正な型を使用したときに発生します。
例:
foo.bar() foo.bar bar() print "hello world\n" print Class::new
文法:
[式 `.'] 識別子 [`(' 式 ... [`*' [式]],[`&' 式] `)'] [式 `::'] 識別子 [`(' 式 ... [`*' [式]],[`&' 式] `)']
メソッド呼出し式はレシーバ(`.'
の左側の式の値)の
メソッドを呼び出します。レシーバが指定されない時はself
のメソッドを呼び出します。
メソッド名には通常の識別子の他、識別子に?
または
!
の続いたものが許されます。慣習として、述語(真
偽値を返すメソッド)には?
を、同名の
(!
の無い)メソッドに比べてより破壊的な作用をもつ
メソッド(例:tr
とtr!
)には
!
をつけるようになっています。
最後の引数の直前に*
がついている場合、その引数の
値が展開されて渡されます。つまり:
foo(*[1,2,3])
は
foo(1,2,3)
と同じです。
最後の引数の直前に&
がついている場合、その引
数で指定した手続きオブジェクトがブロックとしてメソッドに渡さ
れます。
メソッド呼び出しの際、privateなメソッドは関数形式
(レシーバを省略した形式)でしか呼び出すことができません。
またprotectedなメソッドはself
がそのメソッド
が定義されたのと同じクラス、またはそのサブクラスでなければ
呼び出せません。(呼び出し制限を参照)
例:
super super(1,2,3)
文法:
super super(式, ... )
super
は現在のメソッドがオーバーライドしているメ
ソッドを呼び出します。括弧と引数が省略された場合には現在のメソッド
の引数がそのまま引き渡されます。
例:
def foo( arg ) arg = 1 super arg # 1 を引数にして呼び出す super # 5 を引数にして呼び出す super() # 引数なしで呼び出す end foo 5
例:
[1,2,3].each do |i| print i*2, "\n" end [1,2,3].each {|i| print i*2, "\n" }
文法:
method(arg1, arg2, ...) do [`|' 式 ... `|'] 式 ... end method(arg1, arg2, ...) `{' [`|' 式 ... `|'] 式 ... `}' method(arg1, arg2, ..., `&' proc_object)
イテレータとは制御構造の抽象化のために用いられるメソッドです。
最初はループの抽象化のために用いられていましたが、最近では
その他の用途も拡大しています。do ... end
または { ... }
で
囲まれたコードの断片(ブロックと呼ばれる)を後ろに付けてメソッドを
呼び出すと、そのメソッドの内部からブロックを評価できます。
このようなブロックを呼び出すメソッドをイテレータと呼びます。
イテレータからのブロックの呼び出しはyield式を
用います。yield に渡された値は |
と |
の間にはさまれた
変数に代入されます。
{ ... }
の方がdo ... end
ブロックよりも結合強度が
強いです*59。例えば:
foobar a, b do .. end # foobar がイテレータとして呼び出されます foobar a, b { .. } # b がイテレータとして呼び出されます
ブロックの中で初めて代入された(宣言された)ローカル変数はその ブロックの中でだけ有効です。例えば
foobar { i = 20 # ローカル変数 `i' が宣言された ... } print defined? i # `i' はここでは未定義なので false foobar a, b do i = 11 # まったく別の変数 i の宣言 ... end
以下は逆にブロック外でも有効な例です。
i = 10 [1,2,3].each do |m| p i * m # いきなり i を使える end
ブロックの代わりに手続きオブジェクト(Proc)をブロックと
して渡すにはイテレータの引数の最後に `&
' で修飾した手
続きオブジェクトを渡します。
pobj = proc {|v| p v } [1,2,3].each(&pobj) => 1 2 3
例:
yield data
文法:
yield `(' [式 [`,' 式 ... ]] `)' yield [式 [`,' 式 ... ]]
引数をブロックの引数として渡してブロックを評価します。
ブロック引数の代入は多重代入と同じルールで行われます。
またyield
を実行したメソッドにブロックが渡されていない
(イテレータではない) 時は例外 LocalJumpError が発生します。
yield
の値はブロックを評価した値です。
例:
class Foo < Super def test : end : end
文法:
class 識別子 [`<' superclass ] 式.. end
クラスを定義します。クラス名はアルファベットの大文字で始まる識別子です。
クラス定義は、識別子で指定した定数へのクラスの代入になります (Ruby では、クラスもオブジェクトの一つで Classクラスの インスタンスです)。
クラスが既に定義されいるとき、さらに同じクラス名でクラス定義を書くとク ラスの定義の追加になります。ただし、元のクラスと異なるスーパークラスを 明示的に指定して定義すると、元のクラスとは異なる新たなクラスを同名で定 義することになります(このとき、クラス名の定数を上書きすることになるの で警告メッセージが出ます)。
class Foo < Array def foo end end # 定義を追加(スーパークラス Array を明示的に指定しても同じ) class Foo def bar end end # 別のクラスを定義(スーパークラスが異なるので) class Foo < String end # => warning: already initialized constant Foo
クラス定義式の中は self
がそのクラスであることと、
呼び出し制限のデフォルトが異なること以外
にトップレベルとの違いはありません。クラス定義式中には任意の式を書くこ
とができます。
クラス定義はネスト(入れ子)にして定義できます。以下の例で入れ子の外側の クラス Foo と内側のクラス Bar の間には(定数 Bar が Foo の中の定数 Foo::Bar であること以外には)継承関係などの機能的な関連はまったくありま せん。
class Foo class Bar end end
クラスのネストは、意味的に関連するクラスを外側のクラス/モジュールでひ とまとまりにしたり、包含関係を表すために使用されます。
# 関連するクラスを Net というカテゴリにまとめる # このような場合は外側は普通モジュールが利用される # (Net のインスタンスがない。Net を include できるなどのため) module Net class HTTP end class FTP end end obj = Net::HTTP.new # あるいは include Net obj = HTTP.new # 以下のような使い方は組込みのクラスにも見られる # 利用者は File::Constants を include することで、 # File::RDONLY などと書かずに直接 RDONLY と書くことができる。 class File module Constants RDONLY = 0 WRONLY = 1 end include Constants end File.open("foo", File::RDONLY) # あるいは include File::Constants File.open("foo", RDONLY) # 上記はあくまでも例である。実際の File.open ではより簡便な # File.open("foo", "r") という形式が使われる
クラス定義式は値を返しません。
例:
class << obj def test : end : end
文法:
class `<<' expr 式.. end
クラス定義と同じ構文で特定のオブジェクトの機能を定義します。 この構文の内部で定義したメソッドや定数は指定したオブジェクト に対してだけ有効になります。
特異クラス定義式は、最後に評価した式の結果を返します。 最後に評価した式が値を返さない場合は nil を返します。
例:
module Foo def test : end : end
文法:
module 識別子 式.. end
モジュールを定義します。モジュール名はアルファベットの大文字 で始まる識別子です。
モジュール定義は、識別子で指定した定数へのモジュールの代入に なります(Ruby では、モジュールもオブジェクトの一つで Moduleクラスのインスタンスです)。
モジュールが既に定義されいるとき、さらに同じモジュール名でモ ジュール定義を書くとモジュールの定義の追加になります。
モジュール定義式は値を返しません。
例:
def fact(n) if n == 1 then 1 else n * fact(n-1) end end
文法:
def メソッド名 [`(' [arg ['=' default]] ... [`,' `*' arg] [',' '&' arg]`)'] 式.. [rescue [error_type,..] [=> evar] [then] 式..].. [else 式..] [ensure 式..] end
この定義のある場所にメソッドを定義します。すなわち、 クラス/モジュール定義中ならばそのクラス/モジュールのメソッドを 定義します。トップレベルならばどこからでも呼べるメソッドを 定義します。このようなメソッドは結果として他の言語における 「手続き」のように使えます。
メソッド名としては通常の識別子の他に、再定義可能な演算子 (例: ==, +, -など 演算子式 を参照)も指定できます。
仮引数にデフォルト式が与えられた場合、メソッド呼び出し時に実
引数が与えられなかった場合にはデフォルト式を評価した結果で初
期化されます(デフォルト式の評価は呼び出し時に行われます)。最
後の仮引数の直前に*
がある場合には残りの実引数は
みな配列としてこの引数に格納されます。
また最後の仮引数の直前に&
があるとこのメソッドに与えられ
ているブロックが手続きオブジェクトとしてこの引数に格納されます。
ブロックが与えられなかった場合のブロック引数の値はnil
です。
*
と&
が同時に指定される場合には&
が後ろに来ます。
例:
# 引数のないメソッド。以下 end は省略 def foo end # 引数のあるメソッド def foo(arg, arg2) # デフォルト引数のあるメソッド def foo(arg = nil) # ブロックをとる def foo(arg, &block) # すべて持つ def foo(arg, arg2, arg3 = nil, *rest, &block) # 演算子形式 def ==(other) def +(other) def *(other)
そのほか特殊な形式をとるメソッド定義を以下に挙げます。
# 単項プラス/マイナス def +@ def -@ # 要素代入 def foo=(value) # obj.foo = value # [] と []= def [](key) # obj[key] def []=(key, value) # obj[key] = value def []=(key, key2, value) # obj[key, key2] = value # バッククォート記法 def `(arg) # `arg` または %x(arg)
バッククォート記法の実装はメソッドなのでこのように再定義が可能です。普 通はこのメソッドを再定義するべきではありませんが、まれにOS(シェル)のコ マンド実行の挙動に不具合がある場合などに利用できます*60。
通常のメソッド定義はネストできません。またメソッド実行時の
例外を捕捉するためにbegin
式と同様のrescue
節を
指定できます。
メソッドが呼び出されると、まず(必要ならば)引数のデフォルト式が
評価され、本体が評価され、メソッドレベルの rescue
節または
else
節が評価され、最後に ensure
節が評価されます。
メソッド全体の戻り値は return に渡した値です。
return
が呼び出されなかった場合は、本体/rescue
/else
の中で最後に評価した式の値です。その三つともすべてがカラだった
場合は nil
になります。
またメソッドは定義する前に呼び出すことはできません。例えば
foo def foo print "foo\n" end
は未定義メソッドの呼び出しで例外 NameError を発生させます。
メソッド定義式自体は値を返しません。
例:
def foo.test print "this is foo\n" end
文法:
def 式 `.' 識別子 [`(' [引数 [`=' default]] ... [`,' `*' 引数 ]`)'] 式.. [rescue [error_type,..] [=> evar] [then] 式..].. [else 式..] [ensure 式..] end
特異メソッドとはクラスではなくある特定のオブジェクトに固有の メソッドです。特異メソッドの定義はネストできます。
クラスの特異メソッドはそのサブクラスにも継承されます。言い替 えればクラスの特異メソッドは他のオブジェクト指向システムにお けるクラスメソッドの働きをすることになります。
特異メソッド定義式は値を返しません。
Ruby におけるクラスメソッドとはクラスの特異メソッドのことです。Ruby で は、クラスもオブジェクトなので、普通のオブジェクトと同様に特異メソッド を定義できます。
したがって、何らかの方法でクラスオブジェクトにメソッドを定義すれば、そ れがクラスメソッドとなります。具体的には以下のようにして定義することが 出来ます(モジュールも同様です)。
# 特異メソッド方式。 class Hoge def Hoge.foo end end # クラス定義の外でも良い def Hoge.bar end # 以下のようにすればクラス名が変わってもメソッド部の変更が不要 class Hoge def self.baz 'To infinity and beyond!' end end # 特異クラス方式。複数のメソッドを一度に定義するとき向き class << Hoge def bar 'bar' end end # モジュールをクラスに extend すれば、モジュールのインスタンス # メソッドがクラスメソッドになる module Foo def foo end end class Hoge extend Foo end
extend
については、Object#extend を参照して
ください。
メソッドは public
、private
、protected
の三通りの
呼び出し制限を持ちます。
public
に設定されたメソッドは制限なしに呼び出せます。
private
に設定されたメソッドは関数形式でしか呼び出せません。
protected
に設定されたメソッドは、そのメソッドが定義された
クラスおよびその下位クラスのインスタンスからしか呼び出せません。
デフォルトでは def
式がクラス定義の外にあれば private
、
クラス定義の中にあれば public
に定義します。これは
Module#public、Module#private、
Module#protected を用いて変更できます。ただし
initializeという名前のメソッドは定義する場所に関係なく常に
private
になります。
例:
def foo # デフォルトは private end class C def bar # デフォルトは public end def ok # デフォルトは public end private :ok # …だが、ここで private に変わる def initialize # initialize は private end end
例:
alias foo bar alias :foo :bar alias $MATCH $&
文法:
alias 新メソッド名 旧メソッド名 alias 新グローバル変数名 旧グローバル変数名
メソッドあるいはグローバル変数に別名をつけます。メソッド名に
は識別子そのものか Symbol を指定します(obj.method のよ
うな式を書くことはできません)。alias
の引数はメソッド
呼び出し等の一切の評価は行われません。
メソッドの定義内で別名を付けるにはModuleクラスのメソッド Module#alias_method を利用して下さい。
別名を付けられたメソッドは、その時点でのメソッド定義を引き継 ぎ、元のメソッドが再定義されても、再定義前の古いメソッドと同 じ働きをします。あるメソッドの動作を変え、再定義するメソッド で元のメソッドの結果を利用したいときなどに利用されます。
# メソッド foo を定義 def foo "foo" end # 別名を設定(メソッド定義の待避) alias :_orig_foo :foo # foo を再定義(元の定義を利用) def foo _orig_foo * 2 end p foo # => "foofoo"
グローバル変数の alias は一方の変更が他方に反映され、まった く同じ変数であるかのようになります。添付ライブラリの importenv.rb はこのことを利用して組込み変数 に英 語名をつけます。 *61
# 特殊な変数のエイリアスは一方の変更が他方に反映される $_ = 1 alias $foo $_ $_ = 2 p [$foo, $_] # => [2, 2] # こちらは通常の変数のエイリアスで本当の意味での # エイリアスにはならない。これは、version 1.6 ま # での制限 $bar = 3 alias $foo $bar $bar = 4 p [$foo, $bar] # => [3, 4]
ただし、正規表現の部分文字列に対応する変数
$1
,$2
, ... には別名を付けることができません。ま
た、インタプリタに対して重要な意味のあるグローバル変数
(組込み変数を参照)を再定義すると動作に支障を来す場合が
あります。
alias
式は nil を返します。
例:
undef bar
文法:
undef メソッド名[, メソッド名[, ...]]
メソッドの定義を取り消します。メソッド名には識別子そのもの
か Symbol を指定します(obj.method のような式を書くことはできません)。
undef
の引数はメソッド呼び出し等の一切の評価は行われません。
メソッドの定義内で定義を取り消すにはModuleクラスのメソッ ド Module#undef_method を利用して下 さい。
undef
のより正確な動作は、メソッド名とメソッド定義との
関係を取り除き、そのメソッド名を特殊な定義と関連づけます。この状態の
メソッドの呼び出しは例えスーパークラスに同名のメソッドがあっても例外
NameError を発生させます。
(一方、メソッド
Module#remove_method は、関係を取
り除くだけです。この違いは重要です)。
alias
による別名定義と
undef
による定義取り消しによってクラスのインタフェー
スをスーパークラスと独立に変更することができます。ただし、メ
ソッドがselfにメッセージを送っている場合もあるので、よく注意
しないと既存のメソッドが動作しなくなる可能性があります。
undef
式は nil を返します。
例:
defined? print defined? File.print defined?(foobar) defined?($foobar) defined?(@foobar) defined?(Foobar)
文法:
defined? 式
式が定義されていなければ、偽を返します。定義されていれば式の種別 を表す文字列を返します。
定義されていないメソッド、undef されたメソッド、
Module#remove_method により削除さ
れたメソッドのいずれに対しても defined?
は偽を返します。
特別な用法として以下があります。
defined? yield
yield の呼び出しが可能なら真(文字列 "yield")を返します。 block_given? と同様にメソッドがブロック付きで呼ばれたか を判断する方法になります。
defined? super
super の実行が可能なら真(文字列 "super")を返します。
defined? a = 1 p a # => nil
"assignment" を返します。実際に代入は行いませんがローカル変数は定義されます。
/(.)/ =~ "foo" p defined? $& # => "$&" p defined? $1 # => "$1" p defined? $2 # => nil
大文字で始まるメソッド名に対しては ()
を明示しなければ定数の判定
を行ってしまいます。
def Foo(a,b) end p defined? Foo # => nil p defined? Foo() # => "method" Foo = 1 p defined? Foo # => "constant"
以下は、defined? が返す値の一覧です。
クラスのクラス。より正確に言えば、個々のクラスはそれぞれメタクラスと呼
ばれる名前のないクラスをクラスとして持っていて、Class
はそのメタ
クラスのクラスです。この関係は少し複雑ですが、Ruby を利用するにあたっ
ては特に重要ではありません。
クラスは、モジュールとは
という違いがありますが、それ以外のほとんどの機能は Module から継
承されています。Module
のメソッドのうち
は Class
では未定義にされています。
Class.new([superclass])
Class.new([superclass]) {|klass| ... }
新しく名前の付いていない superclass のサブクラスを生成します。
superclass が省略された時にはObject
のサブクラスを生成
します。
名前のないクラスは、最初に名前を求める際に代入されている定数名を検 索し、見つかった定数名をクラス名とします。
p foo = Class.new # => #<Class:0x401b90f8> p foo.name # => "" Foo = foo # ここで p foo すれば "Foo" 固定 Bar = foo p foo.name # => "Bar" ("Foo" になるか "Bar" になるかは不定)
ruby 1.7 feature: ブロックが与えられると生成したクラスをブロックの引数に渡し、クラス のコンテキストでブロックを実行します。この場合も生成したクラスを返 します。
klass = Class.new(super) klass.module_eval {|m| ... } klass
と同じです。ブロックの実行は Module#initialize が行います。
new( ... )
クラスのインスタンスを作ります。このメソッドの引数はブロック引数も 含め initialize に渡されます。
superclass
クラスのスーパークラスを返します。
inherited(subclass)
クラスのサブクラスが定義された時、新しく生成されたサブクラスを引数 にインタプリタから呼び出されます。
class Foo def Foo.inherited(subclass) puts "class \"#{self}\" was inherited by \"#{subclass}\"" end end class Bar < Foo end # => class "Foo" was inherited by "Bar"
require 'importenv'
を加えるだけで環境変数をグローバル変数としてアクセスすることができるようになる。
require 'importenv' p $USER # => "rubikitch" (自分のユーザ名) $USER = "matz" p ENV["USER"] # => "matz" p $USER # => "matz" (*)
Ruby 1.6.2までは(*)の出力が自分のユーザ名になってしまうバグがあったが、それは1.6.3で修正されている。
Ruby には厳密な意味では関数はありませんが、Kernel モジュールで 定義されているメソッドは (どこからでも関数形式で呼び出せるので) 他言語における関数のように使えます。これらのメソッドを再定義する 場合は他の場所への影響を考えて行なう必要があります。
` str
文字列 str を外部コマンドとして実行し、その出力を文字列として
返します。このメソッドは `str`
の形式で呼ばれます
(%x(...) という表記によっても呼び出せます。
詳細は コマンド出力 を参照してください)。
実行したコマンドの終了ステータスは $? で参照できます。
コマンドの出力を得る必要がなく、単にコマンドを実行したいだけなら
system を使います。特に端末を制御するコマンドでは
`command`
は失敗するかもしれません。
Array(arg)
arg.to_ary か arg.to_a を呼び出して引数を配 列に変換した結果を返します。 変換した結果が配列でなければ例外 TypeError が発生 します。
Float(arg)
引数を浮動小数点数(Float)に変換した結果を返します。
整数や浮動小数点数と見なせない文字列を引数に指定した場合、例外 ArgumentError が発生します。 *62
String#to_f も参照してください。
Integer(arg)
引数を整数(Fixnum,Bignum)に変換した結果を返します。 変換した結果が整数(Integerのサブクラス)でなければ 例外 TypeError が発生します。
引数が文字列であった場合には、0x, 0b, 0 などの接頭辞に応じて それぞれ 16 進、2 進、8 進数として変換します。
整数と見なせない文字列を引数に指定した場合、例外 ArgumentError が発生します。 *63
String#hex, String#oct, String#to_i も参照してください。
String(arg)
arg.to_s
を呼び出して引数を文字列に変換した
結果を返します。
変換した結果が文字列でなければ例外 TypeError が発
生します。
arg が文字列の場合、何もせず arg を返します。
abort
Ruby プログラムを異常終了します。exit
との違いは、呼び出し時に $! が
nil
でなければその例外のメッセージを出力することと、
プログラムの終了ステータスが 1 固定であることです。
at_exit { .... }
与えられたブロックをインタプリタ終了時に実行します。at_exit
がメソッドである点を除けば、END ブロックによる終了
処理の登録と同等です。登録した処理を取り消すことはできません。
終了処理も参照してください。
登録した処理を Proc オブジェクトで返します。
autoload(const_name, feature)
定数 const_name を最初に参照した時に feature を require するように設定します。const_name は文字列または Symbol で指定します。 なお、const_name には、"::" 演算子を含めることはできません (つまり、トップレベルの定数しか指定できません)。
nil
を返します。
binding
変数・メソッドなどの環境情報を含んだ Binding オブジェクトを 生成して返します。通常、eval の第二引数として使います。
caller([level])
level 段上の呼出し元の情報を $@ の形式
のバックトレース(文字列の配列)として返します。トップレベルで
は空の配列を返します。caller の戻り値を $@
に代入
することで例外の発生位置を設定できます。以下のようなコードで
呼出し時のスタックトレースを表示できます。
caller(0).each {|c| puts c }
callcc {|cont| .... }
Continuation を参照してください。
catch(tag) {|tag| .... }
ブロックを実行してその値を返します。ブロックの実行中に
tag と同じ名前の throw が行われた
場合は、その throw
の第二引数を戻り値とします。
例えば以下のコードを実行すると some_process は 呼び出されず、また catch の戻り値は 10 ではなく 25 に なります。
ret = catch(:exit) { throw :exit, 25 some_process() 10 } p ret #=> 25
ネストしたループは break によって一気に抜 けることはできません。 このような場合、catch や 例外 を使用します。
catch(:loop1) { for i in 1..2 for j in 1..2 throw :loop1, j end end }
chop
chop!
システム変数 $_ を最後の文字を取り除いたものにし
ます(終端が"\r\n"であれば2文字取り除きます)。
chop!
は文字列そのものを変更しその結果を返しますが、
取り除く文字列がなければ nil
を返します。
詳細は String#chop を参照してください。
$_.chop
と関数 chop
では以下の点で違いがあります。
chop
は $_
の値をコピーして、コピーの方を更新し、
$_
に再代入します。chomp([rs])
chomp!([rs])
システム変数 $_ を rs で指定される末尾
の文字列を取り除いたものにします。
chomp!
は文字列そのものを変更しその結果を返しますが、
取り除く文字列がなければ nil
を返します。
rs のデフォルト値は $/ です。
詳細は String#chomp を参照してください。
$_.chomp
と関数 chomp
では以下の点で違いがあります。
chomp
は $_
の値をコピーして、コピーの方を更新し、
$_
に再代入します。eval(expr[,binding][,fname[,lineno=1]])
文字列 expr を Ruby プログラムとして評価してその結果を返しま す。第2引数に Proc オブジェクトまたは Binding オブジェ クトを与えた場合、そのオブジェクトを生成したコンテキストで文字列を 評価します。binding も参照してください。
def foo a = 1 binding end eval("p a", foo) # => 1
fname と lineno が与えられた場合には、ファイル fname 行番号 lineno に文字列があるかのように コンパイルされ、スタックトレースの表示などを差し替えることが できます。
exec(command)
exec(program[, arg1[, arg2[, ...]]])
command で指定されたコマンドを実行します。プロセスの実行コー ドはそのコマンド(あるいは shell。後述)になるので、起動に成功した場 合、この関数からは戻りません。起動に失敗し、ruby インタプリタに制 御が戻った場合は、例外 Errno::EXXX が発生します。
一番目の形式では command が shell のメタ文字
(* ? {} [] <> () ~ & | \ $ ; ' ` " \n
)を含む場合、
shell 経由で実行されます。そうでなければインタプリタから直接
実行されます。
二番目の形式では、常に shell を経由せずに実行されます。 この場合には空白や shell のメタキャラクタもそのまま program の引数に渡されます。 先頭の引数が2要素の配列であった場合、第1要素の文字列が実際に 起動するプログラムのパスであり、第2要素が「みせかけ」のプロ グラム名になります。
exit([status])
Rubyプログラムの実行を終了します。status として整 数が与えられた場合、その値を Ruby コマンドの終了ステータスとし ます。デフォルトの終了ステータスは 0 です。
exit
は例外 SystemExit を発生させ
ることによってプログラムの実行を終了させますので、
必要に応じて rescue 節で捕捉することができます。
exit!([status])
整数 status を終了ステータスとして、Ruby プログラム
の実行を終了します。exit!
は exit
と
は違って、例外処理などは一切行ないません。
forkの後、
子プロセスを終了させる時などに用いられます。
fork
fork { ... }
fork(2) システムコールを使ってプロセスの複製を作
ります。親プロセスでは子プロセスのプロセスIDを、子プロセスでは
nil
を返します。ブロックを指定して呼び出した場合には、生成し
た子プロセスでブロックを評価します。
gets([rs])
readline([rs])
Ruby インタプリタ実行時に引数として与えられたファイル(なければ標準
入力)をつなげた仮想的なファイル(システム変数 $<
や ARGF でアクセスできる) から一行読み込んで、文字列を返しま
す。ファイルの終りに到達した時には nil
を返します。
行の区切りは引数 rs で指定した文字列になります。rs の デフォルト値はシステム変数 $/ の値です。読み込 んだ文字列はシステム変数 $_ にもセットされます。
rs に nil
を指定すると行区切りなしとみなしてファイルの内容を
すべて読み込みます。
空文字列 ""
を指定すると連続する改行を行の区切りとみなします
(パラグラフモード)。
readline
は gets
と同じ働きをしますが、
ファイルの最後まで読むと例外 EOFError を発生させます。
global_variables
プログラム中で定義されているグローバル変数(`$'で始まる変数)名の 配列を返します。
local_variables, Object#instance_variables, Module.constants, Module#constants, Module#class_variables も参照してください。
gsub(pattern[, replace])
gsub!(pattern[, replace])
gsub(pattern) {|matched| ... }
gsub!(pattern) {|matched| ... }
システム変数 $_ の指す文字列内で pattern に マッチする部分を全て replace に置き換えた文字列を返します。 引数 replace が省略された時にはイテレータとして動作し、ブロッ クを評価した結果で置換を行います。ブロックには引数としてマッチした 文字列が渡されます。
$_ = "foobar" p gsub(/o+/) {|m| m.upcase } # => "fOObar"
gsub!
は $_
の指している文字列そのものを書き換えます。
詳細は、String#gsub を参照してください。
String#gsub
と関数 gsub
では以下の点で違いがあります。
gsub
メソッドは $_
の値をコピーして、コピーの方を更新し、
$_
に再代入します。iterator?
block_given?
メソッドにブロックが与えられている時には真、そうでない時に偽 を返します。
load(file[, priv])
file から Ruby プログラムをロード・実行します。
file をロードするパスはシステム変数 $:
で決定されます。パス先頭の `~
'(チルダ)はユーザのホームディ
レクトリに展開されます。
省略可能な引数 priv が真のとき、 ロード・実行は内部的に生成される無名モジュールを トップレベルとして行われ、グローバルな名前空間を汚染しません。
ロードに成功した場合は、true
を返します。失敗した場合は、例
外 LoadError が発生します。
local_variables
現在のスコープで定義されているローカル変数名の配列を返します。
global_variables, Object#instance_variables, Module.constants, Module#constants, Module#class_variables も参照してください。
loop
(中断されない限り)永遠にブロックの評価を繰り返します。
open(file[, mode[, perm]])
open(file[, mode[, perm]]) {|io| ... }
file をオープンして、File オブジェクトを返します。
mode は、以下の文字列か整数(File::Constants モジュール
の定数の論理和)を指定します。省略時は "r"
が指定されたもの
とみなします。
"+" があれば、ファイルは読み書き両用モード(RDWR)でオープ ンされます。
これらのいずれに対しても "b" フラグを("r+b"のように)つけることがで きます(整数なら File::BINARY)。この場合、バイナリモードでオープン します(ただし、システムがテキスト/バイナリでファイルを区別する場 合に限ります)
第 3 引数 perm は open(2) の第 3 引数と同
じく、CREAT
時のファイルのアクセス権を整数で指定します。
この引数は、第 2 引数が数値形式でなければ無視されます*65。
デフォルトは 0666 です。
ファイル名が `|
' で始まる時には続く文字列をコマンドとして起
動し、コマンドの標準入出力に対してパイプラインを生成します
ファイル名が "|-"
である時、open
は Ruby の子プロセス
を生成し、その子プロセスとの間のパイプ(IOオブジェクト)を返し
ます。(このときの動作は、IO.popen と同じです。
File.open にはパイプラインを生成する機能はありません)。
注意: Perlと異なりコマンドは常に `|
' で始まります。
open
がブロックとともに呼び出された時、open
はファイル
をオープンしてブロックを実行し、ブロックの実行が終了するとファイル
をクローズします。この場合はブロックを評価した結果を返します。つま
り、以下のようになります。
open(path, mode) do |f| ... end # 上記とほぼ同じコード f = open(path, mode) begin ... ensure f.close end
p(obj, [obj2, ...])
obj を人間に読みやすい形で出力します。以下のコードと同じです。 (Object#inspect参照)
print obj.inspect, "\n", obj2.inspect, "\n", ...
nil
を返します。
print([arg1[, arg2, ...]])
引数を順に出力します。引数が与えられない時には変数
$_ の値を出力します。
文字列以外のオブジェクトが引数として与えられた場合には、
当該オブジェクトを to_s
メソッドにより文字列に変換
してから出力します。
ただし、nil
に対しては文字列 "nil"
を出力します
変数 $; (出力フィールドセパレータ)に nil
で
ない値がセットされている時には、各引数の間にその文字列を出力します。
変数 $\ (出力レコードセパレータ)に nil
でな
い値がセットされている時には、最後にそれを出力します。
nil
を返します。
printf([port, ]format[, arg[, ...]])
C 言語の printf と同じように、format に従い引数を文字列に変 換して $> に出力します。第一引数が IO のサ ブクラスのインスタンスであった場合はそのオブジェクトに対して出力を 行ないます*66。 引数を 1 つも指定しなければ何もしません *67。
Ruby における format 文字列の拡張についてはsprintfフォーマット の項を参照してください。
nil
を返します。
proc
lambda
与えられたブロックから手続きオブジェクト (Proc のインスタンス) を生成して返します(Proc.newと同じです)。
ブロックが指定されなければ、呼び出し元のメソッドで指定されたブロック を手続きオブジェクトとして返します。呼び出し元のメソッドがブロックなし で呼ばれると ArgumentError 例外が発生します。
putc(ch)
文字 ch を $> に出力します。 ch が数字なら 0 〜 255 の範囲の対応する文字を出力 します。ch が文字列なら、その先頭の文字を出力します。
ch を返します。
putc("ch") putc(?c) putc(99) # => ccc
puts([obj[, obj2[, ....]]] )
obj と改行を順番に $> に出力します。 引数がなければ改行のみを出力します。
引数が配列の場合、その要素と改行を順に出力します。
配列や文字列以外のオブジェクトが引数として与えられた場合には、
当該オブジェクトを最初に to_ary
により配列へ、
次に to_s
メソッドにより文字列へ変換を試みます。
ただし、nil
に対しては文字列 "nil"
を出力します
末尾が改行で終っている引数に対しては puts
自身
は改行を出力しません。
puts "foo", "bar\n", "baz" puts "" # 改行のみ出力 puts # 改行のみ出力 puts "foo" => foo bar baz foo
nil
を返します。
raise
raise(exception)
raise(message)
raise(error_type, message [, backtrace])
fail(error_type, message [, backtrace])
例外を発生させます。
引数が無い場合は、同スレッドの同じブロック内で最後に rescue された 例外オブジェクト ($!) を再発生させます。そのような 例外が存在しないときは例外 RuntimeError を発生させます。
begin open("nonexist") rescue raise # => `open': No such file or directory - "nonexist" (Errno::ENOENT) end
引数が一つの場合、引数が文字列であれば、その文字列をメッ
セージとする RuntimeError
例外を発生させます。引数
が例外クラスまたは例外オブジェクトであった場合にはその例
外を発生させます。
raise "error message" # => -:1: error message (RuntimeError) raise ArgumentError # => -:1: ArgumentError (ArgumentError) raise ArgumentError.new # => -:1: ArgumentError (ArgumentError)
引数が二つまたは三つの場合、第一引数で指定された例外を、第二引数に 与えたメッセージとともに発生させます。この場合、例外は例外クラスまたは 例外オブジェクトで指定します。第三引数は例外発生時のスタックトレース で、caller の戻り値と同じ形式でなければいけません。
raise ArgumentError, "error message" # => -:1: error message (ArgumentError) raise ArgumentError, "error message", ["file1:99", "file2:999:in `method'"] # => file1:99: error message (ArgumentError) from file2:999:in `method'
例外ではないクラスやオブジェクトを第一引数に指定した場合、実際に
発生する例外はそのオブジェクトの exception
メソッドが
返す値になります。
class MyException def exception ArgumentError.new end end raise MyException.new # => -:7: ArgumentError (ArgumentError)
第二の形式で引数を指定した場合は、exception
メソッ
ドにその引数が渡されます。
class MyException def exception(mesg) ArgumentError.new(mesg) end end raise MyException.new, "error message" # => -:7: error message (ArgumentError)
exception
メソッドは必ず例外オブジェクトを返さなければいけ
ません。そうでない場合は TypeError が発生します。
rand([max=0])
0 以上 max 未満の範囲の整数の乱数を発生します。ま
だsrand が呼ばれていなければ自動的に
srand
を呼び出します。
max に nil
または 0 を指定すると 0 以上 1 未
満の実数値 Float で乱数を与えます。
readlines([rs])
コマンドライン引数として与えられたファイル(なければ標準入力) をつ なげた仮想的なファイル(ARGFを全て読み込んで、その 各行を要素としてもつ配列を返します。
行の区切りは引数 rs で指定した文字列になります。rs の デフォルト値はシステム変数 $/ の値です。
rs に nil
を指定すると行区切りなしとみなします。
空文字列 ""
を指定すると連続する改行を行の区切りとみなします
(パラグラフモード)。
require(feature)
Ruby ライブラリ feature をロードパス $: 上 から探し、同じライブラリがまだロードされていなかった時だけロードし ます。
Ruby ライブラリとは Ruby スクリプト (*.rb
) か拡張ライブラリ
(*.so
) であり、feature の拡張子が省略された場合はその
両方から探します(検索順序に関しては $: を参照して
ください)。省略されなかった場合は指定された種別のみを探します。ま
た拡張ライブラリの拡張子にはアーキテクチャで実際に使われる拡張子に
関らず常に .so
を用います。
実際にライブラリをロードした時には true
、既にロードされてい
る時には false
を返します。ロードに失敗した場合は、例外
LoadError が発生します。ロードした feature の名前を(拡
張子も含めて)、変数 $" に追加します。
scan(re)
scan(re) {|matched| ... }
select(reads[, writes[, excepts[, timeout]]])
IO.select と同じです。
set_trace_func(trace_proc)
Ruby インタプリタがプログラムを実行する過程で、メソッドの呼び出しや 式の評価などのイベントが発生する度に手続きオブジェクト trace_proc を実行します。標準添付のデバッガ、トレーサ、 プロファイラはこの組み込み関数を利用して実現されています。
例:
set_trace_func lambda {|event, file, line, id, binding, klass| # .... }
ブロック引数の意味は以下の通りです。
実行のタイプを表す、以下のいずれかの文字列。
実行中のプログラムのソースファイル名 (文字列)。
実行中のプログラムのソースファイル上の行番号 (整数)。
event に応じ、以下のものが渡されます。 第六ブロック引数の klass と対応しています。
実行中のプログラムのコンテキストを表す Binding オブジェクト。
event に応じ、以下のものが渡されます。 第四ブロック引数の id と対応しています。
sleep([sec])
sec 秒だけプログラムの実行を停止します。sec
には浮動小数点数も指定できます。sec が省略された場
合、(SIGALRM
または他スレッドからの
Thread#run) などで明示的に起こさない限り永
久にスリープします。戻り値は実際に停止していた秒数(整数)です。
split([sep[, limit]])
$_ の示す文字列をパターン sep によって limit 個の文字列に分割し、その配列を返します。詳細 は String#split を参照してください。
sprintf(format ... )
format(format ... )
format 文字列を C 言語の sprintf
と同じよう
に解釈し、引数をフォーマットした文字列を返します。
format 指定子は C 言語の sprintf
が受け付け
るものとほとんど同じです。
Ruby には整数の大きさに上限がないので、%b, %o, %x
に負の数を与えると(左側に無限に1が続くとみなせるので)
..f
のような表示をします。絶対値に符号を付けた形式
で出力するためには%+x
、% x
のように指定します。
詳細はsprintfフォーマットを参照してください。
srand([seed])
rand の乱数の種を設定し、古い初期値を返 します。初期値が省略された時には現在の時間などを種にしま す。
sub(pattern[, replace])
sub!(pattern[, replace])
sub(pattern) {|matched| ... }
sub!(pattern) {|matched| ... }
システム変数 $_ の指す文字列内で pattern に マッチする最初の部分を replace に置き換えた文字列を返します。 引数 replace が省略された時にはイテレータとして動作し、ブロッ クを評価した結果で置換を行います。ブロックには引数としてマッチした 文字列が渡されます。
sub!
は $_
の指している文字列そのものを書き換えます。
詳細は、String#sub を参照してください。
String#sub
と関数 sub
では以下の点で違いがあります。
sub
メソッドは $_
の値をコピーして、コピーの方を更新し、
$_
に再代入します。syscall(num, arg ... )
numで指定された番号のシステムコールを実行します。 第2引数以降をシステムコールの引数として渡します。引数は文字 列または整数でなければなりません。
どの数値がどのシステムコールに対応するかは、
syscall(2) や
/usr/include/sys/syscall.h
を参照してください。
システムコールの慣習に従い、syscall(2) が -1 を返す場合には例外 Errno::EXXX が発生します。 それ以外では、返した値をそのまま数値で返します。
system(command)
system(program[, arg1[, arg2[, ...]]])
command を実行して、成功した時(サブプロセスが終了ステータス 0 で終了した時)には真を、失敗した時(シェルを介している場合はコマンド が実行できなかった場合も含む)には偽を返します。終了ステータスは変 数 $? で参照できます。
その他の挙動に関しては exec を参照して ください。
test(cmd, file1 [, file2])
ファイルテストを行います。cmd は以下に示す 数値リテラルか文字列です(文字列の場合はそ の先頭の文字だけをコマンドとみなします)。
1つの引数を取るもの
?r
ファイルを実効 uid で読むことができる
?w
ファイルに実効 uid で書くことができる
?x
ファイルを実効 uid で実行することができる
?o
ファイルの所有者が実効 uid である
?G
ファイルのグループ所有者が実効 gid である
?R
ファイルを実 uid で読むことができる
?W
ファイルに実 uid で書くことができる
?X
ファイルを実 uid で実行することができる
?O
ファイルの所有者が実 uid である
?e
ファイルが存在する
?z
ファイルサイズが 0 である
?s
ファイルサイズが 0 でない(ファイルサイズを返す)
?f
ファイルはプレーンファイルである
?d
ファイルはディレクトリである
?l
ファイルはシンボリックリンクである
?p
ファイルは名前つきパイプ(FIFO)である
?S
ファイルはソケットである
?b
ファイルはブロック特殊ファイルである
?c
ファイルはキャラクター特殊ファイルである
?u
ファイルに setuid ビットがセットされている
?g
ファイルに setgid ビットがセットされている
?k
ファイルに sticky ビットがセットされている
?M
ファイルの最終更新時刻を返す
?A
ファイルの最終アクセス時刻を返す
?C
ファイルの inode 変更時刻を返す
2つの引数を取るもの
?=
ファイル1とファイル2の最終更新時刻が等しい
?>
ファイル1の方がファイル2より最終更新時刻が新しい
?<
ファイル1の方がファイル2より最終更新時刻が古い
?-
ファイル1がファイル2にハードリンクされている
throw(tag[, value=nil])
同じ tag を指定した catch のブロックの
終わりまで(メソッドを越えて)脱出します。もし同じ tag で
待っている catch
が存在しない場合は NameError で
スレッドが終了します。tag は文字列またはシンボルです。
value は catch
の戻り値になります。
例:
ret = catch(:exit) { throw :exit, 25 some_process() # 絶対に実行されない 10 } p ret #=> 25
trace_var(varname, hook)
trace_var(varname) {|newval| .... }
グローバル変数 varname(文字列かシンボルで指定しま
す)への代入のフックを登録します。
この呼び出し以降、varname で指定したグローバル変数に
代入が起こると文字列または Proc オブジェクト hook
が評価されます。フックが Proc
オブジェクトなら
ブロック引数に代入された値が渡されます。またフックは複数
登録できます。
トレースを解除するには、hook に nil
を
指定するか、untrace_var を用います。
例:
trace_var(:$v) {|val| puts "$v=#{val.inspect}" } $v = "foo" #=> $v="foo" $v = 1 #=> $v=1
hook が nil
ならば、設定されていた
hook の配列を返します(ブロックで登録されていれば
Proc オブジェクトで返されます)
それ以外は、nil
を返します。
trap(signal, command)
trap(signal) { ... }
signal で指定された割り込みにたいするハンドラとして command を登録します。signal はシグナル名の 文字列か Symbol、またはシグナル番号で指定します。
command は文字列またはブロックで指定します。
nil
、空文字列""
、"SIG_IGN"
または
"IGNORE"
を指定した時は、そのシグナルを無視します
(可能ならば)。
"SIG_DFL"
または "DEFAULT"
を指定した時は、
デフォルトの動作を行なうようになります。
"EXIT"
を指定した時は、シグナルを受け取ると終了処理を
行ったあとステータス 0 で終了します。
また signal の特別な値として 0 または "EXIT"
を指定できます。これは「プログラムの終了時」を表します。
いくつかのシグナルに対して、Ruby インタプリタは例外 Interrupt や SignalException を発生させます。このようなシグナルは例外処理によっ て捕捉することもできます。
begin Process.kill :QUIT, $$ # 自身にSIGQUITを送信 rescue SignalException puts "rescue #$!" end # => rescue SIGQUIT
trap() により捕捉されたシグナルは例外を発生させません。
trap は既にシグナルに対応する command が登録されて
いれば、それを返します(ブロックは Proc オブジェク
トとして返されます。"IGNORE" や "DEFAULT" に対しては
nil
を返します)。何も登録されていなければ
nil
を返します。
p trap(:INT, "p true") # => nil p trap(:INT) { } # => "p true" p trap(:INT, "SIG_IGN") # => #<Proc:0x401b1328> p trap(:INT, "DEFAULT") # => nil p trap(:INT, "EXIT") # => nil p trap(:INT, nil) # => "EXIT"
untrace_var(varname[, hook])
グローバル変数 varname に関連付けられたフックを
解除します。hook が指定された場合にはそのフックだけを
解除します。hook が省略されるかまたは nil
を
与えた場合は varname のフックを全て解除します。
解除されたフックの配列を返します。
例:
$v = nil trace_var(:$v) {|val| puts "$v=#{val.inspect}" } $v = 'str' #=> $v="str" untrace_var :$v $v = 'str' # なにも出力されない
浮動小数点数のクラス。
Float.induced_from(num)
num を Float
に変換した結果を返します。
self + other
self - other
self * other
self / other
self % other
self ** other
算術演算子。それぞれ和、差、積、商、剰余、冪を計算します。
self <=> other
self
と other
を比較して、self
が大きい時に正、
等しい時に 0、小さい時に負の整数を返します。
self == other
self < other
self <= other
self > other
self >= other
比較演算子。
finite?
数値が ∞ でも、NaN でもなければ真を返します
infinite?
数値が +∞ のとき 1、-∞のとき -1 を返します。それ以外は nil を返 します。浮動小数点数の 0 による除算は ∞ です。
inf = 1.0/0 p inf p inf.infinite? => Infinity 1 inf = -1.0/0 p inf p inf.infinite? => -Infinity -1
nan?
数値が NaN(Not a number)のとき真を返します。浮動小数点数 0 の 0 に よる除算は NaN です。
nan = 0.0/0.0 p nan p nan.nan? => NaN true
to_f
self
を返します。
to_i
truncate
小数点以下を切り捨てて値を整数に変換します。
引数の数があっていないときや、値が正しくないときに発生します。
Time.at Math.sqrt(-1)
など*68
マシンのポインタのサイズに収まる長さの固定長整数。ほとんどのマシンでは
31 ビット幅です。演算の結果が Fixnum
の範囲を越えた時には自動的
に Bignum に拡張されます。
id2name
Symbol オブジェクトの整数値 (Symbol#to_i
で得られます)に対応する文字列を返します。整数に対応するシンボルが
存在しない時には nil
を返します。
多倍長整数のクラス。Bignum
が扱うことのできる大きさはメモリサイ
ズだけによって制限されます。演算の結果が Fixnum の範囲内である場
合には Fixnum
に変換され、逆に Fixnum
の範囲を越える時には
Bignum
に拡張されます。ビット演算については 2 の補数表現の無限長
のビットストリングとみなすことができます。特に負の数は左側に無限に 1
のビットが立っているように操作できます。Float との混合に関しては、
変換時に桁落ちが生じる可能性があります。
整数の抽象クラス。サブクラスとして Fixnum と Bignum があり ます。この 2 種類の整数は値の大きさに応じてお互いに自動的に変換されま す。ビット操作において整数は無限の長さのビットストリングとみなすことが できます。
Integer.induced_from(num)
num を Integer
に変換した結果を返します。
self[nth]
nth 番目のビットが立っている時 1 を、そうでなければ 0 を返し ます。
self + other
self - other
self * other
self / other
self % other
self ** other
算術演算子。それぞれ和、差、積、商、剰余、冪を計算します。
self <=> other
self
と other
を比較して、self
が大きい時に正、
等しい時に 0、小さい時に負の整数を返します。
self == other
self < other
self <= other
self > other
self >= other
比較演算子。
~ self
self | other
self & other
self ^ other
ビット演算子。それぞれ否定、論理和、論理積、排他的論理和を計算しま す。
self << bits
self >> bits
シフト演算子。bits
だけビットを右(左)にシフトします。
printf("%#b\n", 0b0101 << 1) printf("%#b\n", 0b0101 >> 1) => 0b1010 0b10
chr
文字コードに対応する 1 バイトの文字列を返します。例えば
65.chr
は "A" を返します。
逆に文字列から文字コードを得るには "A"[0]
とします
(String#[] を参照してください)。
整数は 0 から 255 の範囲内でなければなりません。範囲外の整数に対す る呼び出しは例外 RangeError を発生させます。
downto(min) {|n| ... }
self
から min まで 1 ずつ減らしながら繰り返します。
self
< min
であれば何もしません。
next
succ
次の整数を返します。
step(limit, step) {|n| ... }
self
からはじめ step を足しながら limit を越える
前までブロックを繰り返します。step は負の数も指定できます。
step に 0 を指定した場合は例外 ArgumentError が発生します。
self
を返します。
times {|n| ... }
self
回だけ(0 から self-1
まで)繰り返します。
self
が負であれば何もしません。
self
を返します。
to_i
to_int
self
を返します。
size
整数の実装上のサイズをバイト数で返します。
現在の実装では Fixnum は、sizeof(long)
固定(多くの 32
bit マシンで 4 バイト)、Bignumは、システム依存です。
p 1.size p 0x1_0000_0000.size # => 4 8
to_f
値を浮動小数点数(Fixnum)に変換します。
to_s
to_s(base) ((<ruby 1.7 feature>))
整数を 10 進文字列表現に変換します。
ruby 1.7 feature: 引数を指定すれば、それを基数とした文字列表 現に変換します。基数として 2, 8, 10, 16 以外を指定した場合は例外 ArgumentError が発生します。
p 10.to_s(2) # => "1010" p 10.to_s(8) # => "12" p 10.to_s(16) # => "a"
upto(max) {|n| ... }
self
から max まで 1 ずつ増やしながら繰り返します。
self
> min
であれば何もしません。
self
を返します。
組込み関数 callcc { |cont| ... }
の呼出し
は、直前の状態(ローカル変数の値、スタックフレーム)を cont に記憶
してブロックを実行します。cont は、Continuation クラスのインスタ
ンスで、Continuation#call メソッドを実行するこ
とでいつでも記憶した状態を継続することができます。
C 言語の setjmp()/longjmp() がわかる人は
setjmp() == callcc {|c| } longjmp() == c.call
と考えれば、わかりやすいかも知れません(ただし、callcc はスタックが深く なる方向にもジャンプ出来るという違いがあります)
callcc() は、ブロックの戻り値を返しますが、Continuation#call(args) が呼び出されたときは args を返します。
以下は、Continuationによる無限ループの例
def LOOP c = nil yield callcc {|c| true} c.call(false) end LOOP {|v| p v} => true false false false : :
callcc とは、call-with-current-continuation の略です。
call(ret[,ret2[,...]])
self
が記憶した状態を継続します。引数は そのまま
callcc の戻り値になります。
各 errno
に対応する例外クラスです。実際のクラス名については
Errno モジュールとシステムのマニュアル errno(3)
を参照してください。
Errno
各クラスに対応する errno
の値です。
Errno::EXXX::Errno
定数は、対応する値が常に設定されています
が、SystemCallError#errno メソッドは実際にエ
ラーが発生してなければ nil
を返します。
Errno::EAGAIN
と Errno::EWOULDBLOCK
はシステムによっ
ては同じ errno
値を持つ例外クラスです。以下は Errno
定数によりこのことを調べています。
p Errno::EAGAIN::Errno # => 11 p Errno::EWOULDBLOCK::Errno # => 11 p Errno::EAGAIN.new.errno # => nil p Errno::EWOULDBLOCK.new.errno # => nil
スクリプトに指定した引数 (ARGV を参照) をファイル名と
みなして、それらのファイルを連結した 1 つの仮想ファイルを表すオブジェ
クトです。ARGV
が空なら標準入力を対象とします。ARGV
を変更
すればこのオブジェクトの動作に影響します。
while line = ARGF.gets .. end
は、
while argv = ARGV.shift File.open(argv) {|file| while line = file.gets .. end } end
のように動作します。
ARGF
を処理するごとに ARGV
の要素は一つずつ取り除かれます。
最後まで ARGF
を読み込んだ後、再度 ARGF
から内容を読むと
(ARGV
が空なので)標準入力からの読み込みとなります。
ARGV.replace %w(/tmp/foo /tmp/bar) ARGF.each {|line| # 処理中の ARGV の内容を表示 p [ARGF.filename, ARGV]; ARGF.skip } # 最後まで読んだ後(ARGVが空)の動作 p ARGF.gets p ARGF.filename # => ["/tmp/foo", ["/tmp/bar"]] ["/tmp/bar", []] nil "-"
gets など一部の組込み関数は ARGF.gets
な
どこのオブジェクトをレシーバとしたメソッドの省略形です。
IO オブジェクトのメソッドに加えて、以下のメソッドを持ちます。
ARGF.to_s
ARGF.filename
処理対象のファイル名を返します。標準入力に対しては -
を返し
ます。組込み変数 $FILENAME と同じです。
ARGF.file
ARGF.lineno
全引数ファイルを一つのファイルとみなしたときの現在の行番号を返しま
す。個々の引数ファイル毎の行番号を得るには ARGF.file.lineno
とします。
ARGF.skip
処理対象のファイルをクローズします。次回の読み込みは次の引数が処理
対象になります。self
を返します。
EOF(End Of File)に達したときに発生します。
ファイルアクセスのためのクラス。通常 open を 使ってオープンされます。このクラスには FileTest モジュールに 定義されているのと同じ特異メソッドが定義されています。
File.atime(filename)
File.ctime(filename)
File.mtime(filename)
それぞれ、ファイルの最終アクセス時刻/状態が最後に変更された 時刻/最終更新時刻(Time オブジェクト)を返します。
ファイルの時刻の取得に失敗した場合は例外 Errno::EXXX が発生 します。
File.basename(filename[, suffix])
filename の一番後ろのスラッシュに続く要素を返します。もし、 引数 suffix が与えられて、かつそれが filename の末尾に 一致するなら、それを取り除いたものを返します。
例:
p File.basename("ruby/ruby.c") #=> "ruby.c" p File.basename("ruby/ruby.c", ".c") #=> "ruby"
File.chmod(mode[, filename[, ...]])
File.lchmod(mode[, filename[, ...]]) ((<ruby 1.7 feature>))
ファイルのモードを mode に変更します。モードを変更したファイ ルの数を返します。モードの変更に失敗した場合は例外 Errno::EXXX が発生します。
mode は chmod(2) と同様に数値で指定します。
lchmod
は、シンボリックリンクに関してリンクそのものの
モードを変更します。lchmod(2) を実装し
ていないシステムでこのメソッドを呼び出すと
NotImplementedError 例外が発生します。
File.chown(owner, group[, filename[, ...]])
File.lchown(owner, group[, filename[, ...]]) ((<ruby 1.7 feature>))
ファイルのオーナーとグループを変更します。スーパーユーザだけがファ イルのオーナーとグループを変更できます。変更を行ったファイルの数を 返します。変更に失敗した場合は例外 Errno::EXXX が発生します。
owner と group は、chown(2) と同様に
数値で指定します。
片方だけ変更したいような場合は nil
または -1
を指定する
ことでオーナーやグループを現在のままにすることができます。
lchown
は、シンボリックリンクに関してリンクそのもののオーナー、
グループを変更します。lchown(2) を実装していない
システムでこのメソッドを呼び出すと NotImplementedError 例外
が発生します。
File.delete(filename ... )
File.unlink(filename ... )
ファイルを削除します。削除したファイルの数を返します。削除に失敗し た場合は例外 Errno::EXXX が発生します。
このメソッドは通常ファイルの削除用で、ディレクトリの削除には Dir.rmdir を使います。
File.dirname(filename)
filename の一番後ろのスラッシュより前を文
字列として返します。スラッシュを含まないファイル名に対しては
"."
(カレントディレクトリ)を返します。
例:
p File.dirname("dir/file.ext") # => "dir" p File.dirname("file.ext") # => "."
File.expand_path(path[, default_dir])
path を絶対パスに展開した文字列を返します。
path が相対パスであれば default_dir を基準にします。
default_dir が nil
かまたは与えられなかった時にはカ
レントディレクトリが使われます。
先頭の ~
はホームディレクトリ(環境変数 HOME が使われます)に、
~USER
はそのユーザのホームディレクトリに展開されます。
p File.expand_path("..") #=> "/home/matz/work" p File.expand_path("..", "/tmp") #=> "/" p File.expand_path("~") #=> "/home/matz" p File.expand_path("~foo") #=> "/home/foo"
File.fnmatch(pattern, path[, flags]) ((<ruby 1.7 feature>))
File.fnmatch?(pattern, path[, flags]) ((<ruby 1.7 feature>))
ファイル名のパターンマッチを行います(fnmatch(3))。 path が pattern にマッチすれば真を返します。
pattern にはワイルドカードとして `*', `?', `[]' が使用 できます(Dir.globとは違って `{}' は使用できません)。
%w(foo foobar bar).each {|f| p File.fnmatch("foo*", f) } # => true true false
flags に以下の定数(File::Constants モジュールで定義さ れています)を論理和で指定することでパターンマッチの動作を変更する ことができます。flags のデフォルト値は0(フラグ指定なし)です。
エスケープ文字 `\' を普通の文字とみなします。
p File.fnmatch('\*', '\*', File::FNM_NOESCAPE) # => true
ワイルドカードをエスケープしない `\' はこのフラグに関らず `\' に マッチします*69。
p File.fnmatch('\\', '\\') # => true p File.fnmatch('\a', '\a') # => false
ワイルドカード `*', `?', `[]' が `/' にマッチしなくなります。 シェルのパターンマッチにはこのフラグが使用されています。
p File.fnmatch('*', '/', File::FNM_PATHNAME) # => false p File.fnmatch('?', '/', File::FNM_PATHNAME) # => false p File.fnmatch('[/]', '/', File::FNM_PATHNAME) # => false
ワイルドカード `*', `?', `[]' が先頭の `.' にマッチしなくなります。 シェルのパターンマッチにはこのフラグが使用されています。
p File.fnmatch('*', '.', File::FNM_PERIOD) # => false p File.fnmatch('?', '.', File::FNM_PERIOD) # => false p File.fnmatch('[/]', '.', File::FNM_PERIOD) # => false
アルファベットの大小文字を区別せずにパターンマッチを行います。
p File.fnmatch('A', 'a', File::FNM_CASEFOLD) # => true
File.ftype(filename)
ファイルのタイプを表す文字列を返します。文字列は以下のうちのいずれ かです。File.lstat(filename).ftype と同じで す(シンボリックリンクに対して "link" を返します)。
"file" "directory" "characterSpecial" "blockSpecial" "fifo" "link" "socket" "unknown"
File.join(item, item, ...)
File::SEPARATOR
を間に入れて文字列を連結します。
[item, item, ...].join(File::SEPARATOR)
と同じです。(DOSISH 対応で環境依存になる予定です。)
File.link(old, new)
old を指す new という名前のハードリンクを 生成します。old はすでに存在している必要があります。
ハードリンクに成功した場合は 0 を返します。失敗した場合は例外 Errno::EXXX が発生します。
File.new(path[, mode [, perm]])
File.open(path[, mode [, perm]])
File.open(path[, mode [, perm]]) {|file| ... }
pathで指定されるファイルをオープンし、ファイルオブジェクトを 返します。ファイルのオープンに失敗した場合は例外 Errno::EXXX が発生します。
引数 mode, perm については 組込み関数 open と同じです。
open()
はブロックを指定することができます。
ブロックを指定して呼び出した場合は、ファイルオブジェクトを
与えられてブロックが実行されます。ブロックの実行が終了すると、
ファイルは自動的にクローズされます。
ブロックが指定されたときのこのメソッドの戻り値はブロックの実行結果 です。
File.readlink(path)
シンボリックリンクのリンク先を文字列で返します。リンクの読み取りに 失敗した場合は例外 Errno::EXXX が発生します。
File.rename(from, to)
ファイルの名前を変更します。ディレクトリが異なる場合には移動も行い ます。rename(2) を参照してください。移動先のファ イルが存在する時には上書きされます。
ファイルの移動に成功した場合 0 を返します。失敗した場合は例外 Errno::EXXX が発生します。
File.split(pathname)
pathname を dirname
とbasename
に分割して、2 要
素の配列を返します。
[File.dirname(pathname), File.basename(pathname)]
と同じです。
File.stat(filename)
File.lstat(filename)
filename の情報を含む File::Stat オブジェクトを生成し て返します。情報の取得に失敗した場合は例外 Errno::EXXX が発 生します。
lstat
は、シンボリックリンクに関してリンクそのものの
情報を返します。
lstat(2) を実装していないシステムでは、
stat
と同じです。
File.symlink(old, new)
old への new という名前のシンボリックリンクを生成しま す。
シンボリックリンクの作成に成功すれば 0 を返します。失敗した場合は 例外 Errno::EXXX が発生します。
File.truncate(path, length)
path で指定されたファイルのサイズを最大 length バイト にします。
サイズの変更に成功すれば 0 を返します。失敗した場合は例外 Errno::EXXX が発生します。
File.umask([umask])
umask を変更します。変更前の umask の値を返します。umask を 省略すると変更を行わないで、現在の umask の値を返します。
File.utime(atime, mtime[, filename[, ...])
ファイルの最終アクセス時刻と更新時刻を変更します。変更したファイル の数を返します。変更に失敗した場合は例外 Errno::EXXX が発生 します。
先頭の二つの引数は時刻を指定する数値または Time クラスのイン スタンスでなければなりません。
これら以外にもFile
クラスはFileTestクラスで定義されているク
ラスメソッドも持っています。
atime
ctime
mtime
それぞれ、ファイルの最終アクセス時刻/状態が最後に変更された時刻/最 終更新時刻(Time オブジェクト)を返します。
ファイルの時刻の取得に失敗した場合は例外 Errno::EXXX が発生 します。
chmod(mode)
ファイルのモードを mode に変更します。モードの変更に成功した 場合は 0 を返します。失敗した場合は例外 Errno::EXXX が発生し ます。
mode は chmod(2) と同様に数値で指定します。
chown(owner, group)
ファイルのオーナーとグループを変更します。スーパーユーザだけがファ イルのオーナーとグループを変更できます。所有者の変更に成功した場合 は 0 を返します。変更に失敗した場合は例外 Errno::EXXX が発生 します。
owner と group は、chown(2) と同様に
数値で指定します。
nil
または -1
を指定することでオーナーやグループを現在
のままにすることができます。
flock(operation)
ファイルをロックします。ロックに成功した場合は 0 を返します。失敗
した場合は例外 Errno::EXXX が発生します。LOCK_NB
が指
定されていて、ブロックされそうな場合には false
を返します。
有効な operation は以下の通りです。
LOCK_SH
共有ロック。複数のプロセスが同時にロックを共有できます。
システムによってはロック対象のファイルは読み込みモード
("r", "r+" など
)でオープンされている必要があります。そのよ
うなシステムでは読み込み可能でないファイルに対するロックは例外
Errno::EBADF が発生するかもしれません。
LOCK_EX
排他ロック。同時にはただひとつのプロセスだけがロックを保持できます。
システムによってはロック対象のファイルは書き込みモード
("w", "r+" など
)でオープンされている必要があります。そのよ
うなシステムでは書き込み可能でないファイルに対するロックは例外
Errno::EBADF が発生するかもしれません。
LOCK_UN
アンロック。
この明示的なアンロック以外に、Rubyインタプリタの終了 (プロセスの終了)によっても自動的にロック状態は解除されます。
LOCK_NB
ノンブロックモード。
LOCK_SH | LOCK_NB
のように他の指定と or
することで指
定します。この指定がない場合、ブロックされる条件での flock
の呼び出しはロックが解除されるまでブロックされます。
LOCK_NB
の指定がある場合、ブロックされる条件での
flock
は false
を返します。
「ブロックされる条件」とは
の場合です
以上の定数は File::Constants モジュールで定義されています。
例:
f = File.open("/tmp/foo", "w") f.flock(File::LOCK_EX) puts "locked by process1" fork { f = File.open("/tmp/foo", "r") f.flock(File::LOCK_SH) puts "locked by process2" sleep 5 puts "unlocked by process2" } sleep 5 f.flock(File::LOCK_UN) puts "unlocked by process1" sleep 1 # <- 子プロセスが確実に先にロックするための sleep f.flock(File::LOCK_EX) puts "re-locked by process1" => locked by process1 unlocked by process1 locked by process2 unlocked by process2 re-locked by process1
path
オープンしているファイルのパスを返します。
stat
lstat
ファイルの状態を含む File::Stat オブジェクトを生成して返しま す。情報の取得に失敗した場合は例外 Errno::EXXX が発生します。 *71
lstat
は、シンボリックリンクに関してリンクそのものの
情報を返します。
lstat(2) を実装していないシステムでは、
IO#statと同じです。
truncate(length)
ファイルのサイズを最大 length バイトにします。ファイルが書き 込みモードでオープンされてなければ例外 IOError が発生します。
サイズの変更に成功すれば 0 を返します。失敗した場合は例外 Errno::EXXX が発生します。
ALT_SEPARATOR
システムのファイルパスのセパレータが SEPARATOR
と異なる場合
に設定されます。MS-DOS などでは "\"
です。UNIX や Cygwin な
どでは nil です。
PATH_SEPARATOR
PATH 環境変数の要素のセパレータです。UNIX では ":"
MS-DOS な
どでは ";"
です。
SEPARATOR
Separator
ファイルパスのセパレータです。ファイルを扱うメソッドにパス名を渡す
場合などスクリプト内のパス名は環境によらずこのセパレータで統一され
ます。値は "/"
です。
Constants
File クラスに関係する定数を格納したモジュールです。File::Constants を参照してください。
Stat
stat 構造体(stat(2)参照)を表すクラスです。 File::Stat を参照してください。
File クラスに関る定数を集めたモジュール。
File
クラスはこのモジュールをインクルードしているので、以下に挙
げる定数は File
クラスの定数のように扱うことができます。
以下の定数は、File#flock で使用します。
LOCK_SH
共有ロック。複数のプロセスが同時にロックを共有できます。
LOCK_EX
排他ロック。同時にはただひとつのプロセスだけがロックを保持できます。
LOCK_UN
アンロック。
LOCK_NB
ロックの際にブロックしない。他の指定と or
することで指定します。
以下の定数は、File.openで使用します。
RDONLY
WRONLY
RDWR
APPEND
CREAT
EXCL
NONBLOCK
TRUNC
NOCTTY
BINARY
SYNC
以下の定数は、File.fnmatchで使用します。ruby 1.7 feature
FNM_NOESCAPE
FNM_PATHNAME
FNM_PERIOD
FNM_CASEFOLD
IO
クラスは基本的な入出力機能を実装します。
IO.new(fd[, mode])
IO.for_fd(fd[, mode]) ((<ruby 1.7 feature>))
オープン済みのファイルディスクリプタ fd に対する新しい
IO
オブジェクトを生成して返します。IO
オブジェクトの生
成に失敗した場合は例外 Errno::EXXX が発生します。
mode には、File.open と同じ形式で IO のモードを指 定します(ただし、文字列形式のみ)。 mode のデフォルト値は "r" です。
IO.foreach(path[, rs]) {|line| ... }
path で指定されたファイルの各行に対して繰り返します (open と同様 path の先頭が "|" ならば、コマ ンドの出力を読み取ります)。ちょうど以下のような働きをします。
port = open(path) begin port.each_line {|line| ... } ensure port.close end
path のオープンに成功すれば nil
を返します。
失敗した場合は例外 Errno::EXXX が発生します。
行の区切りは引数 rs で指定した文字列になります。rs の デフォルト値はシステム変数 $/ の値です。
rs に nil を指定すると行区切りなしとみなします。
空文字列 ""
を指定すると連続する改行を行の区切りとみなします
(パラグラフモード)。
IO.pipe
pipe(2) を実行して、相互につながった2つの
IO オブジェクトを要素とする配列を返します。IO
オブジェ
クトの作成に失敗した場合は例外 Errno::EXXX が発生します。
返り値の配列は最初の要素が読み込み側で、次の要素が書き込み側です。
p pipe = IO.pipe # => [#<IO:0x401b90f8>, #<IO:0x401b7718>] pipe[1].puts "foo" p pipe[0].gets # => "foo\n"
IO.popen(command [, mode])
command をサブプロセスとして実行し、そのプロセスの標準入出力 との間にパイプラインを確立します。mode はオープンする IO ポー トのモードを指定します(mode の詳細は open 参照)。省略されたときのデフォルトは "r" です。
生成したパイプ(IO オブジェクト)を返します。
p io = IO.popen("read foo; echo $foo", "r+") # => #<IO:0x401b75c8> io.puts "bar" p io.gets # => "bar\n"
ブロックが与えられた場合は生成した IO
オブジェクトを引数にブ
ロックを実行し、その結果を返します。ブロックの実行後、生成したパイ
プは自動的にクローズされます。
p IO.popen("read foo; echo $foo", "r+") {|io| io.puts "bar" io.gets } # => "bar\n"
コマンド名が "-"
の時、Ruby は fork(2) を
行い子プロセスの標準入出力との間にパイプラインを確立します。このと
きの戻りは、親プロセスは IO
オブジェクトを返し、子プロセスは
nil
を返します。ブロックがあれば、親プロセスは生成した
IO
オブジェクトを引数にブロックを実行しその結果を返します。
(パイプはクローズされます)
子プロセスは nil
を引数にブロックを実行し終了します。
# ブロックなしの例 io = IO.popen("-", "r+") if io.nil? # child s = gets print "child output: " + s exit end # parent io.puts "foo" p io.gets # => "child output: foo\n" io.close # ブロックありの例 p IO.popen("-", "r+") {|io| if io # parent io.puts "foo" io.gets else # child s = gets puts "child output: " + s end } # => "child output: foo\n"
パイプ、あるいは子プロセスの生成に失敗した場合は例外 Errno::EXXX が発生します。
IO.read(path,[length,[offset]]) ((<ruby 1.7 feature>))
path で指定されたファイルを offset 位置から length バイト分読み込んで返します。ちょうど以下のような働き をします。
port = open(path) port.pos = offset if offset begin port.read length ensure port.close end
length が nil
であるか省略した場合には、EOF まで読み込
みます。
IO が既に EOF
に達していれば nil
を返します。
path のオープン、offset 位置への設定、ファイルの読み込 みに失敗した場合は例外 Errno::EXXX が発生します。 length が負の場合、例外 ArgumentError が発生します。
IO.readlines(path[, rs])
path で指定されたファイルを全て読み込んで、その各行を要素と
してもつ配列を返します。
IO が既に EOF に達していれば空配列 []
を返します。
ちょうど以下のような働きをします。
port = open(path) begin port.readlines ensure port.close end
行の区切りは引数 rs で指定した文字列になります。rs の デフォルト値はシステム変数 $/ の値です。
rs に nil を指定すると行区切りなしとみなします。
空文字列 ""
を指定すると連続する改行を行の区切りとみなします
(パラグラフモード)。
path のオープン、ファイルの読み込みに失敗した場合は例外 Errno::EXXX が発生します。
IO.select(reads[, writes[, excepts[, timeout]]])
select(2) を実行します。 reads/writes/exceptsには、入力待ちする IO (またはそのサブクラス)のインスタンスの配列を渡します。
timeout は整数、Float または nil
(省略
時のデフォルト値)を指定します。nil
を指定した時に
は IO がレディ状態になるまで待ち続けます。
戻り値は、timeout した時には nil
を、そうで
ないときは 3 要素の配列を返し、その各要素が入力/出力/例外
待ちのオブジェクトの配列です(指定した配列のサブセット)。
select と同じです。
self << object
object を出力します。object が文字列でない時にはメソッ
ド to_s
を用いて文字列に変換します。self
を戻り値とす
るので、以下のような <<
の連鎖を使うことができます。
$stdout << 1 << " is a " << Fixnum << "\n"
出力に失敗した場合は例外 Errno::EXXX が発生します。
binmode
ストリームをバイナリモードにします。MSDOS などバイナリモードの存在 する OS でのみ有効です(そうでない場合このメソッドは何もしません)。 バイナリモードから通常のモードに戻す方法は再オープンしかありません。
self
を返します。
clone
dup
レシーバと同じ IO を参照する新しい IO オブジェクトを返します。
(参照しているファイル記述子は dup(2) されます)
clone の際に self
は一旦 flush されます。
フリーズした IO の clone は同様にフリーズされた IO を返しますが、 dup は内容の等しいフリーズされていない IO を返します。
close
入出力ポートをクローズします。以後のこのポートに対する入出力 操作は例外を発生します。ガーベージコレクトの際にはクローズさ れていないIOポートはクローズされます。 Traps:closeをGCにまかせる
self
がパイプでプロセスにつながっていれば、そのプロセスの終
了を待ち合わせます。
nil
を返します。
close_read
読み込み用の IO を close します。主にパイプや読み書き両用に作成し た IO オブジェクトで使用します。
self
が読み込み用にオープンされていなければ、例外
IOError が発生します。
nil
を返します。
close_write
書き込み用の IO を close します。
self
が書き込み用にオープンされていなければ、例外
IOError が発生します。
nil
を返します。
closed?
ポートがクローズされている時に真を返します。
each([rs]) {|line| ... }
each_line([rs]) {|line| ... }
IO ポートから 1 行ずつ読み込んで繰り返すイテレータ。IO ポートはリー ドモードでオープンされている必要があります(open参 照)。
行の区切りは引数 rs で指定した文字列になります。rs の デフォルト値はシステム変数 $/ の値です。
rs に nil を指定すると行区切りなしとみなします。
空文字列 ""
を指定すると連続する改行を行の区切りとみなします
(パラグラフモード)。
self
を返します。
each_byte {|ch| ... }
IO ポートから 1 バイトずつ読み込みます。IO ポートはリードモードで オープンされている必要があります(open参照)。
self
を返します。
eof
eof?
ストリームがファイルの終端に達した場合真を返します。
fcntl(cmd[, arg])
IOに対してシステムコール fcntl
を実行します。
機能の詳細はfcntl(2)を参照してください。
arg が整数の時にはその値を、true または false の場合はそれぞ れ 1 または 0 を、文字列の場合には pack した構造体だとみなしてその まま fcntl(2) に渡します。arg の省略時の値 は 0 です。
cmd に対して指定できる値は、添付ライブラリ fcntl.so の Fcntl モジュールが提供しています。
fcntl(2)
が返した数値を返します。fcntl(2)
の実行に失敗
した場合は例外 Errno::EXXX が発生します。
fsync ((<ruby 1.7 feature>))
書き込み用の IO に対して、システムコールfsync(2) を実行します。flushを行ったあと(OSレベルで)まだディスクに 書き込まれていないメモリ上にあるデータをディスクに書き出します。
成功すれば 0 を返します。失敗した場合は例外 Errno::EXXX が発
生します。self
が書き込み用でなければ例外 IOError が発
生します。
fileno
to_i
ファイル記述子の番号を返します。
flush
IO ポートの内部バッファをフラッシュします。
self
が書き込み用でなければ例外 IOError が発
生します。
self
を返します。
getc
IO ポートから 1 文字読み込んで、その文字に対応する Fixnum を
返します。EOF に到達した時には nil
を返します。
gets([rs])
一行読み込んで、読み込みに成功した時にはその文字列を返します。
ファイルの終りに到達した時には nil
を返します。
IO#each と同じように動作します
が、こちらは 1 行返すだけで繰り返しません。
行の区切りは引数 rs で指定した文字列になります。rs の デフォルト値はシステム変数 $/ の値です。
rs に nil を指定すると行区切りなしとみなします。
空文字列 ""
を指定すると連続する改行を行の区切りとみなします
(パラグラフモード)。
IO#gets
はgets 同様、読み込んだ文字列を変数
$_
にセットします。
ioctl(cmd[, arg])
IO に対してシステムコール ioctl
を実行します。
機能の詳細はioctl(2)を参照してください。
argが整数の時にはその値を、文字列の場合にはpackした構造体だ とみなしてioctl(2)に渡します。argの 省略時の値は0です。
isatty
tty?
入出力ポートがttyに結合している時、真を返します。
lineno
現在の行番号を返します。
lineno=number
行番号をセットします。
pid
IO.popen で作られたIOポートなら、子プロセスのプロセス ID を
返します。それ以外は nil
を返します。
pos
tell
ファイルポインタの現在の位置を返します。
pos = n
ファイルポインタを指定位置に移動します。
io.seek(pos, IO::SEEK_SET)
と同じです。
print([arg[, ...]])
引数を IO ポートに順に出力します。引数を省略した場合は、 $_ を出力します。 引数の扱いは print と同じです(詳細はこちらを参照 してください)。
nil
を返します。
printf(format[, arg[, ...]])
C
言語の printf
と同じように、format に従い引数
を文字列に変換して、self
に出力します。
第一引数に IO
を指定できないこと、引数を省略できないことを除
けば printf と同じです。
引数の扱いの詳細については sprintfフォーマット を参照してください。
nil
を返します。
putc(ch)
文字 ch を self
に出力します。
引数の扱いは putc と同じです(詳細はこちらを参照し
てください)。
ch を返します。
puts([obj[, ...]])
各 obj を self
に出力した後、改行します。
引数の扱いは puts と同じです(詳細はこちらを参照し
てください)。
nil
を返します。
read([length])
length バイト読み込んで、その文字列を返します。
length が省略された時には、EOF
までの
全てのデータを読み込みます。
IO が既に EOF
に達していれば nil
を返します。
データの読み込みに失敗した場合は例外 Errno::EXXX が発生しま す。length が負の場合、例外 ArgumentError が発生します。
readchar
IO#getc と同様に 1 文字読み込んで、その文字に対応す る Fixnum を返しますが、EOF に到達した時に例外 EOFError を発生させます。
readline([rs])
IO#gets と同様に 1 行読み込みその文字列を返しますが、 EOF に到達した時に例外 EOFError を発生させます。
行の区切りは引数 rs で指定した文字列になります。rs の デフォルト値はシステム変数 $/ の値です。
rs に nil を指定すると行区切りなしとみなします。
空文字列 ""
を指定すると連続する改行を行の区切りとみなします
(パラグラフモード)。
readline
は gets
同様読み込んだ文字列を変数 $_
にセットします。
readlines([rs])
データを全て読み込んで、その各行を要素としてもつ配列を返します。
IO が既に EOF に達していれば空配列 []
を返します。
行の区切りは引数 rs で指定した文字列になります。rs の デフォルト値はシステム変数 $/ の値です。
rs に nil を指定すると行区切りなしとみなします。
空文字列 ""
を指定すると連続する改行を行の区切りとみなします
(パラグラフモード)。
reopen(io)
reopen(name[, mode])
自身を io に繋ぎ換えます。クラスも io に等しくなります (注意)。
第 1 引数が文字列の時、name で指定されたファイルにストリーム を繋ぎ換えます。
self
を返します。
rewind
ファイルポインタを先頭に移動します。IO#lineno
は 0 になります。
seek(offset[, whence])
ファイルポインタを offset だけ移動させます。whence の
値が IO::SEEK_SET
の時にはファイルの先頭から、
IO::SEEK_CUR
の時には現在のファイルポインタから、
IO::SEEK_END
の時にはEOFから offset バイトだけ移動しま
す。whence の省略値は IO::SEEK_SET
です。
offset 位置への移動が成功すれば 0 を返します *72、ファイルの読み込 みに失敗した場合は例外 Errno::EXXX が発生します。
stat
ファイルのステータスを含む File::Stat オブジェクトを生成して 返します。
ステータスの読み込みに失敗した場合は例外 Errno::EXXX が発生 します。
sync
現在の出力同期モードを真偽値で返します。同期モードが真の時は 出力関数の呼出毎にバッファがフラッシュされます。
sync=newstate
出力同期モードを設定します。 newstate が真なら同期モード、偽なら非同期モードになります。 newstate を返します。
sysread(length)
read(2) を用いて入力を行ない、入力されたデータを
含む文字列を返します。ファイルの終りに到達した時には例外
EOFError を発生させます。stdio
を経由しないので
gets
や getc
や eof?
などと混用すると思わぬ動作
をすることがあります。
データの読み込みに失敗した場合は例外 Errno::EXXX が発生しま す。
syswrite(string)
write(2) を用いて string を出力します。
string が文字列でなければ to_s
による文字列化を試みます。
stdio
を経由しないので他の出力メソッドと混用すると思わぬ動作
をすることがあります。
実際に出力できたバイト数を返します。出力に失敗した場合は例外 Errno::EXXX が発生します。
to_io
self
を返します。
ungetc(char)
char を読み戻します。2バイト以上の読み戻しは保証されません。
nil
を返します。
write(str)
IOポートに対して str を出力します。str が文字列でなけ
れば to_s
による文字列化を試みます。
IO#syswrite を除く全ての出力メソッドは、最終的に "write" という名のメソッドを呼び出すので、このメソッドを置き換える ことで出力関数の挙動を変更することができます。
実際に出力できたバイト数を返します。出力に失敗した場合は例外 Errno::EXXX が発生します。
SEEK_CUR
SEEK_END
SEEK_SET
IO#seek を参照してください。
Ruby デバッガです。ruby スクリプトのソースデバッグに使用します。
Emacs を使用したインタフェースruby/misc/rubydb[23]x.el
も ruby の
アーカイブの中にあります。
rubydb2x.el
は、Emacs 19.2x 以前用、
rubydb3x.el
は、Emacs 19.3x 以降用です。
$ ruby -rdebug foo.rb
または、Emacs から
M-x load-library rubydb3x.el M-x rubydb
以下は、デバッガで使用できるコマンド名とその用法の一覧です。各コマンド 名には省略形があります。
ここに挙げたもの以外を入力した場合、その入力を ruby の式として評価します。
ブレークポイントを設定します。引数を省略した場合設定したブレークポ イントを表示します。
設定するブレークポイントの書式は プログラムファイル名:位置 です。 位置 はファイル中の行番号もしくはメソッド名で指定します。 ファイル名: を省略した場合は現在実行中のファイルを指定した ものと見倣されます。
このコマンドの省略形は b
です。
例外が発生した時にデバッガを停止させるキャッチポイントを設定します。 引数を省略した場合設定したキャッチポイントを表示します。
発生した例外が <an Exception> のサブクラスであれば デバッガが停止します。デフォルトのキャッチポイントは StandardErrorに設定されています。
<an Exceptionとして off を指定すると 例外発生時に停止しなくなります。
このコマンドの省略形は cat
です。
式 <expression> の値が変化したときに停止するウォッ チポイントを設定します。
このコマンドの省略形は wat
です。
指定したブレークポイントを取り除きます。引数を省略した場合すべての ブレークポイントを取り除きます。
このコマンドの省略形は del
です。
処理が停止するごとに <expression> を評価するディス プレイ式を設定します。 引数を省略した場合すべてのディスプレイ式を表示します。
このコマンドの省略形は disp
です。
指定したディスプレイ式を取り除きます。引数を省略した場合すべての ディスプレイ式を取り除きます。
このコマンドの省略形は undisp
です。
スクリプトが終了するまで、もしくは次のブレークポイントに到達するま で処理を続行します。
このコマンドの省略形は c
です。
一行ずつ処理を実行します。引数を指定した場合、指定した行数分、処理を 続行します。メソッドの中に入ります。
このコマンドの省略形は s
です。
一行ずつ処理を実行します。引数を指定した場合、指定した行数分、処理を 続行します。step [nnn]との違いは、メソッド呼び出しのところでそのメ ソッドの中に入らないことです。
このコマンドの省略形は n
です。
フレームのスタックと、現在のフレーム位置を表示します。
このコマンドの省略形は w
または f
です。
スクリプトを表示します。引数が `-' ならば前の行を表示します。 nn-mm の形式では指定した範囲の行のスクリプトを表示します。
このコマンドの省略形は l
です。
上位のフレームに上がります。
下位のフレームに下がります。
外側のフレームに上がるまで処理を続行します。
このコマンドの省略形は fin
です。
トレースモードの設定を変更します。トレースモードをonにすると、以後 の実行においてメソッドの呼び出し関係が表示されます。引数を省略した 場合現在のモードを表示します。
このコマンドの省略形は tr
です。
スクリプトを中断し、デバッガを終了します。
このコマンドの省略形は q
です。
それぞれ、グローバル変数、ローカル変数、オブジェクト<object>の インスタンス変数、<object>の定数を表示します。
このコマンドの省略形は v
です。
それぞれ、オブジェクト<object>のインスタンスメソッド クラスメソッド または モジュールメソッドを表示します。
このコマンドの省略形は m
です。
スレッドの一覧を表示します。
このコマンドの省略形は th
です。
現在のスレッドを表示します。
スレッド <nnn> を停止します。
スレッド <nnn> を再開します。
ruby の式 <expression> の結果を表示します。
デバッグコマンドの一覧を表示します。
このコマンドの省略形は h
です。
実行トレース出力をとる機能を提供する。
使い方は大きく分けて2通り。
hoge.rbの実行をすべてトレース出力する。
require 'tracer'
Tracer.on
によりトレース出力を有効にする。
Tracer.off
によりトレース出力を無効にする。
また、ブロック付きで Tracer.on
を呼び出すと、そのブロック内のみ
トレースを出力する。
なし
Tracer.on
Tracer.on {...}
トレース出力を開始。 ブロックを与えられた場合はそのブロック内のみトレース出力を行う。
Tracer.off
トレース出力を中断。
Tracer.set_get_line_procs(filename, proc)
Tracer.set_get_line_procs(filename) { |line| ...}
あるファイルについて利用する、行番号からソースのその行の内容を返す 手続きを指定する。何も指定しなければデフォルトの動作が利用される。 指定する手続きは行番号を唯一の引数として呼び出される。
Tracer.add_filter(proc)
Tracer.add_filter { |event,file,line,id,binding| ...}
トレース出力するかどうかを決定するフィルタを追加する。 何もフィルタを与えない場合はすべての行についてトレース情報が出力される。 与えられた手続き(ブロックまたはProcオブジェクト)が真を返せば トレースは出力される。 フィルタは複数追加でき、そのうち一つでも偽を返すとトレースの出力は 抑制される。 フィルタ手続きは引数として event,file,line,id,binding の5つ をとる(組み込み関数set_trace_funcで指定するものとほぼ同じ)。 set_trace_funcに関してはRuby本 p.391を参照。
Ruby本 p.391より。
イベントを表す文字列。
以下の種類がある。カッコ内はtracer.rbの出力での表記。
ある行を実行
メソッド呼び出し
メソッドからのリターン
クラスコンテキストに入った
クラスコンテキストから出た
例外が発生した
Cで記述されたメソッドが呼ばれた
Cで記述されたメソッドからreturn
現在処理しているファイルの名前
現在処理している行番号
最後に呼び出されたメソッドのメソッド名(のシンボル) そのようなメソッドがなければ0になる。
現在のコンテキスト
Ruby プログラムのためのプロファイラです。プロファイラとは効率改善のた めの調査に用いられるツールのことで、profile.rbは各メソッドの実行時間に 関する統計を出力します。
$ ruby -r profile foo.rb
実行が終ると標準出力にプロファイルを出力します。
プロファイルは各メソッドの実行時間に関する統計からなりますが、この時間 には大きく分けて2種類あります。ひとつは、メソッドが呼び出されてから返 るまでの時間です。もうひとつは、全体の時間からそのメソッド内で行なわれ た他の呼び出しに費やしたすべての時間を引いた時間です。以下の説明では前 者を全体時間、後者を正味時間と呼ぶことにします。
プロファイルの結果は例えば次のようになります。
$ ruby -r profile sample/sieve.rb 1000 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47 … 略 … % cumulative self self total time seconds seconds calls ms/call ms/call name 33.87 1.49 1.49 11 135.65 214.49 Fixnum#step 31.38 2.88 1.38 2410 0.57 0.57 Array#[]= 27.84 4.10 1.23 2 613.28 2070.31 Range#each 4.26 4.29 0.19 1 187.50 234.38 Array#join 1.06 4.34 0.05 168 0.28 0.28 Fixnum#to_s 0.35 4.35 0.02 31 0.50 0.50 Fixnum#+ … 以下略 …
おのおのの行に現れる各フィールドの意味は左から順に次の通りです。
trap されていないシグナル(signal(2) 参照)を受け取ったときに発生します。
実際に発生したシグナル名は、
SignalException#message から
"SIGname
"という形で得られます。
デフォルトの状態では、以下のシグナルが SignalException
を発生さ
せます。
SIGHUP, SIGQUIT, SIGALRM, SIGUSR1, SIGUSR2
また、SIGINT
は 例外 Interrupt を発生させます。
このマニュアルでは、`$'で始まる変数を「グローバル変数」と呼んでいますが *73 組み込みの変数(これらは特殊な機能と用途を持ちます)の中にはその有効なス コープがグローバルとは限らない場合があります(どこでも使えるという意味で はグローバルですが、その値はグローバルとは限りません)。ここでは、変数の 値のスコープで大別してグローバル変数の一覧を列挙します。
以下の変数はスレッドローカルでもあります。
$_
最後に gets
または readline
で読み込んだ文字列。
EOF に達した場合には、nil。この変数はローカルスコープです。
(覚え方: Perlと同じ)
$&
現在のスコープで最後に成功した正規表現のパターンマッチでマッチした
文字列。最後のマッチが失敗していた場合には nil
。
(覚え方: いくつかのエディタでの &
と同じ)
Regexp.last_match[0] と同じ。
$~
現在のスコープで最後に成功したマッチに関する情報(MatchData
オブジェクト)。これを設定すると $&
や $1 ... $9
などの
値が変化します。
このデータから n 番目のマッチ($n)を取り出すためには $~[n]
で
参照できます。
(覚え方: ~ はマッチに使われる)
Regexp.last_match と同じ。
$`
現在のスコープで最後に成功した正規表現のパターンマッチでマッチした
部分より前の文字列。最後のマッチが失敗していた場合には nil
。
(覚え方: `
は文字列の前に置かれる)
$'
現在のスコープで最後に成功した正規表現のパターンマッチでマッチした
部分より後ろの文字列。最後のマッチが失敗していた場合には nil
。
(覚え方: '
は文字列の後ろに置かれる)
$+
現在のスコープで最後に成功した正規表現のパターンマッチでマッチした
中で最後の括弧に対応する部分文字列。
最後のマッチが失敗していた場合には nil
。
いくつかある選択型のパターンのどれがマッチしたのか分からない時に便利
(覚え方: be positive and forward looking.)
$1
$2
$3 ...
最後に成功したパターンマッチでn番目の括弧にマッチした値が格
納されます。該当する括弧がなければnil
が入ってい
ます。(覚え方: \数字 のようなもの)
Regexp.last_match[1], Regexp.last_match[2], ... と同じ。
以下の変数は一つのスレッド内ではグローバルスコープですが、スレッド間で は独立しています。
$?
このスレッドで最後に終了した子プロセスのステータス。 1.6 以前は整数で 1.7 からは Process::Status オブジェクトです。 Process#wait なども参照。
整数値として評価した値は wait()
システムコールで得られる値そ
のものなので、子プロセスのexit statusを得るには 1/256 します($?/256
)。
1.7以降なら
Process::Status#exitstatus も使え
ます。
$!
最近の例外に関する情報。raise によって設定されま す。
$@
例外が発生した時バックトレースが配列として格納されます。 配列の各要素はメソッドの呼び出し位置を示す文字列で形式は
"filename:line"
または
"filename:line:in `methodname'"
です。 (覚え方: where exception occurred at.)
$SAFE
カレントスレッドのセーフレベル。セーフレベルについては セキュリティモデルを参照してください。
$=
パターンマッチや文字列の比較でアルファベットの大文字小文字を 区別するかどうかのフラグ。デフォルトはnil。(覚え方: = は比較 に使われる)*74
$/
入力レコードセパレータ。デフォルトは "\n"
。
awk
のRS変数のように働きます。
この変数に nil を設定するとファイル全体を一度に読み込みます。 空文字列 "" を設定するとパラグラフモードとみなされ、2つ以上連続した 改行がレコードの区切りになります。
$/
には正規表現は使えません。(覚え方: 詩では / を行の区切りに使う)
$\
出力レコードセパレータ。この変数に文字列を指定すると
printの度に最後にこの文字列を付加して出力します。
デフォルトはnil
でこの場合なにも追加しません。
(覚え方: It's just like /, but it's what you get "back" from Ruby.)
$,
Array#joinのデフォルトの区切り文字列。 printの各引数の間に出力される文字列。
(覚え方: print で , があるところで出力される)
$;
String#split のデフォルトの区切り文字。デフォル
トはnil
で、この場合特殊な分割を行います。詳細は
String#split を参照。
$.
最後に読んだ入力ファイルの行番号。
ARGF.lineno と同じ。各引数ファイル毎の行番号が必要な場合は ARGF.file.lineno を使用します。
$<
引数(なければ標準入力)で構成される仮想ファイル。つまり
定数 ARGF の別名。
(覚え方: <
はシェルの入力元指定)
$>
$defout
組込み関数 print、puts や
p などのデフォルトの出力先。初期値は
STDOUT。
-i オプションを指定した場合には読み
込み元と同じ名前のファイル。
(覚え方: >
はシェルの出力先指定)
この変数には、 write
という名前のメソッドが定義されたオブジェ
クトだけしか代入できません(print 等の組込みのメソッドは、最終的に
write メソッドを呼ぶようになっています)。
print 等の Ruby の組込み関数の出力先を変更するにはこの変数の値を別 の IO に再設定すればよいですが、サブプロセスや C による拡張 ライブラリの標準出力までも変更したい場合には IO#reopen や、$stdout によって標 準出力を別の IO にリダイレクトする必要があります。
$0
現在実行中のRubyスクリプトの名前。OSによってはこの変数に代入すると ps(1) の出力が変化します。この機能はプログラムの 現在の状態を表示するのに便利です。(覚え方: sh や kshと同じ)
$*
Rubyスクリプトに与えられた引数。定数ARGVの別名。 Ruby自身に対する引数は取り除 かれています。(覚え方: sh や kshと同じ)
$$
現在実行中のRubyプロセスのpid。(覚え方: シェルと同じ)
Process.pid と同じ。
$:
loadや require がファイルをロードする時に検索するディレクトリのリストを含む 配列。 $LOAD_PATH の別名。 (覚え方: コロンは環境変数PATHの区切り文字である)
起動時には、-I オプションで指定した ディレクトリ、環境変数 RUBYLIB の値、デフォルト値 (コンパイル時に指定する、多くの場合 "/usr/local/lib/ruby" *75)、"."(カレントディレクトリ)を値として持ちます。
-I で指定したパス 環境変数 RUBYLIB の値 /usr/local/lib/ruby/site_ruby/VERSION サイト固有、バージョン依存のライブラリ /usr/local/lib/ruby/site_ruby/VERSION/ARCH サイト固有、システム依存、拡張ライブラリ /usr/local/lib/ruby/site_ruby サイト固有ライブラリ /usr/local/lib/ruby/VERSION 標準ライブラリ /usr/local/lib/ruby/VERSION/ARCH 標準、システム依存、拡張ライブラリ . カレントディレクトリ
*76 上記で VERSION は、1.6, 1.7 等になります。ARCH は、マシン、OSを表す Config::CONFIG['arch']の値です。
require 'foo'
としたとき foo は以下のように .rb, .so を交互
に探索します。(".so" は、共有ライブラリの拡張子で実際にはシステム
依存です。例えば、HP-UX では、require 'foo.so' とすれば、foo.sl を
探します)
/usr/local/lib/ruby/site_ruby/VERSION/foo.rb /usr/local/lib/ruby/site_ruby/VERSION/foo.so /usr/local/lib/ruby/site_ruby/VERSION/ARCH/foo.rb /usr/local/lib/ruby/site_ruby/VERSION/ARCH/foo.so : :
なお、そのロードパスをコマンドラインから調べるには
$ ruby -e'puts $:'
とします。
$"
require でロードされたファイル名を含む配列。 require で同じファイルを2回ロードしないために 用いられています。 (覚え方: prevent files to be doubly quoted(loaded))
$DEBUG
この値が真であればデバッグモードになります。 -d オプションでセットされます。
デバッグモードでは、通常の実行と以下の違いがあります。
いずれかのスレッドが例外によって終了した時に、インタプリタ全体 を中断します。Thread.abort_on_exception を true にセットした時と同じ効果がありますが、デバッグモードでは、スク リプト中で abort_on_exception= クラスメソッドによってフラグをリ セットしても、この効果をなくすことはできません。
通常の実行では、あるスレッドで起こった例外は、 Thread#join などで検出されない限り、そのスレッドだ けをなにも警告を出さずに終了させます。
$FILENAME
仮想ファイル ARGF で現在読み込み中の(メソッド gets が今読んでいる)ファイル名。ARGF.filename と同じ。
$LOAD_PATH
$:の別名。
$stdin
$stdout
$stderr
標準入力、標準出力、標準エラー出力。
これらへの代入はリダイレクトになります。*77
$VERBOSE
冗長メッセージフラグ。Rubyインタプリタへの -vオプションでセットされます。
$KCODE
Rubyの処理する文字コード。 文字列で指定し、文字列の先頭が `E' また は `e' の場合は文字列やアクセスするファイルの内容のコードが EUC で あると仮定します。同様に `S' または `s' の場合は SJIS として処理し ます。`U' または `u' の場合は UTF-8 として処理します。`N' または `n' の場合は漢字を処理しません。デフォルトは `NONE' です。
Ruby インタプリタのコマンドライン情報を示す一連の変数があります。
形式は $-?
で ? の部分にオプションの一文字が入ります。
$-0
$/ の別名。
$-a
-a が指定されている時、真。リードオ ンリー変数。
$-d
$DEBUG の別名。
$-F
$; の別名。
$-i
-i が指定されている時、拡張子を表す
文字列を格納します。指定されていない時の値は nil
です。スクリ
プト内で代入することもでき、その場合は ARGV の次の
ファイルを読み込み始めるタイミングで in-place 置換を開始します。
$-I
$LOAD_PATH の別名。
$-K
$KCODE の別名。
$-l
-l が指定されている時、真。リードオ ンリー変数。
$-p
-p が指定されている時、真。リードオ ンリー変数。
$-v
$-w
$VERBOSE の別名。
正規表現のクラス。正規表現のリテラルはスラッシュで囲んだ形式 で生成します。
/^this is regexp/
Regexp.new(string)
を使って正規表現オブジェクトを動的に生成する
こともできます。
Regexp.compile(string[, option[, code]])
Regexp.new(string[, option[, code]])
文字列をコンパイルして正規表現オブジェクトを生成して返します。第 2 引数が与えられて、その値が真であれば、生成された正規表現はアルファ ベットの大文字小文字を区別しません。第 2 引数が整数であった場合、 その値は Regexp::IGNORECASE、 Regexp::MULTILINE、 Regexp::EXTENDED の論理和でなければなりません。
第 3 引数が与えられた時には、$KCODE の値にかかわ
らず、指定された文字コードでマッチを行います。文字コードは
$KCODE
への代入と同様に文字列引数の最初の一文字で決定されま
す。
第 1 引数が正規表現であれば内容が同じ(ただし、上記フラグの内容はク リアされた)正規表現を複製して返します。このとき、複製した正規表現 に対して、第 2、第 3 引数の指定が設定されます。
正規表現のコンパイルに失敗した場合、例外 RegexpError が発生 します。
Regexp.escape(string[,kcode])
Regexp.quote(string[,kcode])
string の中で正規表現において特別な意味を持つ文字の直前にエ スケープ文字(バックスラッシュ)を挿入した文字列を返します。省略可能 な引数 kcode で文字列の文字コードを指定します (省略時は $KCODE の値が使用されます)。
文字コードの指定は $KCODE
と同様に行います。
Regexp.last_match
カレントスコープで最後に行った正規表現マッチの MatchData オ ブジェクトを返します。このメソッドの呼び出しは $~ の参照と同じです。
/(.)(.)/ =~ "ab" p Regexp.last_match # => #<MatchData:0x4599e58> p Regexp.last_match[0] # => "ab" p Regexp.last_match[1] # => "a" p Regexp.last_match[2] # => "b" p Regexp.last_match[3] # => nil
Regexp.last_match([nth]) ((<ruby 1.7 feature>))
整数 nth が 0 の場合、マッチした文字列を返します
($&)。それ以外では、nth 番目の括弧にマッチ
した部分文字列を返します($1,$2,...)。
対応する括弧がない場合やマッチしなかった場合には nil
を返し
ます。
/(.)(.)/ =~ "ab" p Regexp.last_match # => #<MatchData:0x4599e58> p Regexp.last_match(0) # => "ab" p Regexp.last_match(1) # => "a" p Regexp.last_match(2) # => "b" p Regexp.last_match(3) # => nil
正規表現全体がマッチしなかった場合、引数なしの
Regexp.last_match
はnil
を返すため、
last_match[1]
の形式では例外 NameError が発生します。
対して、last_match(1)
は nil
を返します。
self =~ string
self === string
マッチする場合、マッチした位置のインデックスを返します(先頭は0)。
マッチしなかった場合 nil
を返します。
~ self
変数 $_
の値との間でのマッチをとります。ちょうど以下と同じ意
味です。
self =~ $_
casefold?
正規表現が大文字小文字の判定をしないようにコンパイルされている時、 真を返します。
kcode
その正規表現が対応するようにコンパイルされている文字コードを
$KCODE と同じ形式で返します。もし、正規表現が固定
コードに対してコンパイルされていない(マッチ時点での $KCODE
の値を用いる)場合には、nil を返します。
match(str)
MatchData オブジェクトを返す点を除いて、self =~ str
と
同じです。
正規表現にマッチした部分文字列だけが必要な場合に、
bar = /foo(.*)baz/.match("foobarbaz").to_a[1] foo, bar, baz = /(foo)(bar)(baz)/.match("foobarbaz").to_a.indexes(1,2,3)
のように使用できます。(to_a は、マッチに失敗した場合を考慮しています。)
ruby 1.7 feature:
MatchData には、to_ary メソッドが定義されて
いるので上記の例は以下のように書くこともできます。(ここでの
`_
' は、$& を捨てるために適当に選んだ変数名)
_, foo, bar, baz = /(foo)(bar)(baz)/.match("foobarbaz")
options ((<ruby 1.7 feature>))
正規表現の生成時に指定されたオプションを返します。戻り値は、
Regexp::EXTENDED
, Regexp::IGNORECASE
,
Regexp::MULTILINE
の論理和です。
p Regexp::IGNORECASE # => 1 p //i.options # => 1
source
その正規表現のもととなった文字列表現を生成して返します。
EXTENDED
バックスラッシュでエスケープされていない空白と # から改行までを無
視します。正規表現リテラル の //x オプションと同じ
です。(空白を入れる場合は\
でエスケープして\ (<-空白)
と
指定します)
IGNORECASE
文字の大小の違いを無視します。 正規表現リテラル の //i オプションと同じです。
MULTILINE
複数行モード。正規表現 "." が改行にマッチするようになります。 正規表現リテラル の //m オプションと同じです。
正規表現のマッチに関する情報を扱うためのクラス。 このクラスのインスタンスは、
などにより得られます。
self[n]
n 番目の部分文字列を返します。0 はマッチ全体を意味します。
n の値が負の時には末尾からのインデックスと見倣します(末尾の
要素が -1 番目)。n 番目の要素が存在しない時には nil
を
返します。
/(foo)(bar)(BAZ)?/ =~ "foobarbaz" p $~.to_a # => ["foobar", "foo", "bar", nil] p $~[0] # => "foobar" p $~[1] # => "foo" p $~[2] # => "bar" p $~[3] # => nil (マッチしていない) p $~[4] # => nil (範囲外) p $~[-2] # => "bar"
self[start..end]
Array#[start..end] と同じです。
/(foo)(bar)/ =~ "foobarbaz" p $~[0..2] # => ["foobar", "foo", "bar"]
self[start, length]
Array#[start, length] と同じです。
/(foo)(bar)/ =~ "foobarbaz" p $~[0, 3] # => ["foobar", "foo", "bar"]
begin(n)
n 番目の部分文字列先頭のオフセットを返します。0 はマッチ全体
を意味します。n が範囲外の場合は例外 IndexError が発生
します。n 番目の部分文字列がマッチしていなければ nil
を返します。
/(foo)(bar)(BAZ)?/ =~ "foobarbaz" p $~.begin(0) # => 0 p $~.begin(1) # => 0 p $~.begin(2) # => 3 p $~.begin(3) # => nil p $~.begin(-1) # => `begin': index -1 out of matches (IndexError)
end(n)
n 番目の部分文字列終端のオフセットを返します。0 はマッチ全体
を意味します。n が範囲外の場合は例外 IndexError が発生
します。n 番目の部分文字列がマッチしていなければ nil
を返します。
/(foo)(bar)(BAZ)?/ =~ "foobarbaz" p $~.end(0) # => 6 p $~.end(1) # => 3 p $~.end(2) # => 6 p $~.end(3) # => nil p $~.end(-1) # => `end': index -1 out of matches (IndexError)
length
size
部分文字列の数を返します(self.to_a.size と同じです)。
/(foo)(bar)(BAZ)?/ =~ "foobarbaz" p $~.size # => 4
offset(n)
n 番目の部分文字列のオフセットの配列 [start, end]
を返
します。
[ self.begin(n), self.end(n) ]
と同じです。n番目の部分文字列がマッチしていなければ
[nil, nil]
を返します。
post_match
マッチした部分より後ろの文字列を返します($'と同じ)。
/(bar)(BAZ)?/ =~ "foobarbaz" p $~.post_match # => "baz"
pre_match
マッチした部分より前の文字列を返します($`と同じ)。
/(bar)(BAZ)?/ =~ "foobarbaz" p $~.pre_match # => "foo"
select(index1, index2, ...) ((<ruby 1.7 feature>))
正規表現中のindexN 番目の括弧にマッチした部分文字列の配列を返しま す。0 番目は $& のようにマッチした文字列全体を表 します。
m = /(foo)(bar)(baz)/.match("foobarbaz") p m.select(0,1,2,3,4) # same as m.to_a.indexes(...) p m.select(-1,-2,-3) => ["foobarbaz", "foo", "bar", "baz", nil] ["baz", "bar", "foo"]
string
マッチ対象になった文字列の複製を返します。返す文字列はフリーズ (Object#freeze)されています。
to_a
to_ary ((<ruby 1.7 feature>))
/(foo)(bar)(BAZ)?/ =~ "foobarbaz" p $~.to_a # => ["foobar", "foo", "bar", nil]
to_s
マッチした文字列全体を返します。
/bar/ =~ "foobarbaz" p $~ # => #<MatchData:0x401b1be4> p $~.to_s # => "bar"
Process.wait などで生成されるオブジェクト。プロセスの終 了ステータスを表現します。
self == other
同じステータスの場合に真を返します。
other が数値の場合、self.to_i
との比較が行われます。こ
れは後方互換性のためです。
self & other
to_i & other
と同じです。
このメソッドは後方互換性のためにあります。
to_i
C 言語での終了ステータス表現の整数を返します。
多くのシステムの実装では、この値の上位 8 bit に exit(2) に渡した終了ステータスが、下位 8 bit にシグナル等で終了した等の情 報が入っています。
to_int
to_i
と同じです。このメソッドにより $?
が Fixnum
として扱われるようになります(暗黙の型変換)。これは後方互換性のため
です。
fork { exit 1 } Process.wait p $? # => 256
to_s
to_i.to_s
と同じです。
exited?
プロセスが exit(2) により自分で終了した(他のプロ セスに止められたのではない)場合、真を返します。
exitstatus
exited?
が真の場合プロセスが返した終了ステータスの整数を、そ
うでない場合は nil
を返します。
stopped?
プロセスが現在停止(終了ではない)している場合に真を返します。
Process.waitpid
に Process::WUNTRACED
フラグを設定した
場合にだけ真になりえます。
stopsig
stopped?
が真の場合そのシグナルの番号を、そうでない場合は
nil
を返します。
signaled?
プロセスがハンドラを定義していないシグナルを受けて終了した場合に真 を返します。
termsig
signaled?
が真の場合プロセスを終了させたシグナル番号を、
そうでない場合は nil
を返します。
coredump?
終了時にコアダンプしていたら真を返します。
wait を使用した例
fork { exit } pid = Process.wait case when $?.signaled? p "child #{pid} was killed by signal #{$?.termsig}" when $?.stopped? # 実際には Process.wait を使用しているので、ここに来ることはない p "child #{pid} was stopped by signal #{$?.stopsig}" when $?.exited? p "child #{pid} exited normaly. status=#{$?.exitstatus}" when $?.coredump? # システムがこのステータスをサポートしてなければ常にfalse p "child #{pid} dumped core." else p "unknown status %#x" % $?.to_i end
SIGCHLD を trap する例
trap(:SIGCHLD) {|sig| puts "interrupted by signal #{sig} at #{caller[1]}" # 複数の子プロセスの終了に対して1つの SIGCHLD しか届かない # 場合があるのでループさせる必要があります while pid = Process.waitpid(-1, Process::WNOHANG|Process::WUNTRACED) case when $?.signaled? puts " child #{pid} was killed by signal #{$?.termsig}" when $?.stopped? puts " child #{pid} was stopped by signal #{$?.stopsig}" when $?.exited? puts " child #{pid} exited normaly. status=#{$?.exitstatus}" when $?.coredump? puts " child #{pid} dumped core." else p "unknown status %#x" % $?.to_i end end } p pid1 = fork { sleep 1; exit } p pid2 = fork { loop { sleep } } # signal を待つための sleep begin Process.kill :STOP, pid2 sleep # SIGCHLD を待つための sleep Process.kill :CONT, pid2 Process.kill :TERM, pid2 loop { sleep } # SIGCHLD を待つための sleep rescue Errno::ECHILD puts "done" end => 12964 12965 interrupted by signal 17 at -:27:in `sleep' child 12965 was stopped by signal 19 interrupted by signal 17 at -:30:in `sleep' child 12965 was killed by signal 15 interrupted by signal 17 at -:30:in `sleep' child 12964 exited normaly. status=0 done
UNIX のプロセスを管理するモジュール。Process.exit!, Process.fork 以外のメソッドは全てモジュール関数 (Module#module_function)です。
Process
がプロセスを表現するクラスではなく、プロセスに対する操作
をまとめたモジュールであることに注意してください。
Process.egid
カレントプロセスの実効グループ ID を返します。
Process.egid=gid
カレントプロセスの実効グループ ID を設定します。gid を返します。
Process.euid
カレントプロセスの実効ユーザ ID を返します。
Process.euid=uid
カレントプロセスの実効ユーザ ID を設定します。uid を返します。
Process.gid
カレントプロセスの実グループ ID を返します。
Process.gid=gid
カレントプロセスの実グループ ID を設定します。gid を返します。
Process.pid
カレントプロセスのプロセス ID を返します。変数 $$ の値と同じです。
Process.ppid
親プロセスのプロセス ID を返します。UN*X では実際の親プロセスが終
了した後は ppid
は 1 (init
の pid)になります。
Process.uid
プロセスの実ユーザ ID を返します。
Process.uid=uid
プロセスの実ユーザ ID を設定します。uid を返します。
Process.getpgid(pid)
Process.getpgrp([pid])
pid のプロセスのプロセスグループを返します。pid が 0 の時や省略された時はカレントプロセスを意味します。
プロセスグループの取得に失敗した場合は、例外 Errno::EXXX が 発生します。 *78。
Process.getpriority(which, who)
プロセス、プロセスグループ、ユーザの現在のプライオリティを返 します(getpriority(2) 参照)。
Process
モジュールは which として指定できる定数
PRIO_PROCESS, PRIO_PGRP,
PRIO_USER を定義しています。
who には、which の値にしたがってプロセス ID、プロセス グループ ID、ユーザ ID のいずれかを指定します。
プライロリティの取得に失敗した場合は、例外 Errno::EXXX が発 生します。
Process.kill(signal, pid ... )
pid で指定されたプロセスにシグナルを送ります。signal
はシグナル番号か名前(文字列またはSymbol)で指定します。負の値
を持つシグナル(あるいはシグナル名の前に-
)を与えるとプロセス
ではなくプロセスグループにシグナルを送ります。
全てのシグナル送信に成功した場合、指定した pid の数を返します。 失敗した場合は例外 Errno::EXXX が発生します。
Process.setpgrp(pid, pgrp)
Process.setpgrp ((<ruby 1.7 feature>))
Process.setpgid(pid, pgrp)
pid のプロセスグループを設定します。pid が 0 の時はカ レントプロセスを意味します。
プロセスグループの設定に成功した場合は 0 を返します。失敗した場合 は、例外 Errno::EXXX が発生します。
ruby 1.7 feature: version 1.7 では、Process.setpgrp は、引数を取りません。 *79。
Process.setpriority(which, who, prio)
プロセス、プロセスグループ、ユーザの現在のプライオリティを設 定します(setpriority(2) 参照)。
Process
モジュールは which として指定できる定数
PRIO_PROCESS, PRIO_PGRP,
PRIO_USER を定義しています。
who には、which の値にしたがってプロセス ID、プロセス グループ ID、ユーザ ID のいずれかを指定します。
prio には、-20 から 20 の値を設定します。
プライロリティの設定に成功した場合は 0 を返します。失敗した場合は、 例外 Errno::EXXX が発生します。
Process.setsid()
新しいセッションを作成して、tty を切り離します。デーモンを簡単に作 ることができます。セッション ID を返します。
セッション ID の作成に失敗した場合は、例外 Errno::EXXX が発 生します。
Process.times ((<ruby 1.7 feature>))
自身のプロセスとその子プロセスが消費したユーザ/システム CPU 時間の
積算を Struct::Tms のオブジェクトとして返します。
Struct::Tms
は以下のメンバを持つ構造体クラスです。
utime # user time stime # system time cutime # user time of children cstime # system time of children
時間の単位は秒で、浮動小数点数で与えられます。詳細は times(3) を参照してください。
Process.wait
Process.wait2
子プロセスが終了するのを待ち、終了した子プロセスの pid を返します。 子プロセスが一つもなければ例外 Errno::ECHILD が 発生します。
wait2
は、その戻り値が pid と $? の配列であ
る点だけが異なります。
ruby 1.7 feature:
version 1.7 からは $?
はProcess::Status オブジェクトで
す。
Process.waitall ((<ruby 1.7 feature>))
全ての子プロセスが終了するのを待ちます。
終了した子プロセスの pid と終了ステータス(Process::Status)の 配列を要素に持つ配列を返します。子プロセスがいない状態でこのメソッ ドを呼び出すと空の配列を返します。
$? には最後に終了した子プロセスの終了ステータスが 設定されます。
例:
3.times {|n| Process.fork() { exit n } } p ret = Process.waitall p ret[-1][1] , ret[-1][1].type p $? , $?.type => [[5245, 256], [5244, 0], [5243, 512]] 512 Process::Status 512 Process::Status
Process.waitpid(pid[, flags])
Process.waitpid2(pid[, flags])
pid で指定される特定の子プロセスの終了を待ち、そのプロセスが
終了した時に pid
を返します。子プロセスが存在しなければ例外
Errno::ECHILD が発生します。
flags には、Process
モジュールの定数
WNOHANG(ノンブロッキングモード)と
WUNTRACED の論理和を指定します。省略したときの値は 0
です。
ノンブロッキングモードで子プロセスがまだ終了していない時には
nil
を返します。waitpid(2) か
wait4(2) の実装されていないマシンでは
flags はいつも nil
または 0 を指定する必要があります。
waitpid2
は、その戻り値が pid と $? の配列
である点だけが異なります。
ruby 1.7 feature:
version 1.7 からは $?
は Process::Status オブジェクト
です。
PRIO_PROCESS
Process.getpriority または Process.setpriority のプロセスプライオリティ指定。
PRIO_PGRP
プロセスグループプライオリティ。
PRIO_USER
ユーザプライオリティ。
WNOHANG
Process#waitpid の第二引数に指定するフラグで
す。終了した子プロセスがない時に waitpid
がブロックしません。
WUNTRACED
Process#waitpid の第二引数に指定するフラグで
す。子プロセスの停止によりステータスを報告していない子プロセスがあ
る時に waitpid
がブロックしません。
Status ((<ruby 1.7 feature>))
プロセスの終了ステータスを表現するクラスです。 Process::Status を参照してください。
Ruby インタプリタ作成時に設定された情報を格納したモジュールです。
Config.expand(val)
DESTDIR
TOPDIR
CONFIG
設定値を格納したハッシュです。以下のキーと値を持ちます。
Ruby をコンパイルしたソースディレクトリ
Ruby のインストール先の基準ディレクトリ
ruby インタプリタのファイル名
実行ファイルの拡張子
シェルのパス名
C コンパイラのオプション
C プリプロセッサのオプション
C++ コンパイラのオプション
Fortran コンパイラのオプション
リンカオプション
ライブラリ
アーキテクチャ依存の実行ファイルのインストール先ディレクトリ
実行ファイルのインストール先ディレクトリ
管理者用実行ファイルのインストール先ディレクトリ
他のプログラムから実行される実行ファイルのインストール先ディレクトリ
アーキテクチャに依存しないデータのインストール先ディレクトリ
Ruby の major バージョン番号(1.6.5の1)
Ruby の minor バージョン番号(1.6.5の6)
Ruby の teeny バージョン番号(1.6.5の5)
実行するシステムの情報 (?)
例: C:\>ruby -vrrbconfig -e "p Config::CONFIG['host']" ruby 1.6.6 (2001-12-26) [i386-mingw32] "i686-pc-cygwin"
生成されたコードを実行するシステムの情報
例: C:\>ruby -vrrbconfig -e "p Config::CONFIG['host']" ruby 1.6.6 (2001-12-26) [i386-mingw32] "i386-pc-mingw32"
ビルドしたシステムの情報
C:\>ruby -vrrbconfig -e "p Config::CONFIG['host']" ruby 1.6.6 (2001-12-26) [i386-mingw32] "i586-pc-linux-gnu"
ビルドに使われた C コンパイラ
ビルドに使われた C プリプロセッサ
ビルドに使われた コンパイラコンパイラ
ビルドに使われたライブラリ操作コマンド (?)
Windows のリソース操作コマンド
シンボリックリンク作成コマンド
オブジェクトファイル(コンパイルだけされてリンク前のファイル)の拡張子
ruby本体にリンクされているオブジェクトファイル (?)
ダイナミックリンクライブラリの拡張子
オブジェクトファイルからシンボルを切り捨てるコマンド
ビルド途中に作成される機能限定版rubyのcompile_dirからの相対パス
ruby共有ライブラリの名前
configureで--enable-sharedだったかどうか(値は"yes"または"no") (?)
rubyのバージョン(例:"1.6")
MAKEFILE_CONFIG
CONFIG と同じですが、その値は以下のような形 で他の変数への参照を含みます。
MAKEFILE_CONFIG["bindir"] = "$(exec_prefix)/bin"
これは、Makefile の変数参照の形式で MAKEFILE_CONFIG は、 Makefile 作成の際に利用されることを想定しています。
require 'rbconfig' print <<-END_OF_MAKEFILE prefix = #{Config::MAKEFILE_CONFIG['prefix']} exec_prefix = #{Config::MAKEFILE_CONFIG['exec_prefix']} bindir = #{Config::MAKEFILE_CONFIG['bindir']} END_OF_MAKEFILE => prefix = /usr/local exec_prefix = $(prefix) bindir = $(exec_prefix)/bin
Config.expand は、このような参照を解決する メソッドとして rbconfig.rb 内部で利用されています。 (CONFIG 変数は、MAKEFILE_CONFIG の内容から Config.expand を使って生成されています)
require 'rbconfig' p Config.expand(Config::MAKEFILE_CONFIG["bindir"]) # => "/usr/local/bin"
TRUE
代表的な真の値。true
と同じ。Ruby では偽でない値(false
でも nil
でもない値)は全て真とみなされます。
(obsoleteも参照してください。)
FALSE
偽の値。false
と同じ。
(obsoleteも参照してください。)
NIL
nil
と同じ。
(obsoleteも参照してください。)
STDIN
標準入力。$stdin のデフォルト値。
STDOUT
標準出力。$stdout のデフォルト値。
STDERR
標準エラー出力。$stderr のデフォルト値。
ENV
環境変数を表す(疑似)連想配列(詳細は ENV を参照)。この連想配 列の値を変更すると子プロセスの環境として引き継がれます。
ARGF
引数(なければ標準入力)で構成される仮想ファイル (詳細は ARGF を参照)。つまり gets は ARGF.gets と同 じ意味です。ARGF.file で現在読み込み中のファイルオブジェ クトが、ARGF.filename で現在読み込み中のファイル名が得 られます。
ARGV
$* と同じ
DATA
スクリプトの __END__
(スクリプトの終り)
以降をアクセスする File オブジェクト。
注意:
TOPLEVEL_BINDING
トップレベルでの Binding オブジェクト。
RUBY_VERSION
Ruby のバージョンを示す文字列。
RUBY_RELEASE_DATE
Ruby のリリース日を示す文字列。
RUBY_PLATFORM
プラットフォームを示す文字列。
VERSION
RELEASE_DATE
PLATFORM
これらは、上記の定数 RUBY_XXX
の古い名前です。
obsoleteも参照してください。
SCRIPT_LINES__
この定数は、デフォルトでは定義されていません。
この定数がハッシュとして定義された後に、ソースがコンパイルさ れると、そのソースファイル名をキーに、ソースを行毎に分割した配列を値 にしたハッシュ要素が設定されます。この定数はデバッガ(debug.rb) などで利用されています。
SCRIPT_LINES__ = {} require 'English' p SCRIPT_LINES__ # 注: 出力は加工してあります。 # => {"/usr/local/lib/ruby/1.6/English.rb"=> ["alias $ERROR_INFO $!\n", "alias $ERROR_POSITION $@\n", "alias $LOADED_FEATURES $\"\n", : : "alias $POSTMATCH $'\n", "alias $LAST_PAREN_MATCH $+\n"]}
環境変数を表すオブジェクト。Hash と同様のインターフェースを持ち
ます。ただし、Hash
と異なり、ENV
のキーと値には文字列しか
とることができません。
ENV
で得られる文字列は ENV['PATH']
を除いて汚染されていま
す。(オブジェクトの汚染に関してはセキュリティモデルを参照のこと)
ENV['PATH']
はその要素が誰でも書き込み可能なディレクトリを含ん
でいる場合に限り汚染されます。
p ENV['TERM'].tainted? # => true p path = ENV['PATH'] # => "/usr/local/bin:/usr/bin:/bin:/usr/X11/bin" p path.tainted? # => false
ENV[key]
key に対応する環境変数の値を返します。該当する環境変数が存在
しない時には nil
を返します。
ENV[key]=value
ENV.store(key, value)
key に対応する環境変数の値を value にします。
value が nil
の時、key に対応する環境変数を取り
除きます。
ENV.delete(key)
key に対応する環境変数を取り除きます。取り除かれた環境変数の
値を返 しますが、key に対応する環境変数が存在しない時には
nil
を返します。
ブロックが与えられた時には key にマッチするものがなかった時 に評価されます。
ENV.reject{|key, value| ... }
ブロックを評価した値が真である時、要素を削除します。
Enumerable#reject と異なり Hash
を返
します。
ENV.delete_if {|key, value| ... }
ENV.reject!{|key, value| ... }
key と value を引数としてブロックを評価した値が真であ る時、環境変数を削除します。
reject!
は要素に変化がなければ nil
を返します。
ENV.each {|key, value| ... }
ENV.each_pair {|key, value| ... }
key と value を引数としてブロックを評価します。
ENV.each_key {|key| ... }
key を引数としてブロックを評価します。
ENV.each_value {|value| ... }
value を引数としてブロックを評価します。
ENV.empty?
環境変数がひとつも定義されていない時真を返します。
ENV.fetch(key,[default])
ENV.fetch(key) {|key| ... }
key に関連づけられた値を返します。該当するキーが登録されてい ない時には、引数 default が与えられていればその値を、ブロッ クが与えられていればそのブロックを評価した値を返します。そのいずれ でもなければ例外 IndexError が発生します。
ENV.has_key?(val)
ENV.include?(val)
ENV.key?(val)
ENV.member?(val)
val で指定される環境変数が存在する時真を返します。
ENV.has_value?(value)
ENV.value?(value)
value を値として持つ環境変数が存在する時真を返します。
ENV.index(val)
val に対応するキーを返します。対応する要素が存在しない時には
nil
を返します。
ENV.indexes(key_1, ... , key_n)
ENV.indices(key_1, ... , key_n)
引数で指定された名前の環境変数の値の配列を返します。
ruby 1.7 feature: このメソッドは version 1.7 では、obsolete です。 使用すると警告メッセージが表示されます。 代わりに ENV.select を使用します。
ENV.keys
全環境変数の名前の配列を返します。
ENV.length
ENV.size
環境変数の数を返します。
ENV.rehash
何もしません。nilを返します。
ENV.select(key_1, ..., key_n)
ENV.select {|key, value| ... }
最初の形式では、引数で指定されたキー(環境変数名)に対応する値の配列 を返します。存在しないキー(環境変数)に対しては nil が対応します。 ENV.indexes と ENV.indices と同じです。
ブロック付きでイテレータとして呼び出した場合は Enumerable#select と同じです。つまり、ブロッ クにキーと値の組を順に渡し、ブロックが真を返した要素(キーと値の配 列) の配列を返します。
ENV.to_a
環境変数から [key,value]
なる 2 要素の配列の配列を生成します。
ENV.to_hash
環境変数の名前と値のハッシュを返します。
ENV.values
環境変数の全値の配列を返します。
拡張ライブラリを書く時に new
が定義されているとまずい場合が
あるため、Object から new
だけを undef
したクラス。
Ruby レベルでは気にする必要は全くありません。
全ての例外の祖先のクラスです。
Exception.new([error_message = ""])
Exception.exception([error_message = ""])
例外オブジェクトを生成して返します。引数としてエラーメッセージを表 す文字列を与えることができます。このメッセージはデフォルトの例外ハ ンドラで表示されます。
backtrace
バックトレース情報を返します。
"#{sourcefile}:#{sourceline}:in `#{method}'"
(メソッド内の場合)
"#{sourcefile}:#{sourceline}"
(トップレベルの場合)
という形式(デフォルトでは)の String の配列です。
message
to_s
to_str
エラーメッセージをあらわす文字列を返します。
set_backtrace(errinfo)
バックトレース情報に errinfo を設定します。errinfo は
nil
、String あるいは String の配列のいずれかでな
くてはなりません。
ディレクトリ内の要素を順に返すディレクトリストリーム操作のためのクラス。
Dir[pattern]
Dir.glob(pattern)
Dir.glob(pattern) {|file| ...}
ワイルドカードの展開を行った結果を文字列の配列として返します。
ブロックが与えられたときはワイルドカードにマッチしたファイルを
引数にそのブロックを 1 つずつ評価して nil
を返します
パターンを空白(スペース、タブ、改行)あるいは "\0" で区切って 1 度 に複数のパターンを指定することもできます。
p Dir.glob("f* b*") => ["foo", "bar"]
ワイルドカードには以下のものがあります。
*
空文字列を含む任意の文字列と一致します。
?
任意の一文字と一致します。
[ ]
鈎括弧内のいずれかの文字と一致します。-
でつな
がれた文字は範囲を表します。鈎括弧の中の最初の文字が
^
である時には含まれない文字と一致します。
{ }
コンマで区切られた文字列の組合せに展開します。例えば、
foo{a,b,c}
はfooa
, foob
,
fooc
に展開されそれぞれに対してマッチ判定を行います。
**/
ワイルドカード */
の0回以上の繰り返しを意味し、
ディレクトリを再帰的にたどってマッチを行います。
例えば,
foo/**/bar
は foo/bar
, foo/*/bar
,
foo/*/*/bar
... (以下無限に続く)に対してそれぞれ
マッチ判定を行います。
ruby 1.7 feature:
ワイルドカードはバックスラッシュによりエスケープすることがで
きます。(ダブルクォートの文字列中では 2 重にエスケープする必要がある
ことに注意してください)
また、空白類に特殊な意味はなくなりました("\0"
の効果は残っています)。
1.6と同様の処理を期待する場合は、不要な空白はString#chomp
などで
適切に除去するか、gsub(/[ \t\n]/, "\0")
で変換しておく必要が
あります。
Dir.chdir([path])
Dir.chdir([path]) {|path| ... } ((<ruby 1.7 feature>))
カレントディレクトリを path に変更します。
path を省略した場合、環境変数 HOME
または LOGDIR
が設定されていればそのディレクトリに移動します。
カレントディレクトリの変更に成功すれば 0 を返します。失敗した場合 は例外 Errno::EXXX が発生します。
ruby 1.7 feature: ブロックが指定された場合、ディレクトリの変更はブロックの実行中に限 られます。これは以下と等価です。
savedir = Dir.pwd Dir.chdir(newdir) begin ... ensure Dir.chdir(savedir) end
ブロックが指定されたときのこのメソッドの戻り値はブロックの実行結果 です。
Dir.chroot(path)
ルートディレクトリを path に変更します。 chroot(2) を参照のこと。スーパーユーザだけがルー トディレクトリを変更できます。
元のルートディレクトリに戻る方法はありません。
ルートディレクトリの変更に成功すれば 0 を返します。失敗した場合は 例外 Errno::EXXX が発生します。
Dir.delete(path)
Dir.rmdir(path)
Dir.unlink(path)
ディレクトリを削除します。ディレクトリは空でなければいけませ ん。
ディレクトリの削除に成功すれば 0 を返します。失敗した場合は例外 Errno::EXXX が発生します。
Dir.entries(path)
ディレクトリ path に含まれるファイルエントリ名の 配列を返します。以下と同じです。
def dir_s_entries( path ) Dir.open(path) {|d| return d.to_a } end
Dir.foreach(path) {|file| ...}
pathのディレクトリの要素に対して繰り返すイテレー タ。このメソッドは以下と同じ働きをします。
dir = Dir.open(path) begin dir.each {|file| ... } ensure dir.close end
nil
を返します。
Dir.getwd
Dir.pwd
カレントディレクトリのフルパスを返します。
カレントディレクトリの取得に失敗した場合は例外 Errno::EXXX が発生します(が、普通は失敗することはありません)。
Dir.mkdir(path[, mode])
path という新しいディレクトリを作ります。パーミッションは
mode で指定された値(デフォルトは 0777)に umask をかけた
(mode & ~umask
) 値になります(mkdir(2)) を
参照)。
ディレクトリの作成に成功すれば 0 を返します。失敗した場合は例外 Errno::EXXX が発生します。
Dir.new(path)
Dir.open(path)
Dir.open(path) {|dir| ...}
pathに対するディレクトリストリームをオープンして返します。 オープンに失敗した場合は例外 Errno::EXXX が発生します。
open()
はブロックを指定することができます。
ブロックを指定して呼び出した場合は、ディレクトリストリームを
与えられてブロックが実行されます。ブロックの実行が終了すると、
ディレクトリは自動的にクローズされます。
ruby 1.7 feature: ブロックが指定されたときのこのメソッドの戻り値はブロックの実行結果 です。*80
close
ディレクトリストリームをクローズします。以降のディレクトリに 対する操作は例外 IOError を発生させます。
クローズに成功すれば nil
を返します。失敗した場合は例外
IOError が発生します。
each {|item| ... }
ディレクトリの各要素に対してブロックを評価します。
self
を返します。
pos
tell
ディレクトリストリームの現在の位置を整数で返します。
Dir.open("/tmp") {|d| d.each {|f| p d.pos } }
pos=(pos)
seek(pos)
ディレクトリストリームの読み込み位置を pos に移動させます。 posはDir#tell で与えられた値でなければなりま せん。
pos=
は右辺を返します。seek
は self
を返します。
read
ディレクトリストリームから次の要素を読み出して返します。最後の要素
まで読み出していれば nil
を返します。
ディレクトリの読み出しに失敗した場合は例外 Errno::EXXX が発 生します。
rewind
ディレクトリストリームの読み込み位置を先頭に移動させます。
self
を返します。
ファイルの情報を格納したオブジェクトのクラス。
File::Stat.new(path)
path に関する File::Stat
オブジェクトを生成して返します。
File.stat と同じです。
self <=> other
ファイルの最終更新時刻を比較します。self
が other よりも
新しければ正の数を、等しければ 0 を古ければ負の数を返します。
ftype
ファイルのタイプを表す文字列を返します。文字列は以下のうちの いずれかです。
"file" "directory" "characterSpecial" "blockSpecial" "fifo" "link" "socket" "unknown"
以下の属性メソッドは、システムによってサポートされていない場合 0 が返ります。
dev
デバイス番号(ファイルシステム)
ino
i-node 番号
mode
ファイルモード
nlink
ハードリンクの数
uid
オーナーのユーザID
gid
オーナーのグループID
rdev
デバイスタイプ(スペシャルファイルのみ)
size
ファイルサイズ(バイト単位)
blksize
望ましいI/Oのブロックサイズ
blocks
割り当てられているブロック数
atime
最終アクセス時刻
mtime
最終更新時刻
ctime
最終i-node変更時刻
rdev_major ((<ruby 1.7 feature>))
rdev の major 番号
rdev_minor ((<ruby 1.7 feature>))
rdev の minor 番号
以下の判定メソッドは、FileTest の同名のモジュール関数と同じですが、
ファイル名を引数に取るかわりに Stat
自身について判定します。
directory?
ディレクトリの時に真
readable?
読み込み可能な時に真
readable_real?
実ユーザ/実グループによって読み込み可能な時に真
writable?
書き込み可能な時に真
writable_real?
実ユーザ/実グループによって書き込み可能な時に真
executable?
実効ユーザ/グループIDで実行できる時に真
executable_real?
実ユーザ/グループIDで実行できる時に真
file?
通常ファイルの時に真
zero?
サイズが0である時に真
size?
サイズ(0の時には偽)
owned?
自分のものである時に真
grpowned?
グループIDが実行グループIDと等しい時に真
pipe?
名前つきパイプ(FIFO)の時に真
symlink?
シンボリックリンクである時に真
socket?
ソケットの時に真
blockdev?
ブロックスペシャルファイルの時に真
chardev?
キャラクタスペシャルファイルの時に真
setuid?
setuidされている時に真
setgid?
setgidされている時に真
sticky?
stickyビットが立っている時に真
obj.method(:method_name) によりオブジェクト化され たメソッドオブジェクトのクラスです。メソッドの実体(名前でなく)とレシー バの組を封入します。Proc オブジェクトと違ってコンテキストを保持 しません。
Proc との差…Method
は取り出しの対象であるメソッドが
なければ作れませんが、Proc
は準備なしに作れます。その点から
Proc
は使い捨てに向き、Method
は何度も繰り返し生成する
場合に向くと言えます。また内包するコードの大きさという点では
Proc
は小規模、Method
は大規模コードに向くと言えます。
self[arg, ...]
call(arg ... )
call(arg ... ) { ... }
メソッドオブジェクトに封入されているメソッドを起動します。 引数やブロックはそのままメソッドに渡されます。
self[]
の形の呼び出しは通常のメソッド呼び出しに見た目を
近付けるためだけに用意されたもので、Array#[]のような
他の [] メソッドとの意味的な関連性はありません。
メソッドオブジェクトが汚染されている場合、そのメソッドは、セーフレ ベル 4 で実行されます (セーフレベルに関するその他の詳細を参照)。
arity
メソッドオブジェクトの引数の数を返します。self
が引数の数を
可変長で受け取れる場合
-(最低限必要な数 + 1)
を返します。
inspect
Object#inspect 参照。以下の形式の文字列を返し ます。
#<Method: klass1(klass2)#method>
klass1 は、Method#inspect では、レシーバのクラス名、 UnboundMethod#inspect では、UnboundMethod オブジェクトの生成 元となったクラス/モジュール名です。
klass2 は、実際にそのメソッドを定義しているクラス/モジュール名、 method は、メソッド名を表します。
module Foo def foo "foo" end end class Bar include Foo end p Bar.new.method(:foo) # => #<Method: Bar(Foo)#foo>
ruby 1.7 feature: 特異メソッドに対しては、
#<Method: obj.method> #<Method: klass1(klass2).method>
という形式の文字列を返します。二番目の形式では klass1 はレシーバ、 klass2 は実際にそのメソッドを定義しているオブジェクトになります。
obj = "" class <<obj def foo end end p obj.method(:foo) # => #<Method: "".foo> class Foo def Foo.foo end end p Foo.method(:foo) # => #<Method: Foo.foo> class Bar < Foo end p Bar.method(:foo) # => #<Method: Bar(Foo).foo>
to_proc
self
を call
する Proc オブジェクトを生成して返
します。
unbind
self
のレシーバとの関連を取り除いた UnboundMethod オブ
ジェクトを生成して返します。
レシーバを持たないメソッドオブジェクトのクラスです。
Module#instance_method や
Method#unbind により生成し、後で
UnboundMethod#bind
によりレシーバを割り当てた Method オブ
ジェクトを作ることができます。
例: メソッドの再定義を UnboundMethod を使って行う方法*82
class Foo def foo p :foo end @@orig_foo = instance_method :foo def foo p :bar @@orig_foo.bind(self).call end end Foo.new.foo => :bar :foo
self[args, ...]
call(args, ...)
call(args, ...) { ... }
UnboundMethod
はバインドしなければ起動できません。
常に例外 TypeError が発生します。
class Foo def foo end end Foo.instance_method(:foo).call # => -:5:in `call': you cannot call unbound method; bind first (TypeError)
bind(obj)
self
を obj にバインドして bound method オブジェクト
(つまり Method オブジェクト) を生成し返します。ただしバイン
ドできるのは、unbind したオブジェクトのクラスのインスタンスか、メ
ソッド定義元のモジュールをインクルードしたクラスのインスタンスだけ
です。そうでなければ例外 TypeError が発生します。
例:
# クラスのインスタンスメソッドの UnboundMethod の場合 class Foo def foo "foo" end end # UnboundMethod `m' を生成 p m = Foo.instance_method(:foo) # => #<UnboundMethod: Foo(Foo)#foo> # Foo のインスタンスをレシーバとする Method オブジェクトを生成 p m.bind(Foo.new) # => #<Method: Foo(Foo)#foo> # Foo のサブクラス Bar のインスタンスをレシーバとする Method # オブジェクトを生成(これは許されない) class Bar < Foo end # p m.bind(Bar.new) # => -18:in `bind': bind argument must be an instance of Foo (TypeError) # 同名の特異メソッドが定義されているとダメ class << obj = Foo.new def foo end end p m.bind(obj) # => -:25:in `bind': method `foo' overridden (TypeError) # モジュールのインスタンスメソッドの UnboundMethod の場合 module Foo def foo "foo" end end # UnboundMethod `m' を生成 p m = Foo.instance_method(:foo) # => #<UnboundMethod: Foo(Foo)#foo> # Foo をインクルードしたクラス Bar のインスタンスをレシーバと # する Method オブジェクトを生成 class Bar include Foo end p m.bind(Bar.new) # => #<Method: Bar(Foo)#foo> # Bar のサブクラスは Foo をインクルードしているのと同等なのでよい class Baz <Bar end p m.bind(Baz.new) # => #<Method: Baz(Foo)#foo> # 同名の特異メソッドが定義されているとダメ class << obj = Baz.new def foo end end p m.bind(obj) # => -:27:in `bind': method `foo' overridden (TypeError)
to_proc
self
を call
する Proc オブジェクトを生成して返します。
unbind
self
を返します。
Numeric
は数値の抽象クラスです。Ruby では coerce
メソッドを使うことによって異なる数値クラス間で演算を行うことができます。
演算や比較を行うメソッド(+, -, *, /, <=>)などはサブクラスで定義されま
す。また、効率のため Numeric
のメソッドと同じメソッドがサブクラ
スで再定義されている場合があります。
+ self
self
自身を返します。
- self
self
の符号を反転させたものを返します。
self / other ((<ruby 1.7 feature>))
self を other で割った商を返します。
abs
self
の絶対値を返します。
ceil
self
と等しいかより大きい最小の整数(天井)を返します。
clone
dup
self
を返します。
ruby 1.7 feature: version 1.7 では数値などの immutable なオ ブジェクトは close や dup が禁止されています。
1.dup # => in `clone': can't clone Fixnum (TypeError)
coerce(number)
number の型を自分と直接演算できる型に変換して
[number, self]
という配列に格納して返します。数値クラ
スの算術演算子は通常自分と演算できないクラスをオペランドとして受け
取ると coerce
を使って自分とオペランドを変換した上で演算を行
います。
divmod(other)
self
を other で割った商 (q) と余り (m) を、
[q, m]
という 2 要素の配列にして返します。
ここで、x を y で割った商 q と余り m とい うのは、それぞれ
x = y * q + m かつ |m| < |y|
をみたす 整数 q と 数 m のことです。
ただし divmod
では、上の条件に加えて、余りの符号を
other と同じ(またはゼロ)にします。つまり
となります。
floor
self
を超えない最大の整数(床)を返します。
integer?
self
が整数の時、真を返します。
modulo(other)
self を other で割った余り m を返します(divmod
参照)。
ただし m の符号は other と同じ(またはゼロ)です。 つまり
となります。
nonzero?
ゼロの時、偽を返し、非ゼロの時 self
を返します。
remainder(other)
self を other で割った余り r を返します (divmod参照)。
ただし r の符号は self
と同じ(またはゼロ)です。
つまり
self
> 0 のとき 0 <= r < |other|self
< 0 のとき -|other| < r <= 0となります。
p (13.modulo(4)) #=> 1 p (13.modulo(-4)) #=> -3 p ((-13).modulo(4)) #=> 3 p ((-13).modulo(-4)) #=> -1 p (13.remainder(4)) #=> 1 p (13.remainder(-4)) #=> 1 p ((-13).remainder(4)) #=> -1 p ((-13).remainder(-4)) #=> -1
round
self
に最も近い整数を返します。
truncate
小数点以下を切捨てます。
zero?
ゼロの時、真を返します。
ほとんどの数値関連のメソッドはサブクラスで再定義されています。これは、 効率のためであったり上位抽象クラスで実装を定義することができなかったり するためです。実際にどのメソッドがどのクラスに定義されているかは以下の 表を参照してください。
cary = [Numeric, Integer, Fixnum, Bignum, Float] mary = cary.collect {|c| c.instance_methods} methods = [] mary.each {|m| methods |= m} methods.sort.each_with_index {|op, i| if i % 10 == 0 heading = sprintf("%10s %10s %10s %10s %10s %10s", "", *cary.collect {|klass| klass.name.center(10)}) puts heading puts "-" * heading.size end printf("%10s | %10s %10s %10s %10s %10s\n", op, *mary.collect {|methods| methods.member?(op) ? "o".center(10) : ""}) } ruby 1.6.6 (2002-01-11) [i586-linux] Numeric Integer Fixnum Bignum Float ------------------------------------------------------------------- % | o o o & | o o * | o o o ** | o o o + | o o o +@ | o - | o o o -@ | o o o o / | o o o < | o o Numeric Integer Fixnum Bignum Float ------------------------------------------------------------------- << | o o <= | o o <=> | o o o == | o o o === | o o > | o o >= | o o >> | o o [] | o o ^ | o o Numeric Integer Fixnum Bignum Float ------------------------------------------------------------------- abs | o o o o ceil | o o o chr | o clone | o coerce | o o o divmod | o o o o downto | o o eql? | o o o finite? | o floor | o o o Numeric Integer Fixnum Bignum Float ------------------------------------------------------------------- hash | o o id2name | o infinite? | o integer? | o o modulo | o o o o nan? | o next | o o nonzero? | o remainder | o o round | o o o Numeric Integer Fixnum Bignum Float ------------------------------------------------------------------- size | o o step | o o succ | o o times | o o to_f | o o o to_i | o o to_int | o to_s | o o o truncate | o o o type | o Numeric Integer Fixnum Bignum Float ------------------------------------------------------------------- upto | o o zero? | o o o o | | o o ~ | o o
構造体クラス。Struct.new
はこのクラスのサブクラスを新たに生成し
ます。個々の構造体はサブクラスから new
を使って生成します。個々
の構造体サブクラスでは構造体のメンバに対するアクセスメソッドが定義され
ています。
Struct.new([name,] member ... )
Struct
クラスに name という名前の新しいサブクラスを作っ
て、それを返します。サブクラスでは構造体のメンバに対するアクセスメ
ソッドが定義されています。例えば:
dog = Struct.new("Dog", :name, :age) fred = dog.new("fred", 5) fred.age=6 printf "name:%s age:%d", fred.name, fred.age
は "name:fred age:6"
を出力します。
構造体名 name はStructのクラス定数名になりますので大文字で始 まる必要があります。member は、Symbol か文字列で指定し ます。
name を省略した場合(第一引数が Symbol の場合)、生成し た構造体クラスは名前のないクラスとなります。名前のないクラスは、最 初に名前を求める際に代入されている定数名を検索し、見つかった定数名 をクラス名とします(Class.newを参照)。
例: 構造体クラスのクラス名
p Struct.new("Foo", :foo, :bar) => Struct::Foo p Foo = Struct.new(:foo, :bar) => Foo
Struct::XXX.new(value ... )
Struct::XXX[value ...]
構造体オブジェクトを生成して返します。引数は構造体の初期値です。構
造体のメンバの数よりも多く指定するとと 例外 ArgumentError が
発生します。メンバの初期値は指定されなければ nil
です。
Foo = Struct.new(:foo, :bar) foo = Foo.new(1) p foo.values # => [1, nil]
Struct::XXX.members
構造体のメンバの名前の配列を返します。
self[nth]
構造体の nth 番目のメンバの値を返します。nth が文字列 または Symbol の場合はその名前のメンバの値を返します。
self[nth]=value
構造体の nth 番目のメンバの値を value にします。 nth が文字列または Symbol の場合はその名前のメンバの値 を value にします。
each
構造体の各メンバに対して繰り返します。
self
を返します。
length
size
構造体のメンバの数を返します。
members
構造体のメンバの名前の配列を返します。
values
to_a
構造体のメンバの値を配列にいれて返します。例えば以下のようにして passwd のエントリを出力できます。
require 'etc' print Etc.getpwuid.values.join(":"), "\n"
Thread はグループを持ち、必ずいずれかのグループに属します。
ThreadGroup
クラスによりグループに属する Thread
をまとめて
操作することができます。
デフォルトの ThreadGroup
は、
ThreadGroup::Default です。生成されたばかり
の Thread は生成した Thread のグループを引き継ぎます。
生成したすべてのThreadが終了するのを待つ
5.times { Thread.new { sleep 1; puts "#{Thread.current} finished" } } (ThreadGroup::Default.list - [Thread.current]).each {|th| th.join} puts "all threads finished"
対象の Thread
が Thread
を起こす可能性がある場合
(Thread.exclusive参照)
Thread.exclusive do (ThreadGroup::Default.list - [Thread.current]).each {|th| th.join} end
ThreadGroup.new
新たな ThreadGroup
を生成して返します。
add(thread)
スレッド thread のグループを self
にします。
self
を返します。
list
self
に属するスレッドの配列を返します。
Default
デフォルトで定義されている ThreadGroup
です。メインスレッド
は最初このグループに属します。
時刻オブジェクト。Time.now は現在の時刻を返します。
File#stat の返すファイルのタイムスタンプは Time
オブジェクトです。
Time
オブジェクトは時刻を起算時からの経過秒数で保持しています。
起算時は協定世界時(UTC、もしくはその旧称から GMT とも表記されます) の
1970年1月1日午前0時です。なお、うるう秒を勘定するかどうかはシステムに
よります。
また、Time
オブジェクトは協定世界時と地方時のどちらのタイムゾー
ンを使用するかのフラグを内部に保持しています。ただし、この情報は
Marshal.dump では保存されず、Marshal.load
で読み込んだ Time
オブジェクトのタイムゾーンは常に地方時になりま
す。
Time.at(time[, usec])
time で指定した時刻の Time
オブジェクトを返します。
time は Time
オブジェクト、もしくは起算時からの経過秒
数を表わす整数か浮動小数点数です。
浮動小数点の精度では不十分な場合、usec を指定します。
time + (usec/1000000)
の時刻を返します。この場合、
time、usec ともに整数でなければなりません。
生成された Time
オブジェクトのタイムゾーンは地方時となります。
Time.gm(year[, month[, day[, hour[, min[, sec[, usec]]]]]])
Time.gm(sec, min, hour, mday, mon, year, wday, yday, isdst, zone)
Time.utc(year[, month[, day[, hour[, min[, sec[, usec]]]]]])
Time.utc(sec, min, hour, mday, mon, year, wday, yday, isdst, zone)
引数で指定した協定世界時の Time
オブジェクトを返します。第 2
引数以降は省略可能で、省略した場合の値はその引数がとり得る最小の値
です。
month は 1(1月)から 12(12月)の範囲の整数または英語の月名、ま たは 1 から 12 までの数を表わす文字列で指定します。
引数の数がTime#to_a と全く同じ場合(こちらは秒が先 頭に来る形式ですが)、その順序を正しく解釈します。
Time.local(year[, month[, day[, hour[, min[, sec[, usec]]]]]])
Time.local(sec, min, hour, mday, mon, year, wday, yday, isdst, zone)
Time.mktime(year[, month[, day[, hour[, min[, sec[, usec]]]]]])
Time.mktime(sec, min, hour, mday, mon, year, wday, yday, isdst, zone)
引数で指定した地方時の Time
オブジェクトを返します。引数の扱
いは Time.gm と同じです。
Time.new
Time.now
現在時刻の Time
オブジェクトを返します。new
は
now
とは initialize
を呼び出す点が異なります。
Time.times
自身のプロセスとその子プロセスが消費したユーザ/システム CPU
時間の積算を Struct::Tms のオブジェクトとして返します。
Struct::Tms
は以下のメンバを持つ構造体クラスです。
utime # user time stime # system time cutime # user time of children cstime # system time of children
時間の単位は秒で、浮動小数点数で与えられます。詳細は times(3) を参照してください。
ruby 1.7 feature このメソッドは Process に移動しました。Time.times も使えます が、警告メッセージが出力されます。
self + other
self
より other だけ後の時刻を返します
self - other
other が Time
オブジェクトである時、ふたつの時刻の差を
Float で返します。other が数値である時には self
より other だけ前の時刻を返します。
self <=> other
時刻の比較。other は Time
オブジェクトか数値でなければ
なりません。数値の場合は起算時からの経過秒数とみなして比較します。
asctime
ctime
時刻を asctime(3) の形式の文字列に変換します。た だし、末尾の \n は含まれません。
gmt?
utc?
self
のタイムゾーンが協定世界時に設定されていれば真を返しま
す。
getgm
getutc
タイムゾーンを協定世界時に設定した Time
オブジェクトを新しく
生成して返します。
getlocal
タイムゾーンを地方時に設定した Time
オブジェクトを新しく生成
して返します。
gmtime
utc
タイムゾーンを協定世界時に設定します。
このメソッドを呼び出した後は時刻変換を協定世界時として行ないます。 協定世界時を表示するためには以下のようにします。
print Time.now.gmtime, "\n"
self
を返します。
localtime
タイムゾーンを地方時に設定します(デフォルト)。self
を返しま
す。
localtime
(gmtime
も)の挙動はシステムの
localtime(3)の挙動に依存します。Time
クラ
スでは時刻を起算時からの経過秒数として保持していますが、ある特定の
時刻までの経過秒は、システムがうるう秒を勘定するかどうかによって異
なる場合があります。システムを越えて Time
オブジェクトを受け
渡す場合には注意する必要があります。
strftime(format)
時刻を format 文字列に従って文字列に変換した結果を返します。 format 文字列として指定できるものは 以下の通りです。
%A
曜日の名称(Sunday, Monday ... )
%a
曜日の省略名(Sun, Mon ... )
%B
月の名称(January, February ... )
%b
月の省略名(Jan, Feb ... )
%c
日付と時刻
%d
日(01-31)
%H
24時間制の時(00-23)
%I
12時間制の時(01-12)
%j
年中の通算日(001-366)
%M
分(00-59)
%m
月を表す数字(01-12)
%p
午前または午後(AM,PM)
%S
秒(00-60) (60はうるう秒)
%U
週を表す数。最初の日曜日が第1週の始まり(00-53)
%W
週を表す数。最初の月曜日が第1週の始まり(00-53)
%w
曜日を表す数。日曜日が0(0-6)
%X
時刻
%x
日付
%Y
西暦を表す数
%y
西暦の下2桁(00-99)
%Z
タイムゾーン trap
%%
%自身
現在の実装では、このメソッドは、システムの strftime(3) をそのまま使用しています。そのためここにあげた指示子以外のものが使 用できる場合があります。ただし、上記以外の指示子を使用した場合、移 植性をそこなう可能性がある点に注意してください。
sec
min
hour
mday
day
mon
month
year
wday
yday
zone
isdst
dst?
内部的に保持している tm
構造体の内容を返します。zone
以外は整数を返します。zone
はタイムゾーンを表す文字列を返し
ます。(localtime(3) 参照)
注意: C 言語の tm
構造体とは異なり、month
は 1 月に対
して 1 を返し、year
は 1998 年に対して 1998 を返します。また、
yday
は 1 から数えます。
utc_offset
gmt_offset
gmtoff
協定世界時との時差を秒を単位とする数値として返します。
地方時が協定世界時よりも進んでいる場合(アジア、オーストラリアなど) には負の値、遅れている場合(アメリカなど)には正の値になります。
タイムゾーンが協定世界時に設定されている場合は 0 を返します。
to_a
tm
構造体の中身を配列にして返します。その順序は:
です。
to_f
起算時からの経過秒数を浮動小数点数で返します。1 秒に満たない経過も 表現されます。
to_i
tv_sec
起算時からの経過秒数を整数で返します。
to_s
時刻を date(1) のような形式の文字列に変換します。
usec
tv_usec
時刻のマイクロ秒の部分を返します。
比較演算を許すクラスのための Mix-in
。このモジュールをインクルー
ドするクラスは、基本的な比較演算子である <=>
演算子を定義してい
る必要があります。他の比較演算子はその定義を利用して派生できます。
self == other
self
と other が等しい時真を返します。
self > other
self
が other より大きい時真を返します。
self >= other
self
が other より大きいか等しい時真を返します。
self < other
self
が other より小さい時真を返します。
self <= other
self
が other より小さいか等しい時真を返します。
between?(min, max)
self
が min と max の範囲内(min, max
を含みます)にある時真を返します。
繰り返しを行なうクラスのための Mix-in
。このモジュールの
メソッドは全て each
を用いて定義されているので、インクルード
するクラスには each
が定義されていなければなりません。
all? {|item| ... } ((<ruby 1.7 feature>))
各要素に対してブロックを評価し、すべての結果が真である場合に
true
を返します。ブロックが偽を返した時点で、ただちに
false
を返します。
p [1,2,3].all? {|v| v > 0} # => true p [1,2,3].all? {|v| v > 1} # => false
any? {|item| ... } ((<ruby 1.7 feature>))
各要素に対してブロックを評価し、すべての結果が偽である場合に
false
を返します。ブロックが真を返した時点で、ただちに
true
を返します。
p [1,2,3].any? {|v| v > 3} # => false p [1,2,3].any? {|v| v > 1} # => true
collect {|item| ... }
map {|item| ... }
各要素に対してブロックを評価した結果を全て含む配列を返します。
ブロックを省略した場合、
obj.collect {|item| item}
を行います。これは Enumerable#to_a と同じで す。
each_with_index {|item,index| ... }
要素とインデックスを両方与えるイテレータ。
nil
を返します*83。
find([ifnone]) {|item| ... }
detect([ifnone]) {|item| ... }
要素に対してブロックを評価した値が真になった最初の要素を返します。
真になる要素がひとつも見つからなかったときは ifnone を(もし
指定されていれば)評価して nil
を返します。
ifnone には文字列かあるいは、call
メソッドを持つオブジェ
クト(例えば Proc)を指定します。
[1,2,3].find("raise") {|v| v > 4} # => -:1: unhandled exception
find_all {|item| ... }
select {|item| ... }
各要素に対してブロックを評価した値が真であった要素を全て含む配列を 返します。真になる要素がひとつもなかった場合は空の配列を返します。
grep(pattern)
grep(pattern) {|item| ... }
pattern === item
が成立する要素を全て含んだ配列を返し
ます。ブロックとともに呼び出された時には条件の成立した要素に対して
それぞれブロックを評価し、その結果の配列を返します。マッチする要素
がひとつもなかった場合は空の配列を返します。
inject(init) {|result, item| ... } ((<ruby 1.7 feature>))
最初に初期値 init と self
の最初の要素を引数にブロック
を実行します。2 回目以降のループでは、前のブロックの実行結果と
self
の次の要素を引数に順次ブロックを実行します。そうして最
後の要素まで繰り返し、最後のブロックの実行結果を返します。
空の要素に対しては init を返します。
合計の計算
p [1,2,3,4,5].inject(0) {|result, item| result + item } => 15
これは以下のように書くのと同じです。
result = 0 [1,2,3,4,5].each {|v| result += v } p result => 15
member?(val)
include?(val)
val と ==
の関係にある要素を含むとき真を返します。
max
最大の要素を返します。全要素が互いに <=>
メソッドで比較でき
ることを仮定しています。
max {|a, b| ... }
ブロックの評価値を元に各要素を比較し、最大の要素を返します。
ブロックの値は、a>b
のとき正、a==b
のとき 0、a<b
のとき負の整数を、期待しています。ブロックが整数以外を返したときは
例外 TypeError が発生します。
min
最小の要素を返します。全要素が互いに <=>
メソッドで比較でき
ることを仮定しています。
min {|a, b| ... }
ブロックの評価値で各要素を比較し、最小の要素を返します。
ブロックの値は、a>b
のとき正、a==b
のとき 0、a<b
のとき負の整数を、期待しています。ブロックが整数以外を返したときは
例外 TypeError
が発生します。
reject {|item| ... }
各要素に対してブロックを評価し、その値が偽であった要素を集めた新し い配列を返します。
sort
sort {|a, b| ... }
全ての要素を昇順にソートした配列を生成して返します。
ブロックなしのときは <=>
メソッドを要素に対して呼び、その結
果をもとにソートします。
<=>
以外でソートしたい場合は、ブロックを指定します。この場合
ブロックの評価結果を元にソートします。ブロックの値は、a>b
の
とき正、a==b
のとき 0、a<b
のとき負の整数を、期待して
います。ブロックが整数以外を返したときは例外 TypeError が発
生します。
sort_by {|item| ... } ((<ruby 1.7 feature>))
ブロックの評価結果を <=>
メソッドで比較して昇順にソートを行
い、その結果を新しく生成した配列で返します。これは、以下とほぼ同じ
動作をします。
def sort_by self.collect {|i| [yield(i), i]}. sort {|a,b| a[0] <=> b[0]}. collect! {|i| i[1]} end
sort_by
を使わない以下の例では、比較を行う度に downcase が実
行されるため、downcase の実行速度が遅ければ sort の速度が致命的に
遅くなります。
p ["BAR", "FOO", "bar", "foo"].sort {|a,b| a.downcase <=> b.downcase }
sort_by
を使えば downcase の実行回数は要素数です(つまり、そ
の部分は O(n) のオーダー)。
p ["BAR", "FOO", "bar", "foo"].sort_by {|v| v.downcase} => ruby 1.7.1 (2001-08-24) [i586-linux] ["BAR", "bar", "FOO", "foo"]
以下の、実行回数の検証結果を参照してみてください。
class Integer def count $n += 1 self end end ary = [] 1.upto(1000) {|v| ary << rand(v)} $n = 0 ary.sort {|a,b| a.count <=> b.count } p $n # => 18200 $n = 0 ary.sort_by {|v| v.count} p $n # => 1000
Enumerable#sort のソートアルゴリズムは安定(stable)
ではありませんが(比較結果が同じ要素に対して、元の順序を保持しないこ
とを「安定ではない」と言います)、sort_by
を使って以下のようにするこ
とで stable sort を実現できます。
i = 0 ary.sort_by {|v| [v, i += 1]}
to_a
entries
全ての要素を含む配列を返します。
システムコールのエラーに対応する例外を集めたモジュールです。
以下の例外クラスが定義されています(システムに定義されていれば)。個々の 例外の意味はシステム依存です。これらのクラス全般の説明については Errno::EXXX を参照してください。
なお、Ruby にとって未知の(以下の一覧にはない)システムエラーが発生した
場合は、Errno::Exxx
(xxx は、エラー番号を表す 3 桁の
数字)という名の例外クラスが作成されます。
この例外クラスは BeOS の場合に限ります。
FileTest
はファイルの検査関数を集めたモジュールです。このモジュー
ルはインクルードしても使えます。
FileTest.blockdev?(filename)
filename がブロックスペシャルファイルである時、真を返します。
FileTest.chardev?(filename)
filename がキャラクタスペシャルファイルの時、真を返します。
FileTest.executable?(filename)
filename が実効ユーザ/グループ ID で実行できる時、真を返しま す。
FileTest.executable_real?(filename)
filename が実ユーザ/グループ ID で実行できる時、真を返します。
FileTest.exist?(filename)
filename が存在する時、真を返します。
FileTest.grpowned?(filename)
filename のグループ ID が実行グループ ID と等しい時、真を返 します。
FileTest.directory?(filename)
filename がディレクトリの時、真を返します。
FileTest.file?(filename)
filaname が通常ファイルである時、真を返します。
FileTest.pipe?(filename)
filename が名前つきパイプ(FIFO)である時、真を返します。
FileTest.socket?(filename)
filename がソケットである時、真を返します。
FileTest.owned?(filename)
filename が自分のものである時に真を返します。
FileTest.readable?(filename)
filename を読み込み可能な時に真を返します。
FileTest.readable_real?(filename)
filename が実ユーザ/実グループによって読み込み可能な時に真を 返します。
FileTest.setuid?(filename)
filename が setuid(2) されている時に真を返 します。
FileTest.setgid?(filename)
filename が setgid(2) されている時に真を返 します。
FileTest.size(filename)
filename のサイズを返します。filename が存在しなければ
例外 Errno::EXXX(おそらく Errno::ENOENT
)が発生します。
FileTest.size?, FileTest.zero? も参 照してください。
FileTest.size?(filename)
filename のサイズを返します。filename が存在しない時や
filename のサイズが0の時には nil
を返します。
FileTest.size, FileTest.zero? も参照 してください。
FileTest.sticky?(filename)
filename の sticky ビット(chmod(2) 参照)が 立っている時に真を返します。
FileTest.symlink?(filename)
filename がシンボリックリンクである時、真を返します。
FileTest.writable?(filename)
filename が書き込み可である時、真を返します。
FileTest.writable_real?(filename)
filename が実ユーザ/実グループによって書き込み可である時、真 を返します。
FileTest.zero?(filename)
filename が存在して、そのサイズが 0 である時、真を返します。
filename が存在しない場合は false
を返します。
FileTest.size, FileTest.size?, も参 照してください。
GC
は Ruby インタプリタの「ゴミ集め(Garbage Collection)」を制御
するモジュールです。
GC.disable
ガーベージコレクトを禁止します。
前回の禁止状態を返します(禁止されていたなら true, GC が有効であったなら、 false)。
GC.enable
カーベージコレクトを許可します。
前回の禁止状態を返します(禁止されていたなら true, GC が有効であったなら、 false)。
GC.start
カーベージコレクトを開始します。
nil
を返します。
garbage_collect
ガーベージコレクトを開始します。以下と同じ働きをします。
GC.start
nil
を返します。
Ruby オブジェクトをファイル(または文字列)に書き出したり、読み戻したり する機能を提供するモジュール。大部分のクラスのインスタンスを書き出す事 ができますが、書き出しの不可能なクラスも存在していて(例:IO)、そ のようなクラスを書き出そうとすると例外 TypeError が発生します。
Marshal.dump(obj[,port][,limit])
obj を再帰的にファイルに書き出します。ファイルに書き出せない クラスのインスタンスをファイルに書き出そうとすると例外が発生します。 ファイルに書き出せないクラスは以下の通りです。
また、これらのクラスを間接的に指すクラスなども書き出せません。 *84
port には IO
(またはそのサブクラス)のインスタンスを指定
します。この場合、port を返します。省略した場合には
dump
はそのオブジェクトをダンプした文字列を返します。
出力するオブジェクトがメソッド `_dump
' を定義している場合に
は、ファイル出力はそのメソッドを使って行われます。メソッド
`_dump
' は引数として再帰を制限するレベル limit を受け
取り、オブジェクトを文字列化したものを返します。
インスタンスがメソッド `_dump
' を持つクラスは必ず同じフォー
マットを読み戻すクラスメソッド `_load
' を定義する必要があり
ます。`_load
' はオブジェクトを表現した文字列を受け取り、それ
をオブジェクトに戻したものを返す必要があります。
limit を指定した場合、limit 段以上深くリンクしたオブジェ クトをダンプできません(デフォルトは 100 レベル)。負の limit を指定すると深さチェックを行いません。
Marshal.load(port[,proc])
Marshal.restore(port[,proc])
port からオブジェクトを読み込んで来て、元のオブジェクトと同
じ状態をもつオブジェクトを生成します。port は文字列か
IO
(またはそのサブクラス)のインスタンスを指定します。
proc として手続きオブジェクトが与えられた場合には読み込んで 来るオブジェクトを引数にその手続きが呼び出されます (Fixnum, Symbol は渡されない)。
str = Marshal.dump(["a", 1, 10 ** 10, 1.0, :foo]) p Marshal.load(str, proc {|obj| p obj}) # => [] "a" 10000000000 1.0 ["a", 1, 10000000000, 1.0, :foo]
MAJOR_VERSION ((<ruby 1.7 feature>))
MINOR_VERSION ((<ruby 1.7 feature>))
Marshal.dump) が出力するデータフォーマットのバージョ ン番号です。
Marshal.load は、メジャーバージョンが異なるか、バー ジョンの大きなマーシャルデータを読み込んだとき例外 TypeError を発生させます。
マイナーバージョンが古いだけのフォーマットは読み込み可能ですが、 $VERBOSE = true のときには警告メッセージが 出力されます
マーシャルされたデータのバージョン番号は以下のようにして取得するこ とができます。
obj = Object.new major, minor = Marshal.dump(obj).unpack("cc") p [major, minor]
浮動小数点演算をサポートするクラス。Math
モジュールは同じ定義の
メソッドと特異メソッドとの両方が定義されているので、特異メソッドを呼び
出して使う使い方と、クラスにインクルードして使う使い方との両方ができま
す。
例:
pi = Math.atan2(1, 1)*4; include Math pi2 = atan2(1, 1)*4
Math.acos(x) ((<ruby 1.7 feature>))
Math.asin(x) ((<ruby 1.7 feature>))
Math.atan(x) ((<ruby 1.7 feature>))
x の逆三角関数の値をラジアンで返します。
返される値の範囲はそれぞれ [0, +π]
、[-π/2, +π/2]
、
(-π/2, +π/2)
です。
Math.atan2(y, x)
y/x のアークタンジェントを [-π, π]
の範囲で返します。
Math.cos(x)
Math.sin(x)
Math.tan(x)
ラジアンで表された x の三角関数の値を [-1, 1]
の範囲で
返します。
Math.cosh(x) ((<ruby 1.7 feature>))
Math.sinh(x) ((<ruby 1.7 feature>))
Math.tanh(x) ((<ruby 1.7 feature>))
x の双曲線関数の値を返します。
Math.exp(x)
x の指数関数の値を返します。
Math.frexp(x)
実数 x の指数部と仮数部を返します。
Math.hypot(x, y) ((<ruby 1.7 feature>))
sqrt(x*x + y*y)
を返します。
Math.ldexp(x,exp)
実数 x に 2 の exp 乗をかけた数を返します。
Math.log(x)
x の自然対数を返します。
Math.log10(x)
x の常用対数を返します。
Math.sqrt(x)
x の平方根を返します。x の値が負である時には例外 ArgumentError が発生します。
E
自然対数の低
p "%.60f" % Math::E # => "2.718281828459045090795598298427648842334747314453125000000000"
PI
円周率
p "%.60f" % Math::PI # => "3.141592653589793115997963468544185161590576171875000000000000"
精度をもつ具象数値クラスのための Mix-in。 ここでいう精度とは実数の近似 の良さを意味します。抽象数値クラスや複素数、行列などそれら自身が実数に 含まれないような クラスにインクルードすべきではありません。
Precision.included(module_or_class)
Precision
がインクルードされた時に呼ばれます。詳細は
Module#included を参照してください。
このメソッドは、Precision
をインクルードするクラスやモジュー
ルに対してメソッド induced_from
を自動的に定義するためにあり
ます。*85
Precision.induced_from(number)
number を自分のクラスに変換した結果を返します。 デフォルトの 定義は、例外 TypeError を発生させるので、Mix-in したクラスで このメソッドを再定義する必要があります。再定義に、 Precision#prec を使うと、 無限ループになる可 能性があります。
prec(klass)
self
を精度 klass に変換した結果を返します。デフォルト
の定義では klass.induced_from(self)
を呼び出し、その結
果を返します。
新しく精度クラスを作るときは組み込みクラスの Precision.induced_from を変更するのではなく、この prec の再定義で対応するべきです。
prec_i
self
を Integer に変換します。prec(Integer)
と等
価です。
prec_f
self
を Float に変換します。prec(Float)
と等価で
す。
UNIX のシグナル関連の操作を行うモジュールです。
Signal.list
シグナル名とシグナル番号を対応づけた Hash オブジェクトを返し ます。
p Signal.list # => {"WINCH"=>28, "PROF"=>27, ...}
Signal.trap(signal, command)
Signal.trap(signal) { ... }
関数 trap と同じです
大きすぎるメモリを一度に確保しようとしたときに発生します。
また、メモリ不足に対しては通常 fatal エラーが発生しますが、セー フレベル($SAFE)が 4 以上のときは代わりにこの例外が発 生します。
スクリプトのエラーを表す例外です。
実装されていない機能が呼び出されたときに発生します。
シンタックスエラーがあったときに発生します。
添字が範囲外のときに発生します。
I/O でエラーが起きたときに発生します。
ruby 1.7 feature: 定義されていないメソッドの呼出しが行われたときに発生します。
self.bar => -:1: undefined method `bar' for #<Object:0x401a6c40> (NoMethodError)
メソッド呼出しの形式でなければ NameError 例外が発生します。
bar => -:1: undefined local variable or method `bar' for #<Object:0x401a6c40> (NameError)
範囲に関する例外。範囲外の数値変換 (Bignum から Fixnum へ の変換)などにより発生します。
正負の無限大や NaN
(Not a Number) を Bignum に変換しようと
したり、NaN
との比較を行ったときに発生します。
*86
正規表現のコンパイルに失敗した場合に発生します。
Regexp.new("*") => in `initialize': invalid regular expression; there's no previous \ pattern, to which '*' would define cardinality at 1: /*/ (RegexpError)
システムコールが失敗した時に発生する例外です。実際には
SystemCallError
そのものではなく、サブクラスである Errno
モジュールの内部クラス(各errno
と同じ名前)です。
SystemCallError === other ((<ruby 1.7 feature>))
other が SystemCallError
のサブクラスであれば真です。
(Module#=== と同じ)。
また、左辺が SystemCallError のサブクラスである場合、
other.errno
の値(nil
ならば そのクラスの
Errno 定数の値)が
self::Errno
と同じ場合に真を返します。
このメソッドにより、システムによって errno が同じ値の例外に対して 以下の例のように捕捉できるようになっています。
p Errno::EAGAIN::Errno p Errno::EWOULDBLOCK::Errno begin raise Errno::EAGAIN, "pseudo error" rescue Errno::EWOULDBLOCK p $! end # => 11 11 #<Errno::EAGAIN: pseudo error>
errno
システムから返された errno の値を返します。
実際にシステムコールエラーが発生してなければ nil
を返します。
例:
後半の例のように raiseによって故意にエラーが発生しているかのように 見せかける場合は注意してください。 begin open("nonexistent file") rescue Errno::ENOENT p Errno::ENOENT::Errno # => 2 p $!.errno # => 2 end begin raise Errno::ENOENT rescue Errno::ENOENT p Errno::ENOENT::Errno # => 2 p $!.errno # => nil end
まだ発生してない例外に対応する errno の値を知りたい場合は Errno::EXXX::Errno 定数を使用してください。
スタックレベルが深くなりすぎたときに発生します。
Thread 関連のエラーが起きたときに発生します。
0 で除算を行ったときに発生します。
Ruby は、ライブラリによるクラスやモジュール、メソッドの追加などの拡張 を行うことができます。以下は、標準で添付/配布されているライブラリの一 覧です。ライブラリの読み込みには require や load を使用します。
テキスト /ファイル /ネットワーク /入出力 /日本語 /数学 /データベース /画面制御/CUI /GUI /日付・時間 /マルチスレッド・同期 /Unix /MS Windows /正規表現 /GC /デザインパターン /開発ツール /コマンドライン /その他
cgi/session.rb CGIセッション管理
cgi.rb CGI作成支援
complex.rb 複素数クラス
curses.so 端末操作ライブラリ curses のインターフェイス
date.rb 日付クラス
dbm.so ndbm をハッシュのように使うためのライブラリ
delegate.rb 委譲を支援するクラス
e2mmap.rb 例外クラスとメッセージのマッピング
etc.so /etc/passwd
などを操作するライブラリ
find.rb ファイル探索モジュール
forwardable.rb クラスに対してメソッドの委譲機能を定義(ruby-src:ruby/doc/forwardable.rd.ja を参照)
gdbm.so gdbm (GNU dbm) をハッシュのように使うためのライブラリ
kconv.rb 漢字コード変換
mailread.rb メールから情報を得る
matrix.rb 行列クラス
md5.rb このライブラリはobsoleteです(digest/md5.soを使ってください)
net/http.rb ruby-src:ruby/doc/net/http.rd.ja
net/pop.rb ruby-src:ruby/doc/net/pop.rd.ja
net/smtp.rb ruby-src:ruby/doc/net/smtp.rd.ja
nkf.so 日本語文字コードエンコーディング変換
observer.rb Observer パターンの Ruby 実装
ostruct.rb Python 風の「attr on write」Struct
parsedate.rb 日付フォーマットの解析
ping.rb ホストに対するパケット到達の検証
pstore.rb オブジェクト永続化
pty.so 疑似端末(Pseudo tTY)を扱うモジュール
rbconfig.rb Ruby インタプリタの設定情報
readline.so GNU Readline インタフェース
resolv.rb Ruby版 リゾルバ
singleton.rb Singleton パターンの Ruby 実装
socket.so ソケット拡張ライブラリ
tempfile.rb テンポラリファイル生成
thread.rb スレッドに関するユーティリティ
timeout.rb タイムアウトを行うメソッド timeout
tracer.rb Ruby のトレーサ
weakref.rb GC される「弱い」リファレンスを作成する
Win32API.so Win32 API をコールするクラス (win32 専用)
--> CGI::Session
[2001/08/26] by るびきち
CGIのセッション管理を行うライブラリ。 セッションとは、複数回のHTTPリクエストで一連の動作をさせるものである。*90 セッション管理には従来通り、cgi.rbが提供するクッキーを使用してもいいが、このcgi/session.rbを使用した方がよりわかりやすい。 セッション情報はHashライクなインターフェースである。
このcgi/session.rbを使うと、セッション情報はサーバ側で管理し、クライアントにはそのセッション情報に対応するセッションIDをクッキーで渡すことになる。 そのクッキーはexpiresが指定されていないために、ブラウザを終了した時点で消滅する。
cgi = CGI::new session = CGI::Session::new( cgi [, aHash] )
CGI::Session::newにCGIオブジェクトを渡す。 オプション引数 aHash で使えるキーとその意味は次の通り。
クッキーのpathとして使われる.
(default: File::dirname(ENV["SCRIPT_NAME"])
, スクリプトのURIのpath部の最後のスラッシュまで)
クッキーと<FORM type=hidden>のnameとして使われる.
(default: "_session_id"
)
セッションIDとして使われる.
デフォルトのデータベースであるFileStore
を用いる場合, 値は英数字だけからなる文字列で無ければならない.
このオプションが指定するとリクエストにセッションIDが含まれても無視される.
(default: ランダムに生成される)
値がtrueのとき強制的に新しいセッションを始める.
このオプションが指定するとリクエストにセッションIDが含まれても無視される. (default: false
)
データベースクラス.
(defalut: CGI::Session::FileStore
)
CGI::Session::FileStore
がセッションデータを作成するディレクトリの名前.
(default: ENV["TMP"] || "/tmp"
)
CGI::Session::FileStore
がセッションデータのファイル名に与えるプレフィックス.
(default: ""
)
session['name'] = "rubikitch"
CGI::SessionオブジェクトはHashのようなものであり、キーに対応する値を記録する。
name = session['name']
別なCGIでこのセッション情報を取り出すときは、このようにする。
ヘッダ出力はCGI#out、CGI#headerを使っている限り、通常通りで構わない。 cgi/session.rbは内部的にクッキーを使用しているが、これらのメソッドが面倒を見てくれるので、意識をする必要はない。
umask値が0022ならばセッション情報ファイルのパーミッションが644になるので、任意のユーザがそのセッション情報ファイルを見ることができる。 それが嫌な場合はCGI::Sessionオブジェクト生成前にumask値を設定しておこう。
ただ、名前を入力するとあいさつをするだけのつまらないCGI。
デモ会場はこちら。
#!/usr/bin/ruby require 'kconv' require 'cgi' require 'cgi/session' class SessionDemo def initialize @cgi = CGI::new File.umask(0066) # セッションファイルは誰にも読まれたくないよ @session = CGI::Session::new( @cgi ) # セッションはこうして生成する。 @cmd = @cgi['cmd'].first || 'start' @header = { "type" => "text/html", "charset" => "euc-jp" } __send__("cmd_#{@cmd}") end def cmd_start @cgi.out( @header ) { <<-END <html><head><title>CGI::Session Demo</title></head> <body> <form action="#{ENV['SCRIPT_NAME']}" method="get"> <p> あなたの名前は? <input type="text" name="name"> <input type="hidden" name="cmd" value="hello"> <input type="submit" value="です。"> </p> </form> </body> END } end def cmd_hello name = Kconv::toeuc( @cgi['name'].first ) @session['name'] = name # セッションに記憶 @cgi.out( @header ) { # セッション情報は隠れクッキーで保持されるため、CGI#outで出力 <<-END <html><head><title>CGI::Session Demo</title></head> <body> <p>こんにちは、#{name}さん</p> <p><a href="#{ENV['SCRIPT_NAME']}?cmd=bye">[次へ]</p> </body> END } end def cmd_bye name = @session['name'] # セッションデータから取り出し @cgi.out( @header ) { <<-END <html><head><title>CGI::Session Demo</title></head> <body> <p>#{name}さん、さようなら</p> <p><a href="#{ENV['SCRIPT_NAME']}">[戻る]</p> </body> END } end end SessionDemo.new
このライブラリはobsoleteです。 cgi.rbを使ってください。
[2001/03/17] by るびきち
CGIサポートライブラリ
Version 2.1.0
require "cgi" cgi = CGI.new values = cgi['field_name'] # <== 'field_name' の配列 # 'field_name' が指定されていなかったら、 (({[]}))を返す。 fields = cgi.keys # <== field nameの配列 # フォームに 'field_name' というfield nameがあるときに真 cgi.has_key?('field_name') cgi.has_key?('field_name') cgi.include?('field_name')
require "cgi" cgi = CGI.new params = cgi.params
cgi.params
はHashである。
cgi.params['new_field_name'] = ["value"] # 新しいパラメータを加える cgi.params['field_name'] = ["new_value"] # パラメータの値を変える cgi.params.delete('field_name') # パラメータを消去 cgi.params.clear # 全パラメータを消去
require "pstore" db = PStore.new("query.db") db.transaction do db["params"] = cgi.params end
PStoreを参照。
require "pstore" db = PStore.new("query.db") db.transaction do cgi.params = db["params"] end
require "cgi" cgi = CGI.new values = cgi['field_name'] # <== field_nameの配列 values[0].read # <== values[0]の本文 values[0].local_path # <== values[0]のローカルファイルのパス values[0].original_filename # <== values[0]の元の名前 values[0].content_type # <== values[0]のcontent_type
values[0]
はTempfile
クラスのメソッドを持つ。
(Tempfile
クラスのオブジェクトはFile
クラスのメソッドを持つ。)
CGI::CGI_PARAMS
とCGI::CGI_COOKIES
を設定してからCGI.new
すると、あたかもフォームから入力があったかのようにローカルで実験できる。
ただし、両方とも設定しなければいけない。
#!/usr/bin/ruby require 'cgi' class CGI CGI_PARAMS={'form'=>['value']} CGI_COOKIES= nil end cgi = CGI.new puts cgi['form'].first # => "value"
require "cgi" cgi = CGI.new values = cgi.cookies['name'] # <== 'name' の配列 # 'name'が与えられてない場合は[]を返す。 names = cgi.cookies.keys # <== クッキーの名前の配列
また、cgi.cookies
はHashである。
require "cgi" cgi = CGI.new for name, cookie in cgi.cookies cookie.expires = Time.now + 30 end cgi.out("cookie" => cgi.cookies){"string"} cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... } require "cgi" cgi = CGI.new cgi.cookies['name'].expires = Time.now + 30 cgi.out("cookie" => cgi.cookies['name']){"string"}
あと、クッキーオブジェクトを作るを見ること。
require "cgi" cgi = CGI.new value = cgi.auth_type # ENV["AUTH_TYPE"]
<URL:http://www.w3.org/CGI/>を見ること。
AUTH_TYPE CONTENT_LENGTH CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO PATH_TRANSLATED QUERY_STRING REMOTE_ADDR REMOTE_HOST REMOTE_IDENT REMOTE_USER REQUEST_METHOD SCRIPT_NAME SERVER_NAME SERVER_PORT SERVER_PROTOCOL SERVER_SOFTWARE
content_lengthとserver_portはIntegerを返し、その他はStringを返す。
HTTP_COOKIEとHTTP_COOKIE2
value = cgi.raw_cookie # ENV["HTTP_COOKIE"] value = cgi.raw_cookie2 # ENV["HTTP_COOKIE2"]
その他の HTTP_*
value = cgi.accept # ENV["HTTP_ACCEPT"] value = cgi.accept_charset # ENV["HTTP_ACCEPT_CHARSET"]
HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT
require "cgi" cgi = CGI.new("html3") # HTML生成メソッドを追加 cgi.out() do cgi.html() do cgi.head{ cgi.title{"TITLE"} } + cgi.body() do cgi.form() do cgi.textarea("get_text") + cgi.br + cgi.submit end + cgi.pre() do CGI::escapeHTML( "params: " + cgi.params.inspect + "\n" + "cookies: " + cgi.cookies.inspect + "\n" + ENV.collect() do |key, value| key + " --> " + value + "\n" end.join("") ) end end end end # HTML生成メソッドを追加 CGI.new("html3") # html3.2 CGI.new("html4") # html4.0 (Strict) CGI.new("html4Tr") # html4.0 Transitional CGI.new("html4Fr") # html4.0 Frameset
CGI.escape(string)
文字列をURLエンコードする
例: url_encoded_string = CGI::escape("string")
CGI.unescape(string)
URLエンコードされた文字列を元に戻す
例: string = CGI::unescape("url encoded string")
CGI.escapeHTML(string)
HTMLの &\"<> をエスケープ
例: CGI::escapeHTML("string")
CGI.unescapeHTML(string)
HTMLエスケープされた文字列を元に戻す
例: CGI::unescapeHTML("HTML escaped string")
CGI.escapeElement(string, *element)
特定の要素だけをHTMLエスケープする。
例: print CGI::escapeElement('<BR><A HREF="url"></A>', "A", "IMG") # => "<BR><A HREF="url"></A>" print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"]) # => "<BR><A HREF="url"></A>"
CGI.unescapeElement(string, *element)
特定の要素だけをHTMLエスケープから戻す。
例: print CGI::unescapeElement( CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG") # => "<BR><A HREF="url"></A>" print CGI::unescapeElement( CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"]) # => "<BR><A HREF="url"></A>"
CGI.rfc1123_date(time)
RFC:1123の日付文字列を作成
例: CGI::rfc1123_date(Time.now) # => Sat, 1 Jan 2000 00:00:00 GMT
CGI#header(options = "text/html")
HTTPヘッダ文字列を作成
例: header # Content-Type: text/html header("text/plain") # Content-Type: text/plain header({"nph" => true, "status" => "OK", # == "200 OK" # "status" => "200 GOOD", "server" => ENV['SERVER_SOFTWARE'], "connection" => "close", "type" => "text/html", "charset" => "iso-2022-jp", # Content-Type: text/html; charset=iso-2022-jp "language" => "ja", "expires" => Time.now + 30, "cookie" => [cookie1, cookie2], "my_header1" => "my_value" "my_header2" => "my_value"})
CGI#headerはcharsetを変換しない。
ステータス:
"OK" --> "200 OK" "PARTIAL_CONTENT" --> "206 Partial Content" "MULTIPLE_CHOICES" --> "300 Multiple Choices" "MOVED" --> "301 Moved Permanently" "REDIRECT" --> "302 Found" "NOT_MODIFIED" --> "304 Not Modified" "BAD_REQUEST" --> "400 Bad Request" "AUTH_REQUIRED" --> "401 Authorization Required" "FORBIDDEN" --> "403 Forbidden" "NOT_FOUND" --> "404 Not Found" "METHOD_NOT_ALLOWED" --> "405 Method Not Allowed" "NOT_ACCEPTABLE" --> "406 Not Acceptable" "LENGTH_REQUIRED" --> "411 Length Required" "PRECONDITION_FAILED" --> "412 Rrecondition Failed" "SERVER_ERROR" --> "500 Internal Server Error" "NOT_IMPLEMENTED" --> "501 Method Not Implemented" "BAD_GATEWAY" --> "502 Bad Gateway" "VARIANT_ALSO_VARIES" --> "506 Variant Also Negotiates"
CGI#out(options = "text/html")
HTTPヘッダとブロックで与えられた文字列を$DEFAULT_OUTPUT ($>)
へ出力。
cgi = CGI.new cgi.out{ "string" } # Content-Type: text/html # Content-Length: 6 # # string cgi.out("text/plain"){ "string" } # Content-Type: text/plain # Content-Length: 6 # # string cgi.out({"nph" => true, "status" => "OK", # == "200 OK" "server" => ENV['SERVER_SOFTWARE'], "connection" => "close", "type" => "text/html", "charset" => "iso-2022-jp", # Content-Type: text/html; charset=iso-2022-jp "language" => "ja", "expires" => Time.now + (3600 * 24 * 30), "cookie" => [cookie1, cookie2], "my_header1" => "my_value", "my_header2" => "my_value"}){ "string" }
HEADリクエスト("HEAD" == REQUEST_METHOD
)の場合はHTTPヘッダのみを出力する。
charsetが"iso-2022-jp"
か"euc-jp"
か"shift_jis"
である場合、
charsetを変換し、languageを"ja"
にする。
CGI#print(*options)
出力。
例: cgi = CGI.new cgi.print # default: cgi.print == $DEFAULT_OUTPUT.print
CGI::Cookie.new(name = "", *value)
CGI::Cookie#name
CGI::Cookie#name=
CGI::Cookie#value
CGI::Cookie#value=
CGI::Cookie#path
CGI::Cookie#path=
CGI::Cookie#domain
CGI::Cookie#domain=
CGI::Cookie#expires
CGI::Cookie#expires=
CGI::Cookie#secure
CGI::Cookie#secure=
クッキーオブジェクトを作成。
例: cookie1 = CGI::Cookie::new("name", "value1", "value2", ...) cookie1 = CGI::Cookie::new({"name" => "name", "value" => "value"}) cookie1 = CGI::Cookie::new({'name' => 'name', 'value' => ['value1', 'value2', ...], 'path' => 'path', # optional 'domain' => 'domain', # optional 'expires' => Time.now, # optional 'secure' => true # optional }) cgi.out({"cookie" => [cookie1, cookie2]}){ "string" } name = cookie1.name values = cookie1.value path = cookie1.path domain = cookie1.domain expires = cookie1.expires secure = cookie1.secure cookie1.name = 'name' cookie1.value = ['value1', 'value2', ...] cookie1.path = 'path' cookie1.domain = 'domain' cookie1.expires = Time.now + 30 cookie1.secure = true
CGI::Cookie.parse(raw_cookie)
クッキー文字列の解析。
例: cookies = CGI::Cookie::parse("raw_cookie_string") # { "name1" => cookie1, "name2" => cookie2, ... }
CGI::parse(query)
QUERY_STRINGの解析
例: params = CGI::parse("query_string") # {"name1" => ["value1", "value2", ...], # "name2" => ["value1", "value2", ...], ... }
CGI.pretty(string, shift = " ")
HTMLを整形。
例: print CGI::pretty("<HTML><BODY></BODY></HTML>") # <HTML> # <BODY> # </BODY> # </HTML> print CGI::pretty("<HTML><BODY></BODY></HTML>", "\t") # <HTML> # <BODY> # </BODY> # </HTML>
例: cgi = CGI.new("html3") # HTML生成メソッドを追加 cgi.element cgi.element{ "string" } cgi.element({ "ATTRILUTE1" => "value1", "ATTRIBUTE2" => "value2" }) cgi.element({ "ATTRILUTE1" => "value1", "ATTRIBUTE2" => "value2" }){ "string" } # HTML生成メソッドを追加 CGI.new("html3") # html3.2 CGI.new("html4") # html4.0 (Strict) CGI.new("html4Tr") # html4.0 Transitional CGI.new("html4Fr") # html4.0 Frameset
CGI::HtmlExtension#a(href = "")
例: a("url") # = a({ "HREF" => "url" })
CGI::HtmlExtension#base(href = "")
例: base("url") # = base({ "HREF" => "url" })
CGI::HtmlExtension#blockquote(cite = nil)
例: blockquote("url"){ "string" } # = blockquote({ "CITE" => "url" }){ "string" }
CGI::HtmlExtension#caption(align = nil)
例: caption("align"){ "string" } # = caption({ "ALIGN" => "align" }){ "string" }
CGI::HtmlExtension#checkbox(name = "", value = nil, checked = nil)
例: checkbox("name") # = checkbox({ "NAME" => "name" }) checkbox("name", "value") # = checkbox({ "NAME" => "name", "VALUE" => "value" }) checkbox("name", "value", true) # = checkbox({ "NAME" => "name", "VALUE" => "value", "CHECKED" => true })
CGI::HtmlExtension#checkbox_group(name = "", *values)
例: checkbox_group("name", "foo", "bar", "baz") # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo # <INPUT TYPE="checkbox" NAME="name" VALUE="bar">bar # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz checkbox_group("name", ["foo"], ["bar", true], "baz") # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo # <INPUT TYPE="checkbox" SELECTED NAME="name" VALUE="bar">bar # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz checkbox_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz") # <INPUT TYPE="checkbox" NAME="name" VALUE="1">Foo # <INPUT TYPE="checkbox" SELECTED NAME="name" VALUE="2">Bar # <INPUT TYPE="checkbox" NAME="name" VALUE="Baz">Baz checkbox_group({ "NAME" => "name", "VALUES" => ["foo", "bar", "baz"] }) checkbox_group({ "NAME" => "name", "VALUES" => [["foo"], ["bar", true], "baz"] }) checkbox_group({ "NAME" => "name", "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"] })
CGI::HtmlExtension#file_field(name = "", size = 20, maxlength = nil)
例: file_field("name") # <INPUT TYPE="file" NAME="name" SIZE="20"> file_field("name", 40) # <INPUT TYPE="file" NAME="name" SIZE="40"> file_field("name", 40, 100) # <INPUT TYPE="file" NAME="name" SIZE="40", MAXLENGTH="100"> file_field({ "NAME" => "name", "SIZE" => 40 }) # <INPUT TYPE="file" NAME="name" SIZE="40">
CGI::HtmlExtension#form(method = "post", action = nil, enctype = "application/x-www-form-urlencoded")
例: form{ "string" } # <FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded">string</FORM> form("get"){ "string" } # <FORM METHOD="get" ENCTYPE="application/x-www-form-urlencoded">string</FORM> form("get", "url"){ "string" } # <FORM METHOD="get" ACTION="url" ENCTYPE="application/x-www-form-urlencoded">string</FORM> form({"METHOD" => "post", ENCTYPE => "enctype"}){ "string" } # <FORM METHOD="post" ENCTYPE="enctype">string</FORM>
CGI::HtmlExtension#hidden(name = "", value = nil)
例: hidden("name") # <INPUT TYPE="hidden" NAME="name"> hidden("name", "value") # <INPUT TYPE="hidden" NAME="name" VALUE="value"> hidden({ "NAME" => "name", "VALUE" => "reset", "ID" => "foo" }) # <INPUT TYPE="hidden" NAME="name" VALUE="value" ID="foo">
CGI::HtmlExtension#html(attributes = {})
例: html{ "string" } # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML>string</HTML> html({ "LANG" => "ja" }){ "string" } # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML LANG="ja">string</HTML> html({ "DOCTYPE" => false }){ "string" } # <HTML>string</HTML> html({ "DOCTYPE" => '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">' }){ "string" } # <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML>string</HTML> html({ "PRETTY" => " " }){ "<BODY></BODY>" } # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> # <HTML> # <BODY> # </BODY> # </HTML> html({ "PRETTY" => "\t" }){ "<BODY></BODY>" } # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> # <HTML> # <BODY> # </BODY> # </HTML> html("PRETTY"){ "<BODY></BODY>" } # = html({ "PRETTY" => " " }){ "<BODY></BODY>" } html(if $VERBOSE then "PRETTY" end){ "HTML string" }
CGI::HtmlExtension#image_button(src = "", name = nil, alt = nil)
例: image_button("url") # <INPUT TYPE="image" SRC="url"> image_button("url", "name", "string") # <INPUT TYPE="image" SRC="url" NAME="name", ALT="string"> image_button({ "SRC" => "url", "ATL" => "strng" }) # <INPUT TYPE="image" SRC="url" ALT="string">
CGI::HtmlExtension#img(src = "", alt = "", width = nil, height = nil)
例: img("src", "alt", 100, 50) # <IMG SRC="src" ALT="alt" WIDTH="100", HEIGHT="50"> img({ "SRC" => "src", "ALT" => "alt", "WIDTH" => 100, "HEIGHT" => 50 }) # <IMG SRC="src" ALT="alt" WIDTH="100", HEIGHT="50">
CGI::HtmlExtension#multipart_form(action = nil, enctype = "multipart/form-data")
例: multipart_form{ "string" } # <FORM METHOD="post" ENCTYPE="multipart/form-data">string</FORM> multipart_form("url"){ "string" } # <FORM METHOD="post" ACTION="url" ENCTYPE="multipart/form-data">string</FORM>
CGI::HtmlExtension#password_field(name = "", value = nil, size = 40, maxlength = nil)
例: password_field("name") # <INPUT TYPE="password" NAME="name" SIZE="40"> password_field("name", "value") # <INPUT TYPE="password" NAME="name" VALUE="value" SIZE="40"> password_field("password", "value", 80, 200) # <INPUT TYPE="password" NAME="name" VALUE="value", SIZE="80", MAXLENGTH="200"> password_field({ "NAME" => "name", "VALUE" => "value" }) # <INPUT TYPE="password" NAME="name" VALUE="value">
CGI::HtmlExtension#popup_menu(name = "", *values)
例: popup_menu("name", "foo", "bar", "baz") # <SELECT NAME="name"> # <OPTION VALUE="foo">foo</OPTION> # <OPTION VALUE="bar">bar</OPTION> # <OPTION VALUE="baz">baz</OPTION> # </SELECT> popup_menu("name", ["foo"], ["bar", true], "baz") # <SELECT NAME="name"> # <OPTION VALUE="foo">foo</OPTION> # <OPTION VALUE="bar" SELECTED>bar</OPTION> # <OPTION VALUE="baz">baz</OPTION> # </SELECT> popup_menu("name", ["1", "Foo"], ["2", "Bar", true], "Baz") # <SELECT NAME="name"> # <OPTION VALUE="1">Foo</OPTION> # <OPTION SELECTED VALUE="2">Bar</OPTION> # <OPTION VALUE="Baz">Baz</OPTION> # </SELECT> popup_menu({"NAME" => "name", "SIZE" => 2, "MULTIPLE" => true, "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"] }) # <SELECT NAME="name" MULTIPLE SIZE="2"> # <OPTION VALUE="1">Foo</OPTION> # <OPTION SELECTED VALUE="2">Bar</OPTION> # <OPTION VALUE="Baz">Baz</OPTION> # </SELECT>
CGI::HtmlExtension#radio_button(name = "", value = nil, checked = nil)
例: radio_button("name", "value") # <INPUT TYPE="radio" NAME="name", VALUE="value"> radio_button("name", "value", true) # <INPUT TYPE="radio" NAME="name", VALUE="value", CHECKED> radio_button({ "NAME" => "name", "VALUE" => "value", "ID" => "foo" }) # <INPUT TYPE="radio" NAME="name" VALUE="value" ID="foo">
CGI::HtmlExtension#radio_group(name = "", *values)
例: radio_group("name", "foo", "bar", "baz") # <INPUT TYPE="radio" NAME="name" VALUE="foo">foo # <INPUT TYPE="radio" NAME="name" VALUE="bar">bar # <INPUT TYPE="radio" NAME="name" VALUE="baz">baz radio_group("name", ["foo"], ["bar", true], "baz") # <INPUT TYPE="radio" NAME="name" VALUE="foo">foo # <INPUT TYPE="radio" SELECTED NAME="name" VALUE="bar">bar # <INPUT TYPE="radio" NAME="name" VALUE="baz">baz radio_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz") # <INPUT TYPE="radio" NAME="name" VALUE="1">Foo # <INPUT TYPE="radio" SELECTED NAME="name" VALUE="2">Bar # <INPUT TYPE="radio" NAME="name" VALUE="Baz">Baz radio_group({ "NAME" => "name", "VALUES" => ["foo", "bar", "baz"] }) radio_group({ "NAME" => "name", "VALUES" => [["foo"], ["bar", true], "baz"] }) radio_group({ "NAME" => "name", "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"] })
CGI::HtmlExtension#reset(value = nil, name = nil)
例: reset # <INPUT TYPE="reset"> reset("reset") # <INPUT TYPE="reset" VALUE="reset"> reset({ "VALUE" => "reset", "ID" => "foo" }) # <INPUT TYPE="reset" VALUE="reset" ID="foo">
CGI::HtmlExtension#scrolling_list(name = "", *values)
例: scrolling_list({"NAME" => "name", "SIZE" => 2, "MULTIPLE" => true, "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"] }) # <SELECT NAME="name" MULTIPLE SIZE="2"> # <OPTION VALUE="1">Foo</OPTION> # <OPTION SELECTED VALUE="2">Bar</OPTION> # <OPTION VALUE="Baz">Baz</OPTION> # </SELECT>
CGI::HtmlExtension#submit(value = nil, name = nil)
例: submit # <INPUT TYPE="submit"> submit("ok") # <INPUT TYPE="submit" VALUE="ok"> submit("ok", "button1") # <INPUT TYPE="submit" VALUE="ok" NAME="button1"> submit({ "VALUE" => "ok", "NAME" => "button1", "ID" => "foo" }) # <INPUT TYPE="submit" VALUE="ok" NAME="button1" ID="foo">
CGI::HtmlExtension#text_field(name = "", value = nil, size = 40, maxlength = nil)
例: text_field("name") # <INPUT TYPE="text" NAME="name" SIZE="40"> text_field("name", "value") # <INPUT TYPE="text" NAME="name" VALUE="value" SIZE="40"> text_field("name", "value", 80) # <INPUT TYPE="text" NAME="name" VALUE="value", SIZE="80"> text_field("name", "value", 80, 200) # <INPUT TYPE="text" NAME="name" VALUE="value", SIZE="80", MAXLENGTH="200"> text_field({ "NAME" => "name", "VALUE" => "value" }) # <INPUT TYPE="text" NAME="name" VALUE="value">
CGI::HtmlExtension#textarea(name = "", cols = 70, rows = 10)
例: textarea("name") # = textarea({ "NAME" => "name", "COLS" => 70, "ROWS" => 10 }) textarea("name", 40, 5) # = textarea({ "NAME" => "name", "COLS" => 40, "ROWS" => 5 })
Thu Oct 12 01:16:59 JST 2000 - wakou
Wed Sep 13 06:09:26 JST 2000 - wakou
Tue Sep 12 06:56:51 JST 2000 - wakou
2000/08/09 04:32:22 - matz
2000/06/23 07:01:34 - matz
Sun Jun 18 23:31:44 JST 2000 - wakou
2000/06/13 15:49:27 - wakou
2000/06/03 18:16:17 - wakou
2000/05/30 19:04:08 - wakou
2000/05/24 06:58:51 - wakou
2000/05/08 21:51:30 - wakou
2000/05/07 21:51:14 - wakou
2000/05/02 21:44:12 - wakou
2000/04/03 18:31:42 - wakou
1999/12/06 20:16:34 - wakou
1999/11/29 21:35:58 - wakou
1999/09/13 23:00:58 - wakou
1999/08/05 18:04:59 - wakou
typo. thanks to MJ Ray <markj@altern.org>
HTTP_STATUS["NOT_INPLEMENTED"] --> HTTP_STATUS["NOT_IMPLEMENTED"]
1999/07/20 20:44:31 - wakou
CGI::print --> CGI#out
cgi = CGI.new cgi.out{"string"} # old: CGI::print{"string"}
CGI::cookie --> CGI::Cookie::new
cookie1 = CGI::Cookie::new # old: CGI::cookie
1999/06/29 06:50:21 - wakou
COUTION! incompatible change.
query = CGI.new cookies = query.cookies # old: query.cookie values = query.cookies[name] # old: query.cookie[name]
1999/06/21 21:05:57 - wakou
1999/06/20 23:29:12 - wakou
Mon Jun 14 17:49:32 JST 1999 - matz
Fri Jun 11 11:19:11 JST 1999 - matz
1999/06/03 06:48:15 - wakou
1999/05/24 07:05:41 - wakou
--> Complex
実部。
虚部。
虚数単位。
端末ライブラリ curses のインターフェイス。
(?) がついているのはわからないもの。
(!) がついているものは(青木が)仕様を変えるべきだと 思ったところです。
スクリーンを curses のために初期化します。
Curses
モジュールのすべてのメソッドはこのメソッドを
呼び出してからでないと使えません。
curses スクリーンを閉じます。これ以後 Curses
モジュール
のメソッドを呼び出すとすべて例外になります。
画面全体を表す Curses::Window
オブジェクトを返します。
stdscr の表示を更新します。
(?) wnoutrefresh
と組み合わせないと意味ない?
stdscr
の文字を消去します。
この消去は refresh
を待たずにすぐ実行されます。
入力のエコーを有効にします。
入力のエコーをやめます。
キーボード入力のバッファリングをやめます。
キーボード入力のバッファリングを有効にします。
cooked モードのとき、return キーの入力に対して LF (Ctrl-j) を返すようにします。
cooked モードのとき、return キーの入力に対して CR (Ctrl-m) を返すようにします。
キーボード入力のバッファリングと Ctrl-C など 特殊キーの処理をやめます (raw モード)。
キーボード入力のバッファリングと Ctrl-C など 特殊キーの処理を行うようにします (cooked モード)。
音を出します。 この機能がないところでは単に無視されます。
画面を一瞬点滅させます。 この機能がないところでは単に無視されます。
標準入力から 1 バイト読み込みます。 返り値は ASCII コードを示す整数です。
標準入力から一行読み込みます。 返り値は文字列です。
このメソッドは getnstr()
が実装されていない
プラットホームではバッファオーバーフローをおこす恐れが
あります。
文字 ch (ASCII コードを示す整数)を押し戻します。
stdscr
のカーソルを座標 (x,y) に移動します。
座標はともに 0 が始点です。
文字がない場所に setpos
して文字をなにも書かずに
refresh
するといきなりプロセスが終了してしまうライブラリが
あるようだ(?) 例:linux のノーマル curses
以降書き込む文字を強調します。 「強調」は反転であることが多いようですが、 そう決められているわけではありません。
強調する文字の書き込みを終えます。
stdscr のカーソルの位置に ch (1 バイト)を上書きします。
stdscr のカーソルの位置に ch (1 バイト)を挿入します。
stdscr のカーソルの位置に文字列 str を挿入します。
stdscr のカーソルの位置から 1 バイト削除します。
stdscr のカーソルがある行を削除し、後の行を上に詰めます。
画面に表示可能な行数を返します。
画面に表示可能な桁数(バイト)を返します。 ただし実際にはもう 1 バイト少なくしか表示できないライブラリが あるようです。
stdscr のカーソル位置から 1 バイト読みとって返します。
画面の座標 (x,y) を左上端とし、幅 width
高さ height とする curses のトップレベルウィンドウを
作成し、それを表現する Curses::Window
オブジェクトを
返します。
画面の座標 (x,y) を左上端とし、幅 width
高さ height とするサブウィンドウを作成し、
それを表現する Curses::Window
オブジェクトを返します。
ウィンドウを閉じます。以降のこのウィンドウオブジェクトに 対する操作は例外を発生します。
ウィンドウの表示を消去します。 この操作は即座に実行されます。
ウィンドウの表示を更新します。
縦の線に ver_char、横の線に hor_char を使い ウィンドウに沿って箱を書きます。線は普通にウィンドウ内に 書かれるだけなので上書きしないよう注意してください。
ウィンドウを (x,y) に移動します。
(!) 親ウィンドウからはみだす位置を指定すると無視されます。
ウィンドウ内の (x,y) にカーソルを移動します。
ウィンドウ内におけるカーソルの行番号を返します。 一行目が 0 です。
ウィンドウ内におけるカーソルの桁番号を返します。 一桁目が 0 です。
移動可能な最大の y 座標を返します。 表示可能な行 + 1 です。
移動可能な最大の x 座標を返します。 表示可能なバイト数 + 1 です。
親ウィンドウの中でウィンドウの左上がある y 座標を返します。 始点は 0 です。
親ウィンドウの中でウィンドウの左上がある x 座標を返します。 始点は 0 です。
以後書き込む文字を強調表示します。
強調書き込みを終了します。
ウィンドウのカーソル位置から 1 バイト読みとって返します。
ウィンドウのカーソル位置に ch (1 バイト)を上書きします。
ウィンドウのカーソル位置に ch (1 バイト)を挿入します。
ウィンドウのカーソル位置に文字列 str を上書きします。
ウィンドウへの入力から 1 バイト読みこみます。
ウィンドウへの入力から一行読みこみます。
ウィンドウのカーソル位置から 1 バイト消去します。
ウィンドウの、カーソルがある行を消去します。
--> Date
正しい年日付であれば、相当するユリウス日を返します。 そうでないなら、偽を返します。
new1、および new2 も参照してください。
正しい暦日付であれば、相当するユリウス日を返します。 そうでないなら、偽を返します。
new1、および new3 も参照してください。
正しい暦週であれば、相当するユリウス日を返します。 そうでないなら、偽を返します。
new1、および neww も参照してください。
ユリウス日に相当する日付オブジェクトを生成します。
ユリウス日は 紀元前4713年1月1日 (ユリウス暦) 正午 (グリニッジ平均時) を 暦元とした通日 (経過日数) です。
このクラスで、ユリウス日は、 ただ日付の通し番号として使われます; 故に、 普通は端数はありません (それは正午であることを示します)。
このクラスのいくつかの重要なメソッドで、 負のユリウス日は保証されません。
new3 も参照してください。
年日付に相当する日付オブジェクトを生成します。
年日付は、暦年 (年)、 および暦年の中の序数 (年の日) によって指定される特定の日の日付です。
月の日は負、 または正の数でなければなりません (負のときは最後からの序数)。 零であってはなりません。
new1、および new3 も参照してください。
暦日付に相当する日付オブジェクトを生成します。
暦日付は、暦年 (年)、暦月 (月)、 および暦月の中の序数 (月の日) によって指定される特定の日の日付です。
このクラスでは、紀元前の年を天文学の流儀で勘定します。 1年の前は零年、零年の前は-1年、のようにします。
月、および月の日は負、 または正の数でなければなりません (負のときは最後からの序数)。 零であってはなりません。
省略できる最後の引数は、 グレゴリオ暦をつかい始めた日をあらわすユリウス日でなければなりません。 ビッグバンの代わりに真 (グレゴリオ暦の指定)、 ビッグクランチの代わりに偽 (ユリウス暦の指定) を与えることもできます。
new1 も参照してください。
暦週に相当する日付オブジェクトを生成します。
暦週は、暦年中の序数によって指定される特定の7日の期間であり、 月曜から始まります。 その年の第1暦週は、最初の木曜日を含む週とします。 これは、1月4日を含む週と同じです。
週、および週の日 (曜日) は負、 または正の数でなければなりません (負のときは最後からの序数)。 零であってはなりません。
このメソッドに改暦前の日付を与えることはできません。
new1、および new3 も参照してください。
現在の日付に相当する日付オブジェクトを生成します。
self から n 日後の日付オブジェクトを返します。 n は数値でなければなりません。
x が日付オブジェクトなら、ふたつの差を返します。 あるいは x が数値ならば、self より x 日前の日付を返します。
self より n ヶ月前の日付オブジェクトを返します。 n は数値でなければなりません。
ふたつを比較し、-1、零、あるいは 1 を返します。 other は日付オブジェクトか、ユリウス日をあらわす数値でなければなりません。
同じ日なら真を返します。
self から n ヶ月後の日付オブジェクトを返します。 n は数値でなければなりません。
暦週の日 (曜日) を返します (1-7、月曜は1)。
暦週を返します (1-53)。
暦週における年を返します。
このメソッドは、step(min, -1){|date| ...}
と等価です。
このメソッドは、newsg(Date::ENGLAND)
と等価です。
このメソッドは、newsg(Date::GREGORIAN)
と等価です。
このメソッドは、newsg(Date::ITALY)
と等価です。
ユリウス日を返します。
このメソッドは、newsg(Date::JULIAN)
と等価です。
リリウス日を返します。
リリウス日は、西暦1582年10月15日 (グレゴリオ暦) を暦元とした通日です。
閏年なら真を返します。
月の日を返します (1-31)。
修正ユリウス日を返します (正午として)。
修正ユリウス日は 西暦1858年11月17日 (グレゴリオ暦) 零時 (協定世界時) を 暦元とした通日 (経過日数) です。
月を返します (1-12)。
self を複製して、その改暦日を設定しなおします。
new3 も参照してください。
改暦日をあらわすユリウス日を返します。
new3 も参照してください。
ブロックの評価を繰り返します。ブロックは日付オブジェクトをとります。 limit は日付オブジェクトでなければなりません、 また step は非零でなければなりません。
翌日の日付オブジェクトを返します。
切詰ユリウス日を返します (正午として)。
このクラスで、切詰ユリウス日は 西暦1968年5月24日 (グレゴリオ暦) 零時 (協定世界時) を 暦元とした通日 (経過日数) です。
TJD の使用はまったく勧められません。
"FLOOR(tjd/10000)" と "tjd MOD 10000" の対を返します。 ふたつ目の要素は、もうひとつの TJD です。 それは、本当の TJD かもしれません。 CCSDS 301.0-B-2 を参照してください。
TJD の使用はまったく勧められません。
ISO 8601:1988 書式 (CCYY-MM-DD) の文字列を返します。
このメソッドは、step(max, 1){|date| ...}
と等価です。
曜日を返します (0-6、日曜日は零)。
年の日を返します (1-366)。
年を返します。
このライブラリは date.rb に置き換えられました
--> DBM
NDBMファイルをアクセスするクラス。キー、データともに文字列でなければな らないという制限と、データがファイルに保存されるという点を除いては Hashクラスと全く同様に扱うことがでます。
dbnameで指定したデータベースをモードを
modeに設定してオープンします。modeの省
略値は0666です。modeとしてnil
を指定
するとデータベースが存在しない時には新たなデータベースを作らず
nil
を返します。
keyをキーとする値を返します。
keyをキーとして、valueを格納します。
valueとしてnil
を指定すると、keyに対
する項目を削除します。
DBMファイルを空にします。
DBMファイルをクローズします。以後の操作は例外を発生させます。
keyをキーとする項目を削除します。
ブロックを評価した値が真であれば該当する項目を削除します。
各要素に対するイテレータ。
全てのkeyに対して繰り返すイテレータ。
全てのvalueに対して繰り返すイテレータ。
データベースが空の時、真を返します。
keyがデータベース中に存在する時、真を返します。
valueを値とする組がデータベース中に存在する時、真を返します。
各引数の値をキーとする要素を含む配列を返します。
データベース中に存在するキー全てを含む配列を返します。
データベース中の要素の数を返します。(注意:現在の実現では要素数を数 えるためにデータベースを全部検索します)
データベース中の要素を一つ取り出し、データベースから削除します。
データベース中に存在する値全てを含む配列を返します。
メソッドの委譲(delegation)を行う。
Delegatorクラスは指定したオブジェクトにメソッドの実行を委譲する。
Delegatorクラスを利用する場合はこれを継承して__getobj__
メソッドを
再定義して委譲先のオブジェクトを指定する。
SimpleDelegatorはDelegatorの利用例の一つであり、コンストラクタに 渡されたオブジェクトにメソッドの実行を委譲する。
関数DelegateClass(supperclass)はsuperclassクラスの オブジェクトをひとつとり、そのオブジェクトにインスタンスメソッドを委譲す るクラスを定義して返す。
require 'delegate' foo = Object::new def foo.test p 25 end foo2 = SimpleDelegator::new(foo) foo2.test # => 25 class ExtArray<DelegateClass(Array) def initialize() super([]) end end a = ExtArray::new p a.type # => ExtArray a.push 25 p a # => [25]
与えられたオブジェクトの持つメソッドに関して委譲用のメソッド定義を 提供するクラス。
コンストラクタで指定されたオブジェクトのもつインスタンスメソッドのうち、
自分の持たないメソッドについて、
__getobj__
が返すオブジェクトに実行を委譲するようメソッドを定義する。
Delegator#initialize(obj)
objのもつインスタンスメソッドのうち、
自分の持たないメソッドについて、
__getobj__
が返すオブジェクトに実行を委譲する
ようインスタンスメソッドを定義する。
Delegator#__getobj__
委譲先のオブジェクトを返す。 デフォルトではNotImplementErrorを発生するので、サブクラスで 再定義する必要がある。
Delegatorクラスをそのまま利用した、 指定したオブジェクトにメソッドを委譲するクラス。
Delegator
SimpleDelegator.new(obj)
objがもつメソッドについて、実行をobjに委譲する
オブジェクトを生成する。
SimpleDelegator#__getobj__
委譲先のオブジェクトを返す。
SimpleDelegator#__setobj__(obj)
委譲先のオブジェクトをobjに変更する。
委譲するメソッドの定義は生成時にのみ行われるため、 以前の委譲先オブジェクトとobjの間でインスタンスメソッドに 違いがあっても、 委譲するインスタンスメソッドの再設定は行われないことに注意。
DelegateClass(superclass)
クラスsuperclassのインスタンスへメソッドを委譲するクラスを 定義し、そのクラスを返す。
Object#method_missing(method_symbol, ...)
メソッドがオブジェクトに定義されていなかったときにこのメソッドが 呼ばれる。これを使って自分の知らないメソッドをほかのオブジェクト に委譲することができる。
例:
def hoge.method_missing(message, *arg) @to_obj.send(message, *arg) end
メッセージダイジェストライブラリ ext/digest/digest.txt を参照
例外クラスに特定のエラーメッセージ用フォーマットを関連づけます。
1. クラス定義の中で、Exception2MessageMapperをextendすれば、 def_e2messageメソッドやdef_exceptionメソッドが使えます。 これらで例外クラスとメッセージを関連づけることができます。
class Foo extend Exception2MessageMapper def_e2message ExistingExceptionClass, "message..." def_exception :NewExceptionClass, "message...", StandardError ... end foo = Foo.new foo.Fail ....
2. 何度も使いたい例外クラスは、クラスの代わりにモジュールで定義して、 それをincludeして使います。
module ErrorMod extend Exception2MessageMapper def_e2meggage ExistingExceptionClass, "message..." def_exception :NewExceptionClass, "message...", StandardError ... end class Foo include ErrorMod ... end foo = Foo.new foo.Fail ....
3. 例外を設定したクラスのインスタンス以外から例外を呼ぶこともできます。
module ErrorMod extend Exception2MessageMapper def_e2message ExistingExceptionClass, "message..." def_exception :NewExceptionClass, "message...", StandardError ... end class Foo extend Exception2MessageMapper include ErrorMod ... end Foo.Fail NewExceptionClass, arg... Foo.Fail ExistingExceptionClass, arg...
def_e2message(exception, message_form)
すでに存在する例外クラスexceptionに、 エラーメッセージ用フォーマット message_form を関連づけます。 message_formの形式は sprintf() のformat文字列と同じです。
このフォーマットはRaise(またはその別名のFail)で使われます。
def_exception(exception_name, message_form, superclass)
exception_nameという名前の例外クラスを作ります(exception_name はシンボルで与えられます)。 このクラスは、superclassが設定されていればそのクラスの サブクラスに、設定されていない場合はStandardErrorのサブ クラスになります。
そして、そのクラスにmessage_formで指定されたフォーマットを 関連づけます。 これはRaise(またはその別名のFail)で使われます。
Raise(error, [args [,args2...]])
errorクラスのエラーを発生させます。
errorの後に続く引数 args群は、例外クラスに関連づけられたエラー メッセージ用フォーマットと合わせて、エラーメッセージの一部に なります。例えば、
class Foo extend Exception2MessageMapper def_exception :NewExceptionClass, "message...%d, %d and %d" def foo Raise NewExceptionClass, 1, 2, 3 end end
という定義があれば、
Foo.new().foo()
というメソッドで、
in `Raise': message...1, 2 and 3 (Foo::NewExceptionClass)
というエラーが発生します。
また、
Foo.Raise Foo::NewExceptionClass, 1, 3, 5
というメソッドでも、
in `Raise': message...1, 3 and 5 (Foo::NewExceptionClass)
という例外が発生します。
Fail(error, [args [,args2...]])
Raise の別名です。
--> e2mmap.rb
2つの正規表現によるAND/ORを提供する。
Regexpクラスに&と|のメソッドを定義し、それぞれ 2つの正規表現の両方にマッチすれば真となるもの(RegAnd)と いずれかにマッチすれば真となるもの(RegOr)を返す。 RegAnd、RegOrは=~のみサポートしている。
require 'eregex' p "abc" =~ /b/|/c/ p "abc" =~ /b/&/c/
組み込みクラスRegexpを拡張して次のメソッドを定義している。
Regexp#&(other)
RegAnd(self,other)
を返す
Regexp#|(other)
RegOr(self,other)
を返す
RegAnd#initialize(reg1,reg2)
コンストラクタ
RegAnd#=~(str)
strがreg1とreg2の両方にマッチすれば真を返す
RegOr#initialize(reg1,reg2)
コンストラクタ
RegOr#=~(str)
strがreg1かreg2のいずれかにマッチすれば真を返す
--> Etc
/etc
ディレクトリ以下の情報を得るためのモジュール。クラスにインクルード
して使うこともできる。
require "etc.so" p Etc.getlogin
Etc.getlogin
自分のlogin名を返す。これが失敗した場合はEtc.getpwuidを用いると 良い。
Etc.getpwnam(name)
/etc/passwd
ファイル(あるいはDBMファイルやNISデータベース)を検
索し、nameの名前を持つpasswdエントリを返す。戻り値はpasswd構造
体で以下のメンバを持つ。
struct passwd name # ユーザ名(文字列) passwd # パスワード(文字列) uid # ユーザID(整数) gid # グループID(整数) gecos # gecosフィールド(文字列) dir # ホームディレクトリ(文字列) shell # ログインシェル(文字列) # 以降のメンバはシステムによっては提供されない。 change # パスワード変更時間(整数) quota # クォータ(整数) age # エージ(整数) class # ユーザアクセスクラス(文字列) comment # コメント(文字列) expire # アカウント有効期限(整数) end
詳細はgetpwnam(3)を参照のこと。
Etc.getpwuid([uid])
uidをユーザIDとするpasswdエントリを返す。戻り値は Etc.getpwnamと同様である。引数を省略した場合には getuid(2)の値を用いる。詳細は getpwuid(3) を参照のこと。
Etc.getgrgid(gid)
/etc/group
ファイル(あるいは…Etc.getpwnam参照)を検索し、
gidをグループIDとするグループエントリを返す。戻り値はgroup構
造体で以下のメンバを持つ。
struct group name # グループ名(文字列) passwd # グループのパスワード(文字列) gid # グループID(整数) mem # グループメンバ名の配列 end
詳細はgetgrgid(3)を参照のこと。
Etc.getgrnam(name)
nameという名前のグループエントリを返す。戻り値は Etc.getgrgidと同様である。詳細はgetgrnam(3) を参照。
Etc.group
全てのグループエントリを順にアクセスするためのイテレータ。
Etc.passwd
全てのpasswdエントリを順にアクセスするためのイテレータ。
IO#expect(pat, [timeout])
--> ruby-src:ruby/ext/pty/README.expect.ja
--> Fcntl
Unix のシステムコール fcntl(2) (つまり IO#fcntl)で使用できる定数 を集めたモジュールです。定義される 定数は以下の通りです
F_DUPFD
F_GETFD
F_GETLK
F_SETFD
F_GETFL
F_SETFL
F_SETLK
F_SETLKW
FD_CLOEXEC
F_RDLCK
F_UNLCK
F_WRLCK
O_CREAT
O_EXCL
O_NOCTTY
O_TRUNC
O_APPEND
O_NONBLOCK
O_NDELAY
O_RDONLY
O_RDWR
O_WRONLY
このライブラリで定義されていたメソッドは ruby 本体に組み込まれたため このライブラリ自体は obsolete になりました。
--> Finalizer
--> Find
ディレクトリ配下のファイルを探索するためのモジュールです。
require "find" Find.find('/foo','/bar') {|f| ...}
または
require "find" include Find find('/foo','/bar') {|f| ...}
以下は、ruby のアーカイブに含まれるサンプルスクリプト ruby-src:ruby/sample/trojan.rb をこのモジュールで書き換えたものです。
#! /usr/bin/env ruby require "find" # 他人が書き込み可能な危険なコマンドを探す for dir in ENV['PATH'].split(File::PATH_SEPARATOR) Find::find(dir) do |fpath| if File.file?(fpath) and (File.stat(fpath).mode & 022) != 0 printf("file %s is writable from other users\n", fpath) end end end
Find.find(dir[, ...]) {|file| }
find(1)のようにdir配下のすべてのファイルや ディレクトリを一つずつ引数fileに渡してブロックを実行します。 file に渡される順序は不定です。
あるディレクトリ配下の探索を省略したい場合
require 'find' Find.find('/tmp') {|f| Find.prune if f == "/tmp/bar" ... }
のように、Find.pruneを使用します。この例では "/tmp/bar"
配下のファイルやディレクトリを探索しません。prune
の代わりに
next を使用した場合、"/tmp/bar" 自体をスキップする
だけで、その配下の探索は続行されます。
Find.prune
Find.findメソッドのブロックにディレクトリが渡されたときにこ のメソッドを実行すると、そのディレクトリ配下の探索を無視します。
ディレクトリのシンボリックリンクを辿らなくなりました。
クラスに対してメソッドの委譲機能を定義します。 以下のモジュールが定義されます。
詳細は ruby-src:ruby/doc/forwardable.rd.ja を参照
詳細は ruby-src:ruby/doc/forwardable.rd.ja を参照
詳細は ruby-src:ruby/doc/forwardable.rd.ja を参照
require 'ftools' とすると、ファイルのコピーや削除などのメソッドが追加される。 to は新たなファイル名かディレクトリ名。 verbose が真のとき、標準エラー出力に処理の経過が出る。
File.copy(from, to[, verbose = false]) => true or false
File.cp(from, to[, verbose = false]) => true or false
ファイルをコピーする。より正確には from を読んで to に書き、モードを変更する。ファイルの更新時刻はコピーした時刻に更 新される。
例えば、更新時刻を保持したい場合は
File.copy(from, to) stat = File.stat(from) File.utime(stat.atime, stat.mtime, to)
などとする。
File.move(from, to[, verbose = false]) => true or false
File.mv(from, to[, verbose = false]) => true or false
ファイルを移動する。File.rename と異なりパーティション をまたがる移動もできる。
File.compare(from, to[, verbose = false]) => true or false
File.cmp(from, to[, verbose = false]) => true or false
2つのファイルを比較する。 同じなら true、異なるなら false を返す。
File.safe_unlink(files[, ...][, verbose = false])
File.rm_f(files[, ...][, verbose = false])
(複数の)ファイルを可能な限り削除する。削除できたファイルの数を
返す。rm -f
(rm(1))に相当。
File.makedirs(dirs[, ...][, verbose = false])
File.mkpath(dirs[, ...][, verbose = false])
(複数の)ディレクトリを作成する。多階層のパスを一度に作成することも可能。
mkdir -p
(mkdir(1))に相当。
File.chmod(mode, files[, ...][, verbose = false])
(複数の)ファイルの属性を変える。 オリジナルの File.chmod に verbose の指定が 追加されるだけ。
File.install(from, to[, mode = nil[, verbose = false]])
ファイルをコピーし、モードを設定する。 コピー先が存在する場合は一旦削除されるので、コピー先のファイルが 他のファイルにハードリンクされていれば、そのリンクは切れる。 install (install(1))コマンドに相当。
--> GDBM
GDBMファイルをアクセスするクラス。キー、データともに文字列でなければな らないという制限と、データがファイルに保存されるという点を除いては Hashクラスと全く同様に扱うことがでます。
dbnameで指定したデータベースをモードを
modeに設定してオープンします。modeの省
略値は0666です。modeとしてnil
を指定
するとデータベースが存在しない時には新たなデータベースを作らず
nil
を返します。
flags には、GDBM::FAST, GDBM::SYNC, GDBM::NOLOCK を の論理和を指定します。デフォルト値は指定なし(つまり0)です。
ブロックを指定した場合、オープンしたGDBMオブジェクトを 引数にブロックを実行します。実行後GDBMオブジェクトをクローズ し、openメソッドはブロックの結果を返します。これはちょうど 以下と同じです。
dbm = GDBM.open(file) begin yield dbm ensure dbm.close end
keyをキーとする値を返します。
keyをキーとして、valueを格納します。
DBMファイルを空にします。
DBMファイルをクローズします。以後の操作は例外を発生させます。
keyをキーとする項目を削除します。
指定したキーが存在しなければnilを返します、このとき ブロックを指定していれば、ブロックを評価します。
ブロックを評価した値が真であれば該当する項目を削除します。
各要素に対するイテレータ。
全てのkeyに対して繰り返すイテレータ。
全てのvalueに対して繰り返すイテレータ。
データベースが空の時、真を返します。
オープンしているGDBMオブジェクトのモードを変更します。下記の定数 GDBM::FAST、GDBM::SYNC を参照してください。
ハッシュと同じ
keyがデータベース中に存在する時、真を返します。
valueを値とする組がデータベース中に存在する時、真を返します。
ハッシュと同じ
各引数の値をキーとする要素を含む配列を返します。
値からキーへのハッシュを返します。
データベース中に存在するキー全てを含む配列を返します。
データベース中の要素の数を返します。(注意:現在の実現では要素数を数 えるためにデータベースを全部検索します)
self.to_hash.reject と同じです。ハッシュを返します。
GDBMでは、要素の削除を行ってもDBファイルのサイズは減少しません(削 除によって空いた領域は次の格納のために取っておかれます、)。このメ ソッドを呼び出すことでDBMファイルを新規に作り直し無駄な領域をなく すことができます。
大量の削除を行ったときに、ディスクスペースの節約のために使用します。
DBMの内容を other の内容で置き換えます。 other は each_pair メソッドを持つオブジェクトで なければなりません。
データベース中の要素を一つ取り出し、データベースから削除します。
self[key]=val と同じです。keyに対してvalを格納します。
要素の変更をファイルに反映します。FASTモード (GDBM#open() の第3引数にGDBM::FAST を指定)のときだけ意味があります。
注) GNU gdbm version 1.8 以降よりFASTモードがデフォルトになりました。
DBMの各要素を格納した配列を返します。返される配列の1つの要素は [key, val] です。(つまり配列の配列を返します)。
DBMの各要素を格納したハッシュを返します。
DBMとotherの内容をマージします。重複するキーに対応する値は otherの内容で上書きされます。
otherは each_pair メソッドを持つオブジェクトでなければなりま せん。
データベース中に存在する値全てを含む配列を返します。
libgdbm のバージョン情報の文字列です。
以下の定数は open の第3引数に指定します。
書き込みの結果が、ディスク上のファイルにすぐに反映しなくなります。 このモードのときに結果を明示的にファイルに反映させるには GDBM#sync メソッドを呼びます。libgdbm version 1.8.0 以降ではこのモードがデフォルト です。
書き込みの結果が、ディスク上のファイルにすぐに反映されます。 libgdbm version 1.8.0 以前のデフォルトモードです。
この定数は libgdbm version 1.8.0 以降より有効です
通常、他のプロセスがDBをオープンしている最中にオープンを行うと Errno::EWOULDBLOCK(またはErrno::EAGAIN)例外が発生します。このフラグを 指定していれば、他のプロセスがオープンしている最中でも同時オープンする ことができます。
この定数は libgdbm version 1.8.0 以降より有効です。
詳細は <URL:http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/> を参照
Author: <jammy@shljapan.co.jp>
オプションを解析し、$OPT_xxx に値を設定します。
getopts(SINGLE_OPTS、*OPTS)
`-f'や`-x(=-fx)'の様な一文字のオプションの指定をします。オプショ ンが`-f'と`-x'の2つの場合は`"fx"'の様に指定します。ここでオプシ ョンがないときは必ず`nil'を指定して下さい。
ロングネームのオプションや、引数を伴うオプションの指定をします。 `--version'や`--geometry 300x400'、`-d host:0.0'等がこれに該当し ます。引数を伴う指定は ":" を必ず付ける様にします。この例の場合、 "version"、"geometry:"、"d:" の様になります。 また、オプションを 指定しなかった場合のデフォルトの値を持たせたい場合は、":"の直後に そのデフォルト値を指定します。例えば、"geometry:80x25" の様になり ます。
解析結果は全て "$OPT_指定した引数名" という形で処理されます。
シングルオプションや引数を伴わないオプションが使用された場合は、 `TRUE'がセットされます。
`-f'→`$OPT_f = true' `--version'→`$OPT_version = true'
その他はそのオプションの引数がセットされます。
`-d pengo:0.0'→`$OPT_d = pengo:0.0' `--geometry 80x25'→ `$OPT_geometry = 80x25'。
実際にセットされたオプションの数を返します。また、間違ったオプショ ンを指定した場合は、`nil'を返します。
--> ruby-src:ruby/doc/irb/irb.rd.ja
[2001/02/27] by CozoH [2001/03/08] by るびきち
Stringクラスのメソッドを追加、再定義し、 日本語を意識した文字列処理を提供します。
*91[2001/03/08]るびきち:$KCODEを指定しないと結果がおかしいので注意。
require 'jcode' $KCODE='e' # 漢字コードをEUCに。Windowsでは 's' print 'abcdef'.tr( 'a-z', 'A-Z' ), "\n"
文字列中の各文字に対して繰り返します。 ブロックを指定せずに呼び出された時には、各文字の配列を返します。
例:
#!/usr/bin/env ruby $KCODE='e' require 'jcode' zstr='ABCDEF' p zstr.each_char zstr.each_char do |x| print "+#{x}+" end # => +A++B++C++D++E++F+
最後の文字が多バイト文字である文字列にマッチする正規表現を返します。 再定義されたString#succで内部的に使われます。
String#countの日本語対応版です。
例:
#!/usr/bin/env ruby $KCODE='e' zstr='ABCDEF' hogehoge='hogehoge' p zstr.count 'A' # => 7 ←これは正しくない p hogehoge.count "g" # => 2 require 'jcode' p zstr.jcount 'A' # => 1 p hogehoge.jcount "g" # => 2
String#lengthの日本語対応版です。
例:
#!/usr/bin/env ruby $KCODE='e' zstr='ABCDEF' hogehoge='hogehoge' p zstr.size # => 12 p hogehoge.size # => 8 require 'jcode' p zstr.jsize # => 6 p hogehoge.jsize # => 8
self
に多バイト文字が最初に現れる位置を返します。
多バイト文字が含まれていなければnil
を返します。
例:
#!/usr/bin/env ruby $KCODE='e' zstr='ABCDEF' hoge='hogehoge' require 'jcode' p zstr.mbchar? # => 0 p hoge.mbchar? # => nil
それぞれのメソッドに!
がついているものは破壊的メソッドです。
String#chopの日本語対応版です。
例:
#!/usr/bin/env ruby $KCODE='e' zstr='ABCDEF' hogehoge='hogehoge' p zstr.chop # => ABCDE\243 p hogehoge.chop # => hogehog require 'jcode' p zstr.chop # => ABCDE p hogehoge.chop # => hogehog
String#deleteの日本語対応版です。
例:
#!/usr/bin/env ruby $KCODE='e' zstr='ABCDEF' hogehoge='hogehoge' p zstr.delete "A" # => 唾津\306 p hogehoge.delete "e" # => hoghog require 'jcode' p zstr.delete "A" # => BCDEF p hogehoge.delete "e" # => hoghog
String#squeezeの日本語対応版です。
例:
#!/usr/bin/env ruby $KCODE='e' zstr='AABBCC' hogehoge='hhoge' p zstr.squeeze # => AABBCC p hogehoge.squeeze # => hoge require 'jcode' p zstr.squeeze # => ABC p hogehoge.squeeze # => hoge
String#succの日本語対応版です。
以下のような次の文字列を返します。
"あaあ".succ => "あaぃ" "rb".succ => "rc" "_紅玉".succ => "_紅桐"
従来のString#succは、
多バイト文字と半角文字が混在している文字列を
意図通りに処理することができません。
例えば上記のコードは、それぞれ
"あbあ"
、"sb"
、"_紘玉"
を返します。
なお、"99"
の次は"100"
になるのに対し、
"99"
の次は"100"
にはならないことに注意。
"Az"
や"zz"
も同様です。 *92
String#trの日本語対応版です。
例:
#!/usr/bin/env ruby $KCODE='e' zstr='AABBCC' hogehoge='hhoge' p zstr.tr('A-Z','A-Z') # => A疏疏汰汰蛋\303 p hogehoge.tr('a-z','A-Z') # => 旙旙\332 require 'jcode' p zstr.tr('A-Z','A-Z') # => AABBCC p hogehoge.tr('a-z','A-Z') # => HHOGE
String#tr_sの日本語対応版です。
irb(main):009:0> "foo".tr_s("o", "f") "ff" irb(main):010:0> require 'jcode'; $KCODE='e' "e" irb(main):011:0> "foo".tr_s("o","f") "foo" irb(main):012:0> "foo".tr_s("o", "f") "foo"
文字コードエンコーディングを変換するためのモジュール。
newstring = Kconv::kconv(string, Kconv::JIS, Kconv::AUTO); newstring = Kconv::tojis(string); newstring = Kconv::toeuc(string); newstring = Kconv::tosjis(string); guessed_code = Kconv::guess(string);
または
newstring = string.kconv(Kconv::JIS, Kconv::AUTO); newstring = string.tojis newstring = string.toeuc newstring = string.tosjis
Kconv.kconv(str, out_code, in_code = Kconv::AUTO)
文字列 str のエンコーディングを out_code に変換したものを 返します。in_code も指定されていたら str のエンコーディングが in_code だとして動作します。
out_code in_code は定数で指定します。
Kconv.tojis(str)
文字列 str のエンコーディングを iso-2022-jp に変換して返します。 以下と同じです。
Kconv.kconv(str, Kconv::JIS)
Kconv.toeuc(str)
文字列 str のエンコーディングを euc-jp に変換して返します。 以下と同じです。
Kconv.kconv(str, Kconv::EUC)
Kconv.tosjis(str)
文字列 str のエンコーディングを shift_jis に変換して返します。 以下と同じです。
Kconv.kconv(str, Kconv::SJIS)
Kconv.guess(str)
文字列 str のエンコーディングを判定します。返り値は
Kconv
の定数です。
String
に追加されるメソッドString#kconv(out_code, in_code = Kconv::AUTO)
self
のエンコーディングを out_code
に変換したのを
返します。out_code in_code は Kconv
の定数で
指定します。
String#tojis
self
のエンコーディングを iso-2022-jp に変換した文字列を
返します。
String#toeuc
self
のエンコーディングを euc-jp に変換した文字列を
返します。
String#tosjis
self
のエンコーディングを shift_jis に変換した文字列を
返します。
エンコーディングを自動検出する。 入力の指定でのみ有効。
iso-2022-jp を表す。
euc-jp を表す。
shift_jis (シフト JIS / MS 漢字コードとも言う) を表す。
JIS EUC SJIS 以外
出力においては「エンコーディングを判定できなかった」 入力においては AUTO と同様に「自動検出」を表す。
[2001/02/05] るびきち
シンプルなメールクラス。
require 'mailread' m = Mail.new('/var/mail/foo') puts 'From: ' + m['From'], 'Subject: ' + m['Subject'], '--', m.body[0,5]
Mail.new(f)
メールを解析する。 f はファイル名か IO オブジェクト。 このメソッドを実行した時点でヘッダと本文が切り分けられ、ヘッダの ハッシュ(ヘッダフィールド単位)と本文の配列(行単位)が作られる。
1ファイル複数メールの形式(Unix From 形式)に対応しており (この場合 open 済みの IO を渡す必要があることに注意)、 例えば以下のようにして各メールの Subject を表示できる
require 'mailread' require 'nkf' mailbox = File.open('/var/mail/arai') until (m = Mail.new(mailbox)).header.empty? puts NKF.nkf('-me', m['subject']) end
Mail#header
ヘッダを Hash で返す。 キーは 'From'、'Subject' などのフィールド名で、すべてのキーは String#capitalize されている。
値の末尾の改行は削除される。複数行に分かれている場合、間に改行を はさむ(継続行を表す空白は削除される)。MIME デコードなどを行いた い場合は NKF などを使用すること。
Mail#body
本文を行単位の Array で返す。
Mail#[field]
ヘッダの field の値を返す。 m.header[field.capitalize] と同じなので値取得の際は、フィー ルド名のアルファベットの大小を気にする必要はない。
rational.rbとcomplex.rbを補助する関数群。
本来 Floatととは異なり, Ratinalは誤差がないので,
1/2 -> 1/2 (Rational) 2 * Rational(1,2) -> 1 (Fixnum)
となってほしいこともあるかと思います. つまり, rubyのBignumとFixnumの様 な関係ですね. rubyではこれらの型変換は勝手に行なっています.
mathn.rbをインクルードするとこの様な動作を行ないます. つまり, Ratinal とComplexをBignumとFixnumと同等な関係にします.
Integer.from_prime_division(pd)
素因数分解の配列pdから数を求める。
pdは[素因数, 指数]
組の配列である。
例: Integer.from_prime_division [[2,3],[3,2]] -> 72 # == 2**3 * 3**2
Integer#gcd2(int)
selfとintの最大公約数を求める。
例: 12.gcd2 8 -> 4
Integer#prime_division
selfの素因数分解(の配列)を求める。
例: 72.prime_division -> [[2, 3], [3, 2]]
Prime.new
素数を生成するクラスを作る。
Prime#succ
次の素数を返す。
例: pp = Prime.new pp.succ # => 2 pp.succ # => 3 pp.succ # => 5
Prime#each
素数について繰り返し。 これは無限ループになるので必ずbreakを入れること。
例: > pp=Prime.new; i = 0; pp.each {|x| break if i > 5; puts x; i+=1;} 2 3 5 7 11 13
Rational#**
べき乗。 RationalになるようであればRationalで返す。
Rational#power2
作りかけ(^^;;
Math.sqrt(a)
Math.rsqrt(a)
creates a matrix where `rows' indicates rows. `rows' is an array of arrays, e.g, Matrix[[11, 12], [21, 22]]
creates a matrix where `rows' indicates rows. if optional argument `copy' is false, use the array as internal structure of the metrix without copying.
creates a new matrix using `columns` as set of colums vectors.
creates a matrix where `columns' indicates columns.
creates a diagonal matrix such that the diagal compornents is given by `values'.
creates an n-by-n scalar matrix such that the diagal compornent is given by `value'.
creates an n-by-n unit matrix.
creates an n-by-n zero matrix.
creates a 1-by-n matrix such the row vector is `row'. `row' is specifed as a Vector or an Array.
creates a 1-by-n matrix such that column vector is `column'. `column' is specifed as a Vector or an Array.
returns (i,j) compornent
returns the number of rows
returns the number of columns
returns the i-th row vector. when the block is supplied for the method, the block is iterated over all row vectors.
returns the jth column vector. when the block is supplied for the method, the block is iterated over all column vectors.
creates a matrix which is the result of iteration of given block over all compornents.
returns sub matrix. parameter is specified as the following:
Is regular?
Is singular? i.e. Is non-regular?
Is square?
times
plus
minus
self * m.inv
inverse
power
returns the determinant
returns the rank
returns the trace
returns the transposed
array of row vectors
array of column vectors
converts each element to Array
converts each element to Float
converts each element to Integer
converts each element to Rational
returns string representation
digest/md5.so をロードして MD5 を Digest::MD5
に置き換えます
古い MD5 のマニュアルは以下
--> MD5
RFC:1321に記述されているRSA Data Security, Inc. の MD5 Message-Digest Algorithmを実装するクラス。
新しいMD5オブジェクトを生成する。文字列引数が与えられるとそれ を追加する(see update)。
MD5オブジェクトの複製を作る
今までに追加した文字列に対するハッシュ値を16バイト長の文字列で返す。
今までに追加した文字列に対するハッシュ値を、ASCIIコードを使って
16進数の列を示す 'fe5c2235f48d2bcc911afabea23cd5aa'
の
ような32文字の文字列にエンコードして返す。Rubyで書くと以下と同じ。
def hexdigest ret = '' digest.each_byte {|i| ret << sprintf('%02x', i) } ret end
MD5オブジェクトに文字列を追加する。複数回updateを呼ぶことは文 字列を連結してupdateを呼ぶことと等しい。
Ruby の拡張ライブラリのための Makefile を作成するライブラリです。通常 extconf.rb という名の ruby スクリプトの中で require され、このスクリプ トを実行することで Makefile を作成するのが慣習となっています。
拡張ライブラリの作り方(extconf.rbの書き方)に関しては ruby のアーカイブ に含まれる ruby-src:ruby/README.EXT (日本語版は ruby-src:ruby/README.EXT.ja)も参照してください。
架空の拡張ライブラリ foo.so を作成することを考えます。この拡張ライブラ リを作成するためには、ヘッダファイル bar.h とライブラリ libbar.a の関 数 baz() が必要だとします。このための extconf.rb は以下のように書きま す。
require 'mkmf.rb' dir_config('bar') if have_header('bar.h') and have_library('bar', 'baz') create_makefile('foo') end
そして、拡張ライブラリを作成、インストールするには以下のようにします。
$ ruby extconf.rb $ make $ make site-install
dir_config('bar')
により、ヘッダファイルのパス、ライブラリのパス
を以下のように指定できます。
$ ruby extconf.rb --with-bar-include=/usr/local/include \ --with-bar-lib=/usr/local/lib あるいは $ ruby extconf.rb --with-bar-dir=/usr/local
詳細は dir_config を参照してください。
ここでの configure オプションとは ruby インタプリタ作成時に指定された configure スクリプトのオプション、または extconf.rb 実行時のオプショ ンのことです。extconf.rb の作成者は任意のオプションを定義できます。 (arg_config を参照)。
また、以下のオプションがデフォルトで利用可能です。
ヘッダファイルを探索するディレクトリ directory を追加します。
ライブラリファイルを探索するディレクトリ directory を追加します。
ヘッダファイル、ライブラリファイルを探索するディレクトリ directory/include、directory/lib をそれぞれ追加します。
extconf.rb の中で dir_config(target) を実行していればこ のオプションを指定できます。
ヘッダファイルを探索するディレクトリ directory を追加します。
extconf.rb の中で dir_config(target) を実行していればこ のオプションを指定できます。
ライブラリを探索するディレクトリ directory を追加します。
extconf.rb の中で dir_config(target) を実行していればこ のオプションを指定できます。
ヘッダファイル、ライブラリファイルを探索するディレクトリ directory/include、directory/lib をそれぞれ追加します。
カレントディレクトリに depend という名前のファイルがあればこの内容は生 成される Makefile の最後に追加されます。
このファイルは、ソースファイルの依存関係を記述するために使用します。例 えば、拡張ライブラリのソース foo.c が foo.h をインクルードしていれば foo.h が更新されたときにも foo.c を再コンパイルしたくなります。
このような依存関係を記述するには depend ファイルに以下を書きます。
foo.o: foo.c foo.h
これは、foo.o が foo.c と foo.h に依存し、これらが更新されれば foo.o は再作成されることを示します。
C コンパイラによっては、このような出力を自動生成することができます。こ のためのオプションは -M として知られています。
cc -M *.c > depend
は、上記の出力を得ます。
gcc では、さらに -MM というオプションがあります。これは(通常更新するこ とのないstdio.hなど)システムのヘッダファイルを依存ファイルとみなしませ ん。(#include <...> の形式で参照されるヘッダファイルをシステムのヘッダ ファイルとみなすようです)
gcc -MM *.c > depend
のように使います。
depend ファイルを他の用途で使用しては行けません。mkmf.rb はこの内容を Makefile に出力する際に多少の加工を行う場合があります。
extconf.rb が生成した Makefile には以下のターゲットが定義されています。
拡張ライブラリを作成します。
作成した拡張ライブラリ、オブジェクトファイルなどを削除します。
clean に加えて Makefile extconf.h(create_header参照) core ruby などを削除します。
作成した拡張ライブラリを $archdir にインストールします。カレン トディレクトリにディレクトリ lib があればその配下の ruby スクリプト (.rb ファイル)をディレクトリ階層ごと $libdir にインストールし ます。
install と同様ですが、拡張ライブラリは $sitearchdir に、 ruby スクリプトは $sitelibdir にインストールされます。
以下は、extconf.rb を記述するのに有用な関数です。ヘッダファイルの存在 チェック、ライブラリの存在チェックなど、システム間の差異を調べシステム に適した Makefile を生成するためにこれらの関数が必要となります。
try_link(src[, opt])
C ソース src をコンパイル、リンクします。リンクの結果が正常 かどうかを true または false で返します。
optが指定されていればリンク時のコマンド引数として渡されます。 このメソッドは、$CFLAGS、$LDFLAGS の値もコンパイラ、リ ンカに渡します。
src には直接 C ソースを文字列で書きます。
try_cpp(src[, opt])
C ソース src をプリプロセスし、その結果が正常かどうかを true または false で返します。
$CFLAGS opt
をプリプロセッサの引数に渡します。
src には直接 C ソースを文字列で書きます。
このメソッドはヘッダファイルの存在チェックなどに使用します。
egrep_cpp(pat, src[, opt])
C ソース src をプリプロセスし、その結果が正規表現 pat にマッチするかどうかを判定します。pat には、egrepの正 規表現を文字列で指定します。
を実行し、その結果が正常かどうかを true または false で返します。
src には直接 C ソースを文字列で書きます。
このメソッドはヘッダファイルに関数などの宣言があるかどうかを検 査するのに使用します。
try_run(src[, opt])
C ソース src をコンパイルし、生成された実行ファイルを実行し た結果が正常かどうかを true または false で返します。
src には直接 C ソースを文字列で書きます。
install_rb(mfile, dest[, srcdir])
このメソッドは、create_makefile が使用します
ディレクトリ srcdir/lib
配下の ruby スクリプト
(.rb
ファイル)をdest にインストールするための Makefile
規則を mfile に出力します。mfile は IO クラスの
インスタンスです。
srcdir/lib
のディレクトリ構造はそのまま dest 配
下に反映されます。
引数 srcdir のデフォルトは "." です。
append_library(libs, lib)
ライブラリ lib をライブラリのリスト libs の先頭に追加 した結果を返します。
引数 libs とこのメソッドの戻り値はリンカに渡す引数形式の文字 列です。これは UNIX では、
"-lfoo -lbar"
であり、MS-Windows などでは
"foo.lib bar.lib"
です。引数 lib は、この例での "foo"
や "bar"
に
あたります。
have_library(lib[, func])
ライブラリ lib がシステムに存在し、関数 func が定義され ているかどうかを検査します。検査に成功すれば $libs に lib を追加し true を返します。そうでなければ false を返しま す。
func の指定を省略した場合、関数の存在は検査しません。
func が nil または空文字列("") であれば特に何も検査をせずに、 無条件で lib を追加します。
find_library(lib, func[, path1[, path2[, ...]]])
関数 func が定義されたライブラリ lib を探します。最初 にパス指定なしで検査し、次にpath1を指定、ダメならpath2 を指定・・・といったように順にリンク可能なライブラリを探索します。
検査に成功すれば lib を $libs に追加し、見つかったパス を $LDFLAGS に追加して true を返します。指定されたすべての パスを検査してもライブラリ lib が見つからなければ false を返 します。
path の指定がなければhave_libraryと同じです。
have_func(func[, header])
関数 func が存在するかどうかを検査します。
func が存在すれば $defs に -DHAVE_func
(func は大文字に変換されます)を追加して true を返します。そ
うでなければ false を返します。
header には、関数funcを使用するのに必要なヘッダファイ ル名を指定します。これは引数の型チェックのためではなく(そのような 検査はこのメソッドでは行われません)関数が実際にはマクロで定義され ている場合などのために使用します。
have_header(header)
ヘッダファイル header が存在するかどうかを検査します。
header が存在すれば $defs に、
-DHAVE_header
(header は実際には大文字に変換され
文字 "-", "." が、"_" に置き換えられます)を追加して true を返しま
す。そうでなければ false を返します。
arg_config(config[, default])
configure オプション --config の値を返します。値が設定 されていなければ default を返します。
extconf.rb の場合、
ruby extconf.rb --foo --bar=baz
と実行すれば arg_config("foo") の値は true、arg_config("bar") の値は "baz" です。
with_config(config[, default])
arg_config と同じですが、--with-config
オプショ
ンの値だけを参照します。
enable_config(config[, default])
arg_config と同じですが、--enable-config
オプショ
ン、または--disable-config
オプションの値だけを参照しま
す。
create_header()
have_funcなどの検査結果を元に
#define HAVE_FUNC 1 #define HAVE_HEADER_H 1
などを定義した extconf.h ファイルを生成します。
dir_config(target[, default])
dir_config(target[, idefault, ldefault])
システムに標準では存在しないヘッダファイルやライブラリがあるディレ クトリを extconf.rb の利用者が指定できるようにします。
最初の形式では、configure オプション
--with-target-dir=path
が指定されていれば、
$CFLAGS に "-Ipath/include" を $LDFLAGS に
"-Lpath/lib" を追加します。
--with-target-dir
の代わりに configure オプション
--with-target-include
、--with-target-lib
が指定されていれば、これらの値を $CFLAGS
、$LDFLAGS
に
それぞれ追加します。
configure オプションがいずれも指定されていなければ、省略可能な引数
deafult、idefault、ldefault が使用されます。最初
の形式では、"-Idefault/include"
、
"-Ldefault/lib"
をそれぞれ追加し、二番目の形式では
"-Iidefault"
、"-Lldefault"
をそれぞれ追加
します。
create_makefile(target[, srcdir])
have_libraryなどの各種検査の結果を元に 拡張ライブラリ target.so を作成する Makefile を生成します。
srcdir は make 変数 srcdir の値になり、これにはソー スがあるディレクトリ名を指定します。省略した場合は、 extconf.rb があるディレクトリです。
extconf.rb は普通このメソッドの呼び出しで終ります。
CONFIG
Config::MAKEFILE_CONFIG と同じです。
CFLAGS
この値は、Makefileにも反映されます。
LINK
リンクを検査するときのコマンドラインのフォーマットです。 try_linkなどが使用します。
CPP
プリプロセスを検査するときのコマンドラインのフォーマットです。 try_cppなどが使用します。
$srcdir
ruby インタプリタを make したときのソースディレクトリです。
$libdir
ruby のライブラリを置くディレクトリです。
通常 /usr/local/lib/ruby/version
です。
$archdir
マシン固有のライブラリを置くディレクトリです。
通常 /usr/local/lib/ruby/version/arch
です。
$sitelibdir
サイト固有のライブラリを置くディレクトリです。
通常 /usr/local/lib/ruby/site_ruby/version
です。
$sitearchdir
サイト固有でかつマシン固有のライブラリを置くディレクトリです。
通常 /usr/local/lib/ruby/site_ruby/version/arch
です。
$hdrdir
ruby のヘッダファイル ruby.h
が存在するディレクトリです。
通常 /usr/local/lib/ruby/version/arch
です。
$topdir
拡張ライブラリを make するためのヘッダファイル、ライブラリ等が存在 するディレクトリです。
通常 /usr/local/lib/ruby/version/arch
です。
$defs
拡張ライブラリをコンパイルするときのマクロ定義を指定する配列です。
have_func、have_header の検査結果はこの配列の要素になり
["-DHAVE_FUNC", "-DHAVE_HEADER_H"]
といった値になります。
create_header は、この変数の値を参照してヘッダファイルを生成 します。
$libs
拡張ライブラリをリンクするときに一緒にリンクされるライブラリを指定 する文字列です。
have_library、find_library の検査結果はこの文字列に
"-lfoo -lbar"
のように間に空白を置いて連結されます。
$CFLAGS
拡張ライブラリをコンパイルするときの C コンパイラのオプション、ヘッ ダファイルのディレクトリを指定する文字列です。
dir_config はこの変数に値 "-Idir" を追加します。
$LDFLAGS
拡張ライブラリをリンクするときのリンカのオプション、ライブラリファ イルのディレクトリを指定する文字列です。
find_library、dir_config はこの変数に値 "-Ldir" を追加 します。
Object
Net::FTP.new(host=nil, user=nil, passwd=nil, acct=nil)
新しいインスタンスを生成します。
hostが指定された場合、生成されたインスタンスに対して connectを呼び出し、 さらにuserが指定された場合は loginを呼び出します。
Net::FTP.open(host, user=nil, passwd=nil, acct=nil)
hostを省略できない以外は newと同じです。
Net::FTP#connect(host, port = FTP_PORT)
hostで指定されたホストに接続します。
Net::FTP#sendcmd(cmd)
cmdで指定されたコマンドをサーバーに送り、 サーバーからの応答を返します。
応答コードが4xxの場合は例外FTPTermErrorが、5xxの場合は 例外FTPPermErrorが発生します。 応答コードの最初の数字が1から5のどれでもない場合は 例外FTPProtoErrorが発生します。
Net::FTP#voidcmd(cmd)
sendcmdと同様にサーバーにコマンドを送りますが、nilを返す点と、 応答コードが2xx以外の場合、例外FTPReplyErrorが発生する点が異なります。
Net::FTP#login(user = "anonymous", passwd = nil, acct = nil)
ログイン処理を行ないます。
userが省略された場合、anonymousでログインします。
Net::FTP#retrbinary(cmd, blocksize, rest_offset = nil, callback = Proc.new)
サーバーにcmdで指定されたコマンドを送り、バイナリデータを 取り寄せます。 blocksizeで指定されたバイト単位でデータを 読み込み、callbackで指定されたProcオブジェクトまたは ブロックに読み込んだデータを渡します。
Net::FTP#retrlines(cmd, callback = nil)
サーバーにcmdで指定されたコマンドを送り、テキストデータを 取り寄せます。一行ずつテキストを読み込み、callbackで指定された Procオブジェクトまたはブロックに読み込んだ行を渡します。
callbackもブロックも省略された場合は読み込んだ行をprintします。
Net::FTP#storbinary(cmd, file, blocksize, rest_offset = nil, callback = nil)
サーバーにcmdで指定されたコマンドを送り、バイナリデータを 送ります。blocksizeで指定されたバイト単位で fileからデータを読み込み、サーバーに送ります。
callbackやブロックが指定された場合はデータが 送信されるごとにそれを呼び出します。
Net::FTP#storlines(cmd, file, callback = nil)
サーバーにcmdで指定されたコマンドを送り、テキストデータを 送ります。一行ずつでfileからテキストを読み込み、 サーバーに送ります。
callbackやブロックが指定された場合はデータが 送信されるごとにそれを呼び出します。
Net::FTP#getbinaryfile(remotefile, localfile, blocksize = DEFAULT_BLOCKSIZE, callback = nil)
サーバー上のバイナリファイルをgetします。
callbackやブロックが指定された場合は データが送信されるごとにそれを呼び出します。
Net::FTP#gettextfile(remotefile, localfile, callback = nil)
サーバー上のテキストファイルをgetします。
callbackやブロックが指定された場合は データが送信されるごとにそれを呼び出します。
Net::FTP#putbinaryfile(localfile, remotefile, blocksize = DEFAULT_BLOCKSIZE, callback = nil)
サーバーにバイナリファイルをputします。
callbackやブロックが指定された場合は データが送信されるごとにそれを呼び出します。
Net::FTP#puttextfile(localfile, remotefile, callback = nil)
サーバーにテキストファイルをputします。
callbackやブロックが指定された場合は データが送信されるごとにそれを呼び出します。
Net::FTP#acct(account)
サーバーにアカウント情報を送ります。
Net::FTP#nlst(dir = nil)
dirで指定したディレクトリのファイルの配列を返します。 dirを省略した場合カレントディレクトリが指定されます。
Net::FTP#list(*args, &block)
Net::FTP#ls(*args, &block)
Net::FTP#dir(*args, &block)
LISTコマンドを送信し、結果を返します。
ブロックとともに呼び出された場合は各行に対してブロックを 実行します。
Net::FTP#rename(fromname, toname)
ファイルをリネームします。
Net::FTP#delete(filename)
ファイルを削除します。
Net::FTP#chdir(dirname)
カレントディレクトリをdirnameに変更します。
Net::FTP#size(filename)
ファイルのサイズを返します。
Net::FTP#mtime(filename, local = false)
filenameの更新時刻をTimeオブジェクトで返します。 localは、更新時刻をローカル時刻とみなすかどうかの フラグです。(省略したときのデフォルト値はfalseです)。
Net::FTP#mkdir(dirname)
ディレクトリを作成します。
Net::FTP#rmdir(dirname)
ディレクトリを削除します。
Net::FTP#pwd
Net::FTP#getdir
カレントディレクトリを返します。
Net::FTP#system
サーバーのOSのタイプを返します。
Net::FTP#abort
データの転送を中止します。
Net::FTP#status
現在の状態を返します。
Net::FTP#mdtm(filename)
MDTMコマンドを送信し、結果を返します。
Net::FTP#help(arg = nil)
help情報を返します。
Net::FTP#quit
ログアウトします。
Net::FTP#close
接続を切ります。
Net::FTP#closed?
接続が切れている時に真を返します。
汎用データ転送プロトコル HTTP を扱うライブラリです。 実装は [RFC2616] <URL:http://www.ietf.org/rfc/rfc2616.txt> に 基いています。
require 'net/http' Net::HTTP.start( 'some.www.server', 80 ) {|http| response , = http.get('/index.html') puts response.body }
また以下は同じ意味で短く書いたものです。
require 'net/http' Net::HTTP.get_print 'some.www.server', '/index.html'
require 'net/http' Net::HTTP.start( 'some.www.server', 80 ) {|http| response , = http.post( '/cgi-bin/any.rhtml', 'querytype=subject&target=ruby' ) }
Net::HTTP のクラスメソッド Net::HTTP.Proxy は、常にプロクシ経由で 接続するような動作をする、新しいクラスを作成して返します。このクラスは Net::HTTP を継承しているので Net::HTTP と全く同じように使えます。
require 'net/http' $proxy_addr = 'your.proxy.addr' $proxy_port = 8080 : Net::HTTP::Proxy($proxy_addr, $proxy_port).start( 'some.www.server' ) {|http| # always connect to your.proxy.addr:8080 : }
また Net::HTTP.Proxy は第一引数が nil だと Net::HTTP 自身を返すので 上のコードのように書いておけばプロクシなしの場合にも対応できます。
require 'net/http' Net::HTTP.version_1_1 host = 'www.ruby-lang.org' path = '/' begin Net::HTTP.start( host, 80 ) {|http|
response , = http.get(path)
print response.body
}
rescue Net::ProtoRetriableError => err if m = %r<http://([^/]+)>.match( err.response['location'] ) then
host = m[1].strip path = m.post_match retry
end
end
この例では URL からホスト名を得るのにいいかげんな方法を使っていますが、 将来 URI クラスが標準添付になればもっと簡単になるはずです。
require 'net/http' Net::HTTP.start( 'auth.some.domain' ) {|http| response , = http.get( '/need-auth.cgi', 'Authentication' => ["#{account}:#{password}"].pack('m').strip ) print response.body }
バージョン 1.2 (Ruby 1.7 以降に添付) では次のように書けます。
require 'net/http' req = Net::HTTP::Get.new('/need-auth.cgi') req.basic_auth 'account', 'password' Net::HTTP.start( 'auth.some.domain' ) {|http| response = http.request( req ) print response.body }
Ruby 1.6 に入っているのが http.rb 1.1 で 1.7 以降が 1.2 ですが、 この間ではかなり大きく仕様が変わります。そこで突然に仕様を変更 するのでなく、両方の実装を並存させる時期を設けることにしました。
メソッド HTTP.version_1_2、HTTP.version_1_1 を呼ぶと そのあとに生成される Net::HTTP オブジェクトはそれぞれの バージョンの仕様で動作するようになります。以下は使用例です。
# example Net::HTTP.start {|http1| ...(http1 has 1.2 features)... } Net::HTTP.version_1_1 Net::HTTP.start {|http2| ...(http2 has 1.1 features)... } Net::HTTP.version_1_2 Net::HTTP.start {|http3| ...(http3 has 1.2 features)... }
この機能はスレッドセーフではありません。
新しい HTTP オブジェクトを生成します。address は HTTP サーバーの FQDN で、 port は接続するポート番号です。このメソッドではまだ接続はしません。
proxy_addr を与えるとプロクシを介して接続するオブジェクトを生成します。
以下と同じです。
Net::HTTP.new(address, port, proxy_addr, proxy_port).start(&block)
ホスト address の port 番ポートに接続して path の表現する エンティティを取得、文字列で返します。
ホスト address の port 番ポートに接続して path の表現する エンティティを取得したうえ、$stdout に << で出力します。
常に指定されたプロクシに接続するクラスを作成し返します。 このクラスは Net::HTTP を継承しているので Net::HTTP と全く 同じように使えます。
address が nil のときは Net::HTTP クラスをそのまま返します。
# example proxy_class = Net::HTTP::Proxy( 'proxy.foo.org', 8080 ) : proxy_class.start( 'www.ruby-lang.org' ) do |http| # connecting proxy.foo.org:8080 : end
自身が (Proxy メソッドによって作成された) プロクシ用のクラスならば真。
HTTP のデフォルトポート (80)。
TCP コネクションを張り、HTTP セッションを開始します。 すでにセッションが開始していたら何もせずに false を返します。
イテレータとして呼ばれた時はブロックの間だけセッションを接続し、 ブロック終了とともに自動的にセッションを閉じます。
HTTP セッションが開始されていたら真。
接続するアドレス
接続するポート番号
接続時に待つ最大秒数。この秒数たってもコネクションが 開かなければ例外 TimeoutError を発生します。
読みこみ (read(1) 一回) でブロックしてよい最大秒数。 この秒数たっても読みこめなければ例外 TimeoutError を発生します。
HTTP セッションを終了します。セッション開始前にこのメソッドが 呼ばれた場合はなにもせずに false を返します。
プロクシを介して接続するなら真。
プロクシ経由で接続する HTTP オブジェクトならプロクシのアドレス。 そうでないなら nil。
プロクシ経由で接続する HTTP オブジェクトならプロクシのポート。 そうでないなら nil。
サーバ上の path にあるエンティティを取得し、dest に << メソッドを 使って書きこみます。また header が nil でなければリクエストを送る ときにその内容を HTTP ヘッダとして書きこみます。header はハッシュで、 「ヘッダ名 => 内容」のような形式でなければいけません。
返り値は、バージョン 1.1 では HTTPResponse と dest 二要素の配列です。 1.2 では HTTPResponse ただひとつのみです。
イテレータとして呼ばれた時はエンティティボディを少しづつブロックに 与えます。
1.1 では 3xx (再試行可能なエラー)に対しても例外を発生します。この場合 HTTPResponse は例外オブジェクトから err.response で得ることができます。 一方 1.2 では全く例外を発生しません。
# version 1.1 (bundled with Ruby 1.6) response, body = http.get( '/index.html' ) # version 1.2 (bundled with Ruby 1.7 or later) response = http.get( '/index.html' ) # compatible in both version response , = http.get( '/index.html' ) response.body # using block File.open( 'save.txt', 'w' ) {|f| http.get( '/~foo/', nil ) do |str| f.write str end } # same effect File.open( 'save.txt', 'w' ) {|f| http.get '/~foo/', nil, f }
サーバ上の path にあるエンティティのヘッダのみを取得します。 また header が nil でなければリクエストを送るときにその内容を HTTP ヘッダとして書きこみます。header はハッシュで、 「ヘッダ名 => 内容」のような形式でなければいけません。
HTTPResponse オブジェクトを返します。
1.1 では 3xx (再試行可能なエラー)に対しても例外を発生します。この場合 HTTPResponse は例外オブジェクトから err.response で得ることができます。 一方 1.2 では全く例外を発生しません。
response = nil Net::HTTP.start( 'some.www.server', 80 ) {|http| response = http.head( '/index.html' ) } response['content-length'] #-> '2554' response['content-type'] #-> 'text/html' response['Content-Type'] #-> 'text/html' response['CoNtEnT-tYpe'] #-> 'text/html'
サーバ上の path にあるエンティティに対し文字列 data を 送ります。レスポンスは << メソッドを使って dest に書き こまれます。header は get メソッドと同じです。 HTTPResponse オブジェクトと dest の配列を返します。
イテレータとして呼びだされたときはエンティティボディを少しづつ ブロックに与えます。
1.1 では 3xx (再試行可能なエラー)に対しても例外を発生します。この場合 HTTPResponse は例外オブジェクトから err.response で得ることができます。 一方 1.2 では全く例外を発生しません。
# version 1.1 response, body = http.post( '/index.html', 'querytype=subject&target=ruby' ) # version 1.2 response = http.post( '/index.html', 'querytype=subject&target=ruby' ) # compatible for both version response , = http.post( '/index.html', 'querytype=subject&target=ruby' ) # using block File.open( 'save.html', 'w' ) {|f| http.post( '/index.html', 'querytype=subject&target=ruby' ) do |str| f.write str end } # same effect File.open( 'save.html', 'w' ) {|f| http.post '/index.html', 'querytype=subject&target=ruby', nil, f }
リクエストオブジェクト request を送信します。POST の時は data も 与えられます。(POST 以外で data を与えると ArgumentError を発生します)
ブロックとともに呼びだされたときは接続を保持したまま HTTPResponse オブジェクトをブロックに与えます。
HTTP リクエストを抽象化するクラス。key はすべて大文字小文字を 区別しません。
HTTP リクエストオブジェクトを生成します。
key ヘッダフィールドの文字列。 key は大文字小文字を区別しません。
key ヘッダフィールドに val をセットします。 key は大文字小文字を区別しません。
ヘッダ名とその値に対するくりかえし。ヘッダ名は小文字で統一されます。
Authrization: ヘッダを basic auth 用にセットします。
Range: ヘッダの示す範囲を Range オブジェクトで返します。
範囲を指定してエンティティを取得するためのヘッダ Range: をセットします。 r は Range オブジェクト、i, len は始点と長さです。
Content-Length: ヘッダの値 (整数)。
Content-Range: ヘッダの値 (Range)。
HTTP レスポンスのクラスです。 引数がヘッダフィールド名である場合、大文字小文字を区別しません。
key ヘッダフィールド(文字列)です。たとえばキー 'content-length' に対しては '2048' のような文字列が得られます。 key は大文字小文字を区別しません。
key ヘッダフィールドを value に設定します。 key は大文字小文字を区別しません。
key というヘッダフィールドがあれば真。 key は大文字小文字を区別しません。
すべてのヘッダフィールド名とその値のペアに対するくりかえし。
ヘッダフィールドの正式名とその値のペアに対して繰り返します。
HTTP のリザルトコードです。例えば '302' などです。
HTTP サーバがリザルトコードに付加して返すメッセージです。 例えば 'Not Found' などです。
エンティティボディを取得し dest に << メソッドを使って書きこみます。 同じ HTTPResponse オブジェクトに対して二回以上呼ばれた場合、 二回目からはなにもせずに一回目の返り値をそのまま返します。
エンティティボディを少しづつ取得して順次ブロックに与えます。
エンティティボディです。read_body を呼んでいればその引数 dest、 呼んでいなければエンティティボディを文字列として読みこんで返します。
メールを受信するためのプロトコル POP3 (Post Office Protocol version 3) を を扱うライブラリです。POP3 の実装は [RFC1939] <URL:http://www.ietf.org/rfc/rfc1939.txt> に基いています。
メールを受信してファイル 'inbox/1' 'inbox/2'... に書きこみ、 サーバ上からメールを消します。 pop3.server.address は適宜読みかえてください。
require 'net/pop' Net::POP3.start( 'pop3.server.address', 110, 'YourAccount', 'YourPassword' ) {|pop| if pop.mails.empty? then puts 'no mail.' else i = 0 pop.each_mail do |m| # or "pop.mails.each ..." File.open( 'inbox/' + i.to_s, 'w' ) {|f| f.write m.pop } m.delete i += 1 end end puts "#{pop.mails.size} mails popped." }
以下は動作は同じでコードを短くしたバージョンです。
require 'net/pop' Net::POP3.start( 'pop3.server.address', 110, 'YourAccount', 'YourPassword' ) {|pop| if pop.mails.empty? then puts 'no mail.' else i = 0 pop.delete_all do |m| File.open( 'inbox/' + i.to_s, 'w' ) {|f| f.write m.pop } i += 1 end end }
クラスメソッドの POP3.delete_all を使うとさらに短くなります。
require 'net/pop' i = 0 Net::POP3.delete_all( 'pop3.server.address', 110, 'YourAccount', 'YourPassword' ) do |m| File.open( 'inbox/' + i.to_s, 'w' ) {|f| f.write m.pop } i += 1 end
これまでの例では m.pop の部分でメールをひとつの文字列として うけとっていましたが、たとえば 3MB くらいある巨大なメールの場合は これではまずい場合があります。そのような場合は以下のように m.pop に File オブジェクトを与える手が使えます。
require 'net/pop' Net::POP3.delete_all( 'pop3.server.address', 110, 'YourAccount', 'YourPassword' ) do |m| File.open( 'inbox', 'w' ) {|f| m.pop f #### } end
APOP 認証を使うには
の二通りの方法があります。
# (1) require 'net/pop' Net::APOP.start( 'apop.server.address', 110, 'YourAccount', 'YourPassword' ) {|pop| # Rest code is same. } # (2) require 'net/pop' Net::POP3.start( 'apop.server.address', 110, 'YourAccount', 'YourPassword', true #### ) {|pop| # Rest code is same. }
Net::POP3 オブジェクトを生成します。まだ接続はしません。 apop が真のときは APOP 認証を行うオブジェクトを生成します。
address の port 番ポートに接続し、アカウント account パスワード password で POP ログインします。第二引数 port に nil を渡すと POP3 のデフォルトポート(110)を使います。
Net::POP3.start( addr, port, account, password ) do |pop| pop.each_mail do |m| file.write m.pop m.delete end end
POP セッションを開き、サーバ上のすべてのメールに対して繰り返します。 以下と同じです。
Net::POP3.start( address, port, account, password ) {|pop| pop.each_mail do |m| yield m end } # example Net::POP3.foreach( 'your.pop.server', 110, 'YourAccount', 'YourPassword' ) do |m| file.write m.pop m.delete if $DELETE end
POP セッションを開き、サーバ上のメールをすべて削除します。 ブロックが与えられた時は削除する前にブロックにそのメールを 渡します。以下と同じです。
# example Net::POP3.delete_all( addr, nil, 'YourAccount', 'YourPassword' ) do |m| m.pop file end
POP セッションを開き認証だけを行って接続を切ります。 POP before SMTP 専用です。
# example pop = Net::POP3.auth_only( 'your.pop3.server', nil, # using default (110) 'YourAccount', 'YourPassword' )
リモートホストとの接続を開始し、アカウントに account、 パスワードに password を使って POP ログインします。
POP3 セッションが開始されていたら真。
接続するアドレス
接続するポート番号
接続時に待つ最大秒数。この秒数たってもコネクションが 開かなければ例外 TimeoutError を発生します。
読みこみ (read(1) 一回) でブロックしてよい最大秒数。 この秒数たっても読みこめなければ例外 TimeoutError を発生します。
POP3 セッションを終了します。セッション開始前にこのメソッドが 呼ばれた場合はなにもせずに false を返します。
Net::POPMail オブジェクトの配列をかえします。 この配列はセッションを開始したときに自動的に更新されます。
pop3.mails.each と同じです。
サーバ上のメールを全て消去します。 ブロックを与えられたときは消去する前にその POPMail オブジェクトを ブロックに渡します。
# example n = 1 pop.delete_all do |m| File.open("inbox/#{n}") {|f| f.write m.pop } n += 1 end
POP セッションを開き認証だけを行って接続を切ります。 POP before SMTP 専用です。
# example pop = Net::POP3.new( 'your.pop3.server' ) pop.auth_only 'YourAccount', 'YourPassword'
セッションをリセットします。 具体的には POPMail#delete で消したメールが全て復活します。 (POP3 ではメール一個だけを復活する方法はありません)
このクラスでは新しいメソッドは導入していません。 認証方式が APOP に変わるだけです。
Net::POP3
POP サーバー上のメール一通を抽象的に表現するクラス。 メールの取得や消去といった操作をカプセル化します。
メールを受信して dest に << メソッドを使って書きこみます。 dest を返します。
# example allmails = nil POP3.start( 'your.pop3.server', 110, 'YourAccount, 'YourPassword' ) do |pop| allmails = pop.mails.collect {|popmail| popmail.pop } end
メールの文字列を少しづつ読みこみ、順次ブロックに与えます。
# example POP3.start( 'localhost', 110 ) {|pop3| pop3.each_mail do |m| m.pop do |str| # do anything end end }
ヘッダだけを受信して文字列で返します。
メールヘッダと lines 行ぶんの本文を取得し文字列で返します。
サーバ上からメールを削除します。
メールのサイズ (単位はバイト) をかえします。
メールがサーバ上で消去されているとき真。消去してしまったら POP3#reset を使う以外に復活する方法はありません。
メールを送信するためのプロトコル SMTP (Simple Mail Transfer Protocol) を扱うライブラリです。ヘッダなどメールのデータを扱うことはできません。 SMTP の実装は [RFC2821] <URL:http://www.ietf.org/rfc/rfc2821.txt> に基いています。
SMTP を使ってメールを送るにはまず SMTP.start でセッションを開きます。 第一引数がサーバのアドレスで第二引数がポート番号です。 ブロックを使うと File.open と同じように終端処理を自動的にやってくれる のでおすすめです。
require 'net/smtp' Net::SMTP.start( 'your.smtp.server', 25 ) {|smtp| # use smtp object only in this block }
your.smtp.server は適切な SMTP サーバのアドレスに読みかえてください。 通常は LAN の管理者やプロバイダが SMTP サーバを用意してくれているはずです。
セッションが開いたらあとは send_mail でメールを流しこむだけです。
require 'net/smtp' Net::SMTP.start( 'your.smtp.server', 25 ) {|smtp| smtp.send_mail <<EndOfMail, 'your@mail.address', 'to@some.domain' From: Your Name <your@mail.address> To: Dest Address <to@some.domain> Subject: test mail Date: Sat, 23 Jun 2001 16:26:43 +0900 Message-Id: <unique.message.id.string@some.domain> This is test mail. EndOfMail }
ひとつ上の例では文字列リテラル(ヒアドキュメント)を使って送信しましたが、 each メソッドを持ったオブジェクトからならなんでも送ることができます。 以下は File オブジェクトから直接送信する例です。
require 'net/smtp' Net::SMTP.start( 'your.smtp.server', 25 ) {|smtp| File.open( 'Mail/draft/1' ) {|f| smtp.send_mail f, 'your@mail.address', 'to@some.domain' } }
SMTP ではメールを送る側のホストの名前を要求されるのですが、 ダイヤルアップなどの場合には自分のマシンに正式な名前がない場合が あります。そのような場合は適宜 SMTP サーバの名前などを与えてやら ないと配送を拒否されることがあります。SMTP.start あるいは SMTP#start の引数 helo_domain がそれです。
Net::SMTP.start( 'your.smtp.server', 25, 'mail.from.domain' ) {|smtp|
新しい SMTP オブジェクトを生成します。address はSMTPサーバーのFQDNで、 port は接続するポート番号です。ただし、このメソッドではまだ接続はしません。
以下と同じです。
Net::SMTP.new(address,port).start(helo_domain,account,password,authtype) # example Net::SMTP.start( 'your.smtp.server' ) { smtp.send_mail mail_string, 'from@mail.address', 'dest@mail.address' }
TCP コネクションを張り、同時に SMTP セッションを開始します。そのとき、 こちらのホストの FQDN を helo_domain に指定します。 もしすでにセッションが開始していたら何もせずに false を返します。
account と password の両方が与えられた場合、AUTH コマンドによって 認証を行います。authtype は使用する認証のタイプで、シンボル で :plain か :cram_md5 を指定します。
SMTP セッションが開始されていたら真。
接続するアドレス
接続するポート番号
接続時に待つ最大秒数。この秒数たってもコネクションが 開かなければ例外 TimeoutError を発生します。
読みこみ (read(1) 一回) でブロックしてよい最大秒数。 この秒数たっても読みこめなければ例外 TimeoutError を発生します。
SMTP セッションを終了します。セッション開始前にこのメソッドが 呼ばれた場合はなにもせずに false を返します。
mailsrc をメールとして送信します。mailsrc は each イテレータを持つ オブジェクトならなんでも構いません (たとえば String や File)。 from_domain は送り主のメールアドレス ('...@...'のかたちのもの) で、 to_addrs には送信先メールアドレスを並べます。
# example Net::SMTP.start( 'your.smtp.server' ) {|smtp| smtp.send_mail mail_string, 'from@mail.address', 'dest@mail.address' 'dest2@mail.address' }
メール書きこみの準備をしたうえで、write メソッドを持つオブジェクトを ブロックにあたえます。from_addr は送信元メールアドレスで to_addrs は 宛先のメールボックスです。
# example Net::SMTP.start( 'your.smtp.server', 25 ) {|smtp| smtp.ready( 'from@mail.addr', 'dest@mail.addr' ) do |adapter| adapter.write str1 adapter.write str2 adapter.write str3 end }
セッション中に (SMTP レベルの) エラーがおこった場合、 以下の例外が発生します。
SMTP コマンドの構文ミス(500番台)
恒久的なエラー(550番台)
予期しないエラー。おそらくバグ
一時的なエラー(420/450番台)
--> Net::Telnet
require 'net/telnet' # リモートホスト foobar に接続 telnet = Net::Telnet.new("Host" => "foobar") {|c| print c} # ログイン telnet.login("your name", "your password") {|c| print c} # ログイン後、プロンプトが出るまで待ち合わせる telnet.cmd("ls") {|c| print c} # コマンド実行後、プロンプトが出るまで待ち合わせる # 少し複雑な例 telnet.cmd("sleep 5 && echo foobar &") {|c| print c} STDOUT.flush # <- これがないとここまで処理が来てることがわかりにくい # 前のコマンドの出力を待ち合わせる telnet.waitfor(/foobar\Z/) {|c| print c} # ログインセッションの終了 telnet.cmd("exit") {|c| print c} telnet.close
Net::Telnet のインスタンスは、ソケットのメソッドをdelegateします(例え ば、セッションが終わった後は close を実行した方が良いでしょう)。
Net::Telnet.new(opts)
Telnetオブジェクトを生成します。このときリモートホストへの接続も行いま す。opts には Telnet オブジェクトに設定する以下のオプションをハッ シュで指定します。オプションは省略時にはそれぞれ右に示すデフォルト値が 適用されます。
Host => "localhost" Port => 23 Prompt => /[$%#>] \z/n Timeout => 10 # 接続待ちタイムアウト値(sec) Waittime => 0 # Prompt を待ち合わせる時間。この値を nil にしてはいけません Binmode => false Telnetmode => true Output_log => nil # 出力ファイル名 Dump_log => nil # 出力ファイル名 Proxy => nil # Net::Telnet または IO のオブジェクトを指定する
生成されたインスタンスは TCPSocket あるいは "Proxy" で指定したオ ブジェクトが持つメソッドを受け付けます(SimpleDelegatorにより delegateされる)。
"Timeout" で指定した時間までに接続できない場合 TimeoutError 例外 が発生します。
"Waittime" は Net::Telnet#waitfor メソッドの "Waittime" のデフォ ルト値になります。waitfor メソッドのプロンプト待ち合わせの処理は、リモー トホストからの出力が "Prompt" で指定した正規表現にマッチしてから "Waittime" 秒待っても出力がないかどうかで判断されます。 waitfor メソッドは Net::Telnet#cmd や Net::Telnet#login の内部でも使用されています。
ブロックを指定した場合、接続前に
"Trying #{ホスト名} ...\n"
接続後に
"Connected to #{ホスト名}.\n"
という文字列を引数にそれぞれブロックを実行します。
Net::Telnet#login(user[, password])
Net::Telnet#login("Name"=>user, "Password"=>password)
ユーザ名user, パスワードpasswordでログインします。 リモートホストが以下のプロンプトでユーザ名、パスワードの入力を要求する ことを期待しています。
xxxlogin: Password:
これに適合しない場合は、自分で例えば以下のようにログインを行う必要があ ります。
# ログイン時にいきなりパスワードの問い合わせが来る場合 telnet = Net::Telnet.new("Host"=>"localhost") {|c| print c} telnet.waitfor(/Password[: ]*\z/n) {|c| print c} telnet.cmd("your password")
ブロックを指定した場合、出力文字列を引数にブロックを逐次実行します。
Net::Telnet#waitfor(match)
Net::Telnet#waitfor("Match"=>match, "Timeout"=>timeout, "Waittime"=>waittime)
正規表現 match で指定した文字列が出力されるまで待ち合わせます。 match の代わりに "String" をキーに文字列を指定した場合、 リモートホストからの出力にその文字列が現れるまで待ち合わせます。
timeout 待っても何も出力がなければ TimeoutError 例外が発生 します。
timeout, waittime のデフォルト値は new で指定した "Timeout", "Waittime" の値です。
ブロックを指定した場合、出力文字列を引数にブロックを逐次実行します。
Net::Telnet#cmd(string)
Net::Telnet#cmd("String"=>string, "Match"=>match, "Timeout"=>timeout)
string を改行付きでリモートホストに送り、次のプロンプト match が出力されるまで待ちます。
match のデフォルト値は new で指定した "Prompt" の値です。 timeout のデフォルト値は new で指定した "Timeout" の値です。
ブロックを指定した場合、出力文字列を引数にブロックを逐次実行します。
Net::Telnet#puts(string)
string を改行を付けてリモートホストに送ります。
Net::Telnet#telnetmode
Net::Telnet#telnetmode(bool)
Net::Telnet#telnetmode = bool
...
Net::Telnet#binmode
Net::Telnet#binmode(bool)
Net::Telnet#binmode = bool
...
Net::Telnet#sock
リモートホストに接続している IO オブジェクトを返します。
--> SimpleDelegator
--> NKF
nkf(1) (Network Kanji code conversion Filter version 1.7)を ruby から使うためのモジュールです。
以下は、漢字コード変換コマンドの例です。
#!/usr/local/bin/ruby require 'nkf' opt = '' opt = ARGV.shift if ARGV[0][0] == ?- while line = ARGF.gets print NKF.nkf(opt, line) end
以下は、漢字コード判別コマンドの例です。
#!/usr/local/bin/ruby require 'nkf' CODES = { NKF::JIS => "JIS", NKF::EUC => "EUC", NKF::SJIS => "SJIS", NKF::BINARY => "BINARY", NKF::UNKNOWN => "UNKNOWN(ASCII)", } while file = ARGV.shift str = open(file) {|io| io.gets(nil) } printf "%-10s ", file if str.nil? puts "EMPTY" else puts CODES.fetch NKF::guess(str) end end
NKF.nkf(opt, str)
文字列 str の文字コードを変換し、変換結果の文字列を返します。
opt には、
nkf(1)
と同じコマンドラインオプションを指定します。複数指定する場合は、
NKF.nkf('-Se', str)
や NKF.nkf('-S -e', str)
などとし
ます。optは、必ず '-'
で始めなければいけないことに注意
してください
このメソッドは(nkf コマンドがそうであるように)、MIME Base64 の デコード処理がデフォルトでオンになっています。この動作を無効にしたけ れば opt に '-m0' を含めるようにしてください。
NKF.guess(str)
文字列 str の漢字コードを判別して返します。 返される値は、NKF モジュールのモジュール定数です(下記参照)。
NKF::JIS
JISコードを表します。
NKF::EUC
EUCコードを表します。
NKF::SJIS
SJISコードを表します。
NKF::BINARY
入力が binary であることを表します。
NKF::UNKNOWN
コード判定に失敗したことを表します。 入力が ASCII 文字列でもこの値になります。
--> Observable
Mix-inによりobserverパターンを提供する。
Observableモジュールをincludeしたクラスは Observable#changedメソッドにより更新フラグを立て、 Observable#notify_observers()が呼び出されると 更新フラグが立っている場合はオブザーバに通知する (オブザーバのupdateメソッドを呼び出す)。 Observable#notify_observers()の引数は そのままオブザーバのupdateメソッドに渡される。
require 'observer' class AObservable include Observable ... end class AObserver def update(arg) ... end ... end obj = AObservable::new observer = AObserver::new obj.add_observer(observer) obj.changed obj.notify_observers(args)
Observable#add_observer(observer)
オブザーバを追加する。
オブザーバはupdate
メソッドを備えている必要がある。
observerがupdate
メソッドを持たないときは
例外NameErrorを発生する。
Observable#delete_observer(observer)
オブザーバを削除する。
Observable#delete_observers
オブザーバをすべて削除する。
Observable#count_observers
オブザーバの数を返す。
Observable#changed(state=true)
更新フラグを立てる。
Observable#changed?
更新フラグの状態を返す。
Observable#notify_observers(*arg)
更新フラグが立っていたら、オブザーバのupdate
メソッドを呼び出す。
与えられた引数はそのupdate
メソッドに渡される。
更新フラグはfalse
になる。
--> Open3
[2001/02/05] るびきち
perlにあるopen3のruby版。
require "open3" inn, out, err = Open3.popen3('nroff -man')
include Open3 inn, out, err = popen3('nroff -man')
class String def external_filter (prog) require 'open3' pipe = Open3.popen3(prog) pipe[0] .print self pipe[0] .close pipe[1] .read end end
String#external_filter(prog)
Stringを標準入力として外部プログラムprogを起動し、標準出力をStringとして返す。 標準添付希望。
[2001/06/18] ゆん
このまんまだとバッファサイズの関係で、 文字列がでかい時にパイプが詰まってロックがかかっちゃうみたいなんで、 このくらいの方がいいみたい。
んでもって標準添付希望ー。
class String def external_filter (prog) require 'open3' pipe = Open3.popen3(prog) Thread.start do s = 0 while s < size s += pipe[0].write(self[s, 1024]) end pipe[0].close end pipe[1] .read end end
Open3.popen3(cmd)
外部プログラムcmdを実行し、そのプロセスの標準入力、標準出力、 標準エラー出力に接続されたパイプを3要素の配列で返す。 cmd は execと同じ規則で解釈される。
ブロックを指定するとパイプの配列を引数にブロックを実行し、最後に パイプを close する。この場合はブロックの最後の式の結果を返す。
require 'open3' Open3.popen3("read stdin; echo stdout; echo stderr >&2") {|stdin, stdout, stderr| stdin.puts "stdin" p stdout.read p stderr.read } #=> "stdout\n" "stderr\n"
--> OpenStruct
[2001/02/07] るびきち
手軽な構造体クラス。
method_missing
の使い方の例でもある。
require 'ostruct' s = OpenStruct.new s.foo = 25 p s.foo # => 25 s.bar = 2 p s.bar # => 2 p s # => <OpenStruct bar=2 foo=25> s.delete_field("foo") p s.foo # => nil p s # => <OpenStruct bar=2> t = OpenStruct.new("foo"=>"bar") p t.foo # => "bar" t.baz = "fobar" p t.baz # => "fobar"
OpenStruct.new(hash = nil)
OpenStruct
オブジェクトを生成。
hashが与えられたとき、
OpenStruct#delete_field(name)
nameで指定された要素を削除。
その後その要素を参照したらnil
が返る。
Author: <jammy@shljapan.co.jp>
オプションを解析し、`$OPT_xxx'に値を設定します。更に指定したオプシ ョンが条件にあっていない場合、USAGE を表示します。
parseArgs(MIN_ARGC、CHECH_OPTS、SINGLE_OPTS、*OPTS)
`-'や`--'を伴って指定するオプション以外のオプションの最低必要数 を指定します。存在しない場合は0を指定します。
どのオプションが必要条件かを指定します。第三、第四引数で指定する オプションのうち必要なものを'('、')'、'|'、'&' を使って並べ、全 体をダブルクォテーションで括ります。 Rubyスクリプト実行時に全て のオプションが省略可能ならば `nil'を指定して下さい。 以下の例では、"-d" と最低でも "-x"、"-y"、"--geometry"のど れか一つが実行時に必要なオプションとなります。 `parseArgs(0、"d&(x|y|geometry)"、"fd"、"x:"、"y:"、"geometry:"、"version")'
getopts の第一、第二引数と同じです。
getopts のオプション解析と同じです。
`$USAGE'に`usage()'(名前は何でもよい)をセットします。
def usage() printf("Usage:\n") : end $USAGE='usage'
parsedate[23] - 日付と時刻の解析
<URL:http://www.funaba.org/ruby.html#date2>*99
--> ParseDate
これはもうひとつの日付解析モジュールです。
このモジュールは与えられた日付表現を解析するメソッドを提供します。 これは、ctime(3)、伝統的な date(1)、 RFC 822 日付、RFC 850 日付、 ISO 8601 の一部、JIS X0301 拡張の一部、などを受けつけます。
解析結果をTimeオブジェクトにする。
module ParseDate def to_time(date, cyear=false) ary = parsedate(date, cyear) if ary[6] == 'GMT' Time::gm(*ary[0..-3]) else Time::local(*ary[0..-3]) end end module_function :to_time end to_time ("Wed, 24 Jan 01 06:46:26 GMT").localtime => "Wed Jan 24 15:46:26 JST 2001"
なお、time.rb で同様のことができる(time.rb は、parsedate.rb を利 用している)。
require 'time' p Time.parse("Wed, 24 Jan 01 06:46:26 GMT").localtime => Wed Jan 24 15:46:26 JST 2001
ParseDate.parsedate(date, cyear=false)
dateは日付文字列。
さまざまな形式に対応している。
cyear
が指定してあるときは、年を2桁表記から4桁表記に直す。
二桁表記で69以上ならば1900年代、それ未満のときは2000年代とみなされる。
[年, 月, 日, 時, 分, 秒, タイムゾーン, 曜日] の配列が返る。
--> Ping
Ping.pingecho(host, timeout=5, service='echo')
host の TCP サービスserviceに対して接続を試み 成功すれば true を返します。ping(1) と異なり ICMP を使用しないので root 権限を必要としない利点があります。
注: 最近は不要なサービスを受け付けないホストが多いので必ずしもこの モジュールが有用とは限りません*100
--> PStore
Rubyのオブジェクトを外部ファイルに格納するためのクラス。 内部でMarshalを使っている。
db = PStore.new("/tmp/foo") db.transaction do p db.roots ary = db["root"] = [1,2,3,4] ary[0] = [1,1.5] end db.transaction do p db["root"] end
データベースにアクセスするためには、transactionのブロック内である必要がある。 インターフェースはHashライクである。
PStore.new(file)
ファイル名fileでデータベースを読み書きする。
fileのあるディレクトリは書き込み可能である必要がある。
なぜなら、データベースを更新するときにバックアップファイルが作成されるからだ。
バックアップファイル名はファイル名の後に~
がつく。
PStore#transaction
PStore#transaction(read_only=false) ((<ruby 1.7 feature>))
トランザクションに入る。 このブロックの中でしかデータベースの読み書きはできない。
ruby 1.7 feature: 1.7では読み込み専用のトランザクションが使用可能。
PStore#[name]
ルートnameに対応する値を得る。
Hash#[]
に相当。
PStore#[name] = value
ルートnameに対応する値valueをセットする。
Hash#[]=
に相当。
PStore#delete(name)
ルートnameに対応する値を削除する。
Hash#delete
に相当。
PStore#roots
ルートの集合を配列で返す。
Hash#keys
に相当。
PStore#root?(name)
nameがルートであるかどうか。
Hash#key?
に相当。
PStore#path
データベースのファイル名を得る。
PStore#commit
データベースの読み書きを終了する。 すなわち、transactionブロックから抜ける。 データベースの変更が反映される。
PStore#abort
データベースの読み書きを終了する。 transactionブロックから抜けるが、データベースの変更は反映されない。
PStore#in_transaction
トランザクションの中でなければ例外を発生させる。
--> PTY
疑似端末(Pseudo tTY)を扱うモジュール
--> ruby-src:ruby/ext/pty/README.ja
--> Rational
--> Config
IO#readbytes(size)
IO#readと同様にsizeバイト読み込みますが、 EOFに到達した時に例外 EOFError を発生させます。 sizeバイト未満しか読み込めなかった時には 例外 TruncatedDataError を発生させます。
IO#readbytes が発生させる例外
TruncatedDataError#data
例外が発生するまでに読み込んだデータを文字列で返します。
--> Readline
GNU Readline によるコマンドライン入力インタフェースを提供するモジュー ルです。
このようにして使います。
require "readline" while buf = Readline.readline("> ", true) print "-> ", buf, "\n" end
Readline.readline([prompt, [add_hist]])
ユーザからのキー入力を求め、入力した文字列を返します。EOF(UNIX で は ^D)を入力すると nil を返します。
入力時には行内編集が可能で、vi モードと Emacs モードが用意されています。 (Readline.vi_editing_mode、Readline.emacs_editing_mode を参照)。デフォルトは Emacs モードです。
文字列 prompt を指定するとカーソルの前にこの文字列を表示します。
add_hist が真ならば、入力した文字列はヒストリに記録されます。 Emacs モードなら ^P を入力することで前に入力した文字列を呼び出した り、Readline::HISTORY モジュールによりヒストリの内容を操作す ることができます。このデフォルト値は nil です。
入力待ちの状態で ^C すると ruby インタプリタもろとも終了し端末状 態を復帰しません。これを回避するには、
stty_save = `stty -g`.chomp begin while buf = Readline.readline p buf end rescue Interrupt system("stty", stty_save) exit end
または、
stty_save = `stty -g`.chomp trap("INT") { system "stty", stty_save; exit } while buf = Readline.readline p buf end
などとします。単に、^C を受け付けなくするだけならば以下で十分です。
trap("INT", "SIG_IGN") while buf = Readline.readline p buf end
Readline.completion_proc= proc
補完時の動作を決定するProcオブジェクトを指定します。
procは引数に入力文字列を取り、候補文字列の配列を返すように
してください。
入力文字列は単語ごとに区切られます。
bashの補完と同じく/[ \t\n\"\\'`@$><=;|&{(]/
で単語に区切ります。*101
require 'readline' WORDS = %w(foo foobar foobaz) Readline.completion_proc = proc {|word| WORDS.grep(/^#{Regexp.quote word}/) } while buf = Readline.readline("> ") p buf end
Readline.basic_word_break_characters=(str)
Readline.basic_word_break_characters
補完時の単語同士の区切りを指定する basic な文字列。デフォルトでは Bash用の文字列 " \t\n\"\\'`@$><=;|&{(" (スペース含む)になっています。
Readline.completer_word_break_characters=(str)
Readline.completer_word_break_characters
rl_complete_internal() で使われる、補完時の単語同士の区切りを指定する 文字列です。デフォルトでは Readline.basic_word_break_characters です。
Readline.basic_quote_characters=(str)
Readline.basic_quote_characters
引用符を指定します。デフォルトでは、/"'/ です。
Readline.completer_quote_characters=(str)
Readline.completer_quote_character
補完時の引用符を指定します。この引用符の間では、completer_word_break_characters も、普通の文字列として扱われます。
Readline.filename_quote_characters=(str)
Readline.filename_quote_characters
補完時のファイル名の引用符を指定します。デフォルトでは nil です。
Readline.completion_proc
補完時の動作を決定するProcオブジェクトを返します。
Readline.completion_case_fold=(bool)
Readline.completion_case_fold
入力補完時に大文字/小文字の区別をするかどうかを決定します。 bool が真ならば区別しません。
Readline.vi_editing_mode
編集モードを vi モードにします。詳細は、GNU Readline のマニュアル を参照してください。
Readline.emacs_editing_mode
編集モードを Emacs モードにします。デフォルトは Emacs モードです。
詳細は、GNU Readline のマニュアルを参照してください。
Readline::FILENAME_COMPLETION_PROC
Readline::USERNAME_COMPLETION_PROC
ライブラリに組み込みで用意された補完用 Proc オブジェクトです。 それぞれファイル名、ユーザ名の補完を行います。 Readline.completion_proc= で使用します。
Readline::HISTORY
Readlineモジュールで入力した内容は入力履歴として記録されます(有効にし ていればですが。Readline.readline を参照)
この定数により、入力履歴の内容にアクセスすることができます。おおよそ、 Array クラスのインスタンスのように振舞います。 (Enumerable モジュールをextend しています)
while buf = Readline.readline("> ", true) p Readline::HISTORY.to_a print "-> ", buf, "\n" end
空行や直前の入力と同じ内容は入力履歴に残したくないと思うかも知れません。 この場合、以下のようにします。
while buf = Readline.readline("> ", true) # p Readline::HISTORY.to_a Readline::HISTORY.pop if /^\s*$/ =~ buf begin Readline::HISTORY.pop if Readline::HISTORY[Readline::HISTORY.length-2] == buf rescue IndexError end # p Readline::HISTORY.to_a print "-> ", buf, "\n" end
以上が追加されました。
BasicSocket#send
、IPSocket.getaddress
、
TCPSocket.new
、TCPSocket.open
、
UDPSocket#connect
、UDPSocket#send
の
名前解決にResolvを使うようにメソッドの書き換えをする。
--> Resolv
Rubyで書かれたリゾルバ(名前解決)ライブラリ。 Since it is written in Ruby, it is thread-aware. I.e. it can resolv many hostnames concurrently.
It is possible to lookup various resources of DNS using DNS module directly.
Resolv.getaddress("www.ruby-lang.org") Resolv.getname("210.251.121.214").to_s Resolv::DNS.new.getresources("www.ruby-lang.org", Resolv::DNS::Resource::IN::A).collect {|r| r.address} Resolv::DNS.new.getresources("ruby-lang.org", Resolv::DNS::Resource::IN::MX).collect {|r| [r.exchange.to_s, r.preference]}
Resolv.getaddress(name)
Resolv.getaddresses(name)
Resolv.each_address(name) {|address| ...}
They lookups IP addresses of name which represents a hostname as a string.
getaddress returns first entry of lookupped addresses. getaddresses returns lookupped addresses. each_address iterates over lookupped addresses.
例:
Resolv.getaddress("www.ruby-lang.org").to_s #=> "210.251.121.214"
Resolv.getname(address)
Resolv.getnames(address)
Resolv.each_name(address) {|name| ...}
lookups hostnames of address which represents IP address as a string.
getname returns first entry of lookupped names. getnames returns lookupped names. each_names iterates over lookupped names.
例:
Resolv.getname("210.251.121.214").to_s #=> "helium.ruby-lang.org"
hostname resolver using /etc/hosts format.
Resolv::Hosts.new(hosts='/etc/hosts')
Resolv::Hosts#getaddress(name)
Resolv::Hosts#getaddresses(name)
Resolv::Hosts#each_address(name) {|address| ...}
address lookup methods.
Resolv::Hosts#getname(address)
Resolv::Hosts#getnames(address)
Resolv::Hosts#each_name(address) {|name| ...}
hostnames lookup methods.
DNS stub resolver.
Resolv::DNS.new(resolv_conf='/etc/resolv.conf')
Resolv::DNS#getaddress(name)
Resolv::DNS#getaddresses(name)
Resolv::DNS#each_address(name) {|address| ...}
address lookup methods.
name must be a instance of Resolv::Name or String. Lookupped address is represented as an instance of Resolv::IPv4 or Resolv::IPv6.
Resolv::DNS#getname(address)
Resolv::DNS#getnames(address)
Resolv::DNS#each_name(address) {|name| ...}
hostnames lookup methods.
address must be a instance of Resolv::IPv4, Resolv::IPv6 or String. Lookupped name is represented as an instance of Resolv::Name.
Resolv::DNS#getresource(name, typeclass)
Resolv::DNS#getresources(name, typeclass)
Resolv::DNS#each_resource(name, typeclass) {|resource| ...}
They lookup DNS resources of name. name must be a instance of Resolv::Name or String.
typeclass should be one of follows:
Lookupped resource is represented as an instance of (a subclass of) Resolv::DNS::Resource.
name
name
mname
rname
serial
refresh
retry
expire
minimum
cpu
os
rmailbx
emailbx
preference
exchange
data
address
address
protocol
bitmap
name
address
Resolv::DNS::Name.create(name)
Resolv::DNS::Name#to_s
Resolv::IPv4.create(address)
Resolv::IPv4#to_s
Resolv::IPv4#to_name
Resolv::IPv4::Regex
IPv4のアドレスの正規表現。
Resolv::IPv6.create(address)
Resolv::IPv6#to_s
Resolv::IPv6#to_name
Resolv::IPv6::Regex
IPv6のアドレスの正規表現。
NISはサポートされていません。
--> SDBM
digest/sha1.so をロードして SHA1 を Digest::SHA1
に置き換えます
ruby-src:ruby/doc/shell.rd を参照
--> Shellwords
Unixのシェルと同じように単語に分割して、 分割した単語の配列を返す。
--> Singleton
Mix-inによりsingletonパターンを提供する。
Singletonモジュールをincludeすることにより、クラスは 高々ひとつのインスタンスしか持たないことが保証される。
Singletonをmix-inしたクラスの
クラスメソッドinstance
はその唯一のインスタンスを返す。
new
はprivateメソッドに移され、外部から呼び出そうとするとエラーになる。
class SomeSingletonClass include Singleton #.... end a = SomeSingletonClass.instance b = SomeSingletonClass.instance # a and b are same object p [a,b] a = SomeSingletonClass.new # error (`new' is private)
Singleton#instance
そのクラスの唯一のインスタンスを返す。 最初に呼ばれたときはそのインスタンスを生成する。
Singletonをincludeしたクラスで定義されるので、 正確にはSingletonモジュールのメソッドではない。
AF_INETなソケットにおいてホストを指定するには以下のいずれか の形式を指定します。
INADDR_ANY
に相当"<broadcast>"
- INADDR_BROADCAST
に相当サービスを指定するには以下のいずれかの形式を指定します。
ソケットを表す抽象クラス。具体的なソケット操作はサブクラスで 定義されます。 例えばインターネットドメインストリームソケットの場合は TCPSocketを用います。
この値が真ならアドレスからホスト名への逆引きを行わなくなります。 デフォルトは false です。この設定は大域的に作用します。 *103
require 'socket' p TCPSocket.new('localhost', 'telnet').addr TCPSocket.do_not_reverse_lookup = true p TCPSocket.new('localhost', 'telnet').addr => ["AF_INET", 2253, "localhost", "127.0.0.1"] ["AF_INET", 2254, "127.0.0.1", "127.0.0.1"]
Socket.for_fd(fd) ((<ruby 1.7 feature>))
ファイルディスクリプタ fd に対する新しいソケットを生成します。
ruby 1.7 feature: このメソッドは Socket クラスからこのクラスに移動しました。 これにより、任意のソケットである fd から対応するソケッ トクラスを作ることができます。
接続の相手先のソケットの情報を取得します。sockaddr構造体をパッ
クした文字列を返します。getpeername(2)
を参照の
こと。
ソケットの情報を取得します。sockaddr構造体をパックした
文字列を返します。getsockname(2)
を参照のこと。
ソケットのオプションを取得します。getsockopt(2)
を参照のこと。取得したオプションのデータをパックした文字列を
返します。
ソケットからデータを受け取り、文字列として返します。 lenは受け取る最大の長さを指定します。 flagsについてはrecv(2)を参照。flagsの デフォルト値は0です。flagsの指定に必要な定数は Socketクラスで定義されています。(例: Socket::SO_LINGER)
ソケットを介してデータを送ります。flagsに関しては
send(2)
を参照してください。connect
していないソケットに対しては送り先であるtoを指定
する必要があります。実際に送ったデータの長さを返します。
ソケットのオプションを設定します。setsockopt(2) を参照のこと。*104
ソケットの以降の接続を終了させます。howが0である
時、以降の受信が、1である時は、以降の送信が拒否されます。
howが2の時には、それ以降の送信、受信ともに拒否さ
れます。howを省略すると2を指定したことになります。
shutdown(2)
を参照。
インターネットドメインソケットのクラス。通常の IOクラスのサブクラスと同 様の入出力ができます。
ホスト名からホストのアドレスを返します。ホストのアドレスは文 字列はoctet decimalの文字列(例:127.0.0.1)です。
ソケットの接続情報を表す配列を返します。配列の各要素は第1要 素が文字列 "AF_INET"、第2要素がport番号、第3要素がホストを表 す文字列、第4要素がホストのIPアドレスを表す文字列(octet decimal)です。*105
接続相手先ソケットの情報を表す配列を返します。配列の各要素は IPSocket#addrメソッドが返す配列 と同じです。
recv
と同様にソケットからデータを受け取りますが、
戻り値は文字列と相手ソケットのアドレス(形式は
IPSocket#addr参照)のペアです。引数につ
いてはBasicSocket#recvと同様です。
インターネットドメインのストリーム型ソケットのクラス。通常の IOクラスのサブクラスと同 様の入出力ができます。このクラスによってソケットを用いたクラ イアントを簡単に記述できるようになります。ユーザの入力をその ままサーバに転送するプログラムは以下のようになります。
require "socket" port = if ARGV.size > 0 then ARGV.shift else 4444 end print port, "\n" s = TCPSocket.open("localhost", port) while gets s.write($_) print(s.gets) end s.close
hostで指定したホストのserviceで指定したポートと接続したソケッ
トを返します。hostはホスト名、またはoctet decimal
によるインターネットアドレスを示す文字列、service
は/etc/services
(またはNIS)に登録されているサー
ビス名かポート番号です。
ruby 1.7 feature: 引数 local_host, local_service を指定した場合、そのアドレス に対してbind(2)します。
ホスト名またはIPアドレス(整数または"127.0.0.1"
のような文字列)からホストの情報を返します。ホスト情報は、ホ
スト名、ホストの別名の配列、ホストのアドレスタイプ、ホストの
アドレスを各要素とする配列です。ホストのアドレスはoctet
decimalの文字列("127.0.0.1"
のような文字列)です。
TCP/IPストリーム型接続のサーバ側のソケットのクラス。このクラ スによって簡単にソケットを利用したサーバのプログラミングがで きます。例えばechoサーバは以下のようになります。
require "socket" gs = TCPServer.open(0) socks = [gs] addr = gs.addr addr.shift printf("server is on %s\n", addr.join(":")) while true nsock = select(socks) next if nsock == nil for s in nsock[0] if s == gs socks.push(s.accept) print(s, " is accepted\n") else if s.eof? print(s, " is gone\n") s.close socks.delete(s) else str = s.gets s.write(str) end end end end
Thread
を使えばもっと短くなります。
require "socket" gs = TCPServer.open(0) addr = gs.addr addr.shift printf("server is on %s\n", addr.join(":")) while true Thread.start(gs.accept) do |s| # save to dynamic variable print(s, " is accepted\n") while s.gets s.write($_) end print(s, " is gone\n") s.close end end
TCPServer.new([host, ]service)
TCPServer.open([host, ]service)
新しいサーバー接続をオープンします。serviceは
/etc/services
(またはNIS)に登録されているサービ
ス名かポート番号で指定します。hostを指定した時は
指定したホストに対しての接続だけを受け付けます。省略時は全てのホ
スト(インタフェース)への接続要求を受け付けることになります。
accept
クライアントからの接続要求を受け付け、接続した
TCPSocket
のインスタンスを返します。
listen(backlog) ((<ruby 1.7 feature>))
backlog は、クライアントからの接続要求を保留できる数です。 TCPServer のインスタンスは最初は backlog の値は 5 で生成されます。
listen(2) が成功すれば 0 を返します。 失敗すれば 例外 Errno::EXXX が発生します。
UDP/IPデータグラム型ソケットのクラス。
新しいUDPソケットを返します。
ソケットをhostのportに結合します。
ソケットをhostのportにconnectします。
ソケットを介してデータを送ります。flagsに関しては
send(2)
を参照してください。connect
していないソケットに対しては送り先を指定するためhost
とportを指定する必要があります。実際に送ったデー
タの長さを返します。
UNIXドメインのストリーム型ソケットのクラス。通常の IOクラスのサブクラスと同様の 入出力ができます。
pathで指定したパス名を用いて接続したソケットを返 します。
相互に結合されたUNIXソケットのペアを含む2要素の配列を返します。 type が省略された場合、Socket::SOCK_STREAM が使われます。 protocol が省略された場合、0 が使われます。
ソケットの接続情報を表す配列を返します。配列の各要素は第1要 素が文字列 "AF_UNIX"、第2要素がパスを表す文字列です。
UNIXソケットのパスを返します。
接続相手先ソケットの情報を表す配列を返します。配列の各要素は IPSocket#addrメソッドが返す配列 と同じです。
recv
と同様にソケットからデータを受け取りますが、
戻り値は文字列と相手ソケットのパスのペアです。引数につい
てはrecvと同様です。
ファイルディスクリプタを受け取ります。
klass が nil の場合、ファイルディスクリプタが Fixnum として 返されます。
klass が nil でない場合、
klass.for_fd(fd[, mode])
が呼ばれ、その値が返されます。
klass が省略された場合は IO
が指定されたものとみなされ、
IO.for_fd(fd[, mode])
が呼ばれます。
IO や Fixnum に対応するファイルディスクリプタを送ります。
UNIXストリーム型接続のサーバ側のソケットのクラス。
UNIXServer.open(path)
UNIXServer.new(path)
pathで指定したパス名を用いて接続を受け付けるソケットを返 します。
accept
クライアントからの接続要求を受け付け、接続した UNIXSocketのインスタンスを返します。
listen(backlog) ((<ruby 1.7 feature>))
backlog は、クライアントからの接続要求を保留できる数です。 UNIXServer のインスタンスは最初は backlog の値は 5 で生成されます。
listen(2) が成功すれば 0 を返します。 失敗すれば 例外 Errno::EXXX が発生します。
ソケットそのものに対するシステムコールレベルのアクセスを提供 するクラス。Perlのソケットに対するアクセスと同レベルの機能を 提供してます。このクラスではソケットアドレスは pack された文字列で指定します。
一般的なソケットプログラミングはより高レベルの TCPSocketクラスや TCPServerクラスを用い て行われることが多く、このクラスはあまり用いられません。
Socket.open(domain, type, protocol)
Socket.new(domain, type, protocol)
新しいソケットを生成します。domain、type、
protocol はインクルードファイルにある定数で指定しま
す。ほとんどの定数は Socket::AF_INET
のように
Socket クラスの定数として定義されています。domain
とtype に関しては、"AF_INET"
,
"SOCK_STREAM"
のように文字列でも指定できますが、文
字列ですべての機能を指定できる保証はありません。
Socket.for_fd(fd)
ファイルディスクリプタ fd に対する新しいソケットを生成します。
ruby 1.7 feature: このメソッドは BasicSocket に移動しました。
Socket.getaddrinfo(nodename, servname[, family[, socktype[, protocol[, flags]]]])
RFC:2553で定義された
getaddrinfo()
の機能を提供するクラスメソッド。この関数は
gethostbyname()
やgetservbyname()
の代わりとして用意されており、
IPのバージョンに依存しないプログラムを書くための標準的なAPIです。
アドレス情報の配列を返します。アドレス情報とは7つの要素からなる次の 形の配列です。
必須引数の意味は以下の通りです。
残りの引数は省略可能です。
Socket::AF_INET
など、
アドレスファミリーにある定数を指定します。Socket::SOCK_STREAM
など、
ソケットタイプにある定数を指定します。Socket::IPPROTO_IP
など、
プロトコルにある定数を指定します。Socket::AI_PASSIVE
、
Socket::AI_CANONNAME
、
Socket::AI_NUMERICHOST
が用意されている場合があります。引数に指定できる定数の意味については getaddrinfo(3) を参照して下さい。
Socket.getnameinfo(sa[, flags])
RFC:2553 で定義されたgetnameinfo()
の機能を提供するク
ラスメソッド。 gethostbyaddr()
や getservbyport()
の代
わりとして用意されています。IPのバージョンに依存しないプログラムを
書くための標準的なAPIです。
配列を返し、その要素はアドレスとポートを表す文字列です。
引数 sa には文字列か配列を与えます。文字列の場合は sockaddr 構造体 のパック文字列を与えます。具体的には getsockaddr の値が利用できます。配列を与える場合には、要素が3つの場合と4つの場合 があります。
要素が3つの場合:
[アドレスファミリー, サービス, ホスト]
要素が4つの場合:
[アドレスファミリー, サービス, 任意, アドレスを表す文字列]
アドレスファミリーには Socket::AF_INET
等の定数の他に文字列
で "AF_INET"
もしくは "AF_INET6"
もしくは nil
が
指定できます。ただしIPv6が使えないようにコンパイルされている場合は
"AF_INET6"
は無効な指定となります。アドレスファミリーに
nil
を指定することは Socket::AF_UNSPEC
を指定すること
と等価です。
サービス、ホストの指定に関しては サービス指定形式、 ホスト指定形式を参照してください。
要素が3つの場合でも、ホストにはアドレスを指定できますが、要素が4つ の場合には、最後の要素を名前解決しないことが保証されます。*108
省略可能な第2引数 flags には getnameinfo(3) の第7番目の引数に指定する flags に相当する Fixnum を与えます。
引数flagsを構成するための定数として
Socket::NI_MAXHOST
、
Socket::NI_MAXSERV
、
Socket::NI_NOFQDN
、
Socket::NI_NUMERICHOST
、
Socket::NI_NAMEREQD
、
Socket::NI_NUMERICSERV
、
Socket::NI_DGRAM
が用意されている場合があります。
これらの定数の意味については getnameinfo(3)を参照 して下さい。
例:
Socket.getnameinfo(Socket.sockaddr_in('21','127.0.0.1')) #=> ["localhost", "ftp"] Socket.getnameinfo([nil, 21,'127.0.0.1']) #=> ["localhost", "ftp"]
Socket.gethostbyaddr(host[, type])
sockaddr 構造体をパックした文字列からホスト情報を返します。
ホスト情報の構造は Socket.gethostbynameと同じです。
type には、アドレスタイプ(デフォルトは
Socket::AF_INET
)を指定します。
Socket.gethostbyname(host)
ホスト名またはIPアドレス(指定方法に関しては ホスト指定形式を参照) からホストの情報を返します。ホスト情報は、ホスト名、ホス トの別名の配列、ホストのアドレスタイプ、ホストのアドレス を各要素とする配列です。
例: irb(main):009:0> Socket.gethostbyname ("210.251.121.214") ["helium.ruby-lang.org", ["helium"], 2, "\322\373y\326"]
Socket.gethostname
システムの標準のホスト名を取得します。
その他のホスト名などの情報は
Socket.gethostbyname(Socket.gethostname)
で取得できます。
Socket.getservbyname(service[, proto])
service, protoに対応するポート番号を返
します。protoの省略値は"tcp"
です。
Socket.sockaddr_in(port, host) ((<ruby 1.7 feature>))
Socket.pack_sockaddr_in(port, host) ((<ruby 1.7 feature>))
指定したアドレスをソケットアドレス構造体に pack して文字列で返しま す。port は、ポート番号を表す Fixnum あるいは、ポート 番号、サービス名を表す文字列です。
require 'socket' p Socket.pack_sockaddr_in("echo", "localhost") => "\002\000\000\a\177\000\000\001\000\000\000\000\000\000\000\000"
Socket.sockaddr_un(path) ((<ruby 1.7 feature>))
Socket.pack_sockaddr_un(path) ((<ruby 1.7 feature>))
指定したアドレスをソケットアドレス構造体に pack して文字列で返しま す。
require 'socket' p Socket.pack_sockaddr_un("/tmp/.X11-unix/X0") => "\001\000/tmp/.X11-unix/X0\000...."
Socket.pair(domain, type, protocol)
Socket.socketpair(domain, type, protocol)
相互に結合されたソケットのペアを含む2要素の配列を返します。
引数の指定はSocket.open
と同じです。
Socket.unpack_sockaddr_in(addr) ((<ruby 1.7 feature>))
pack されたソケットアドレス構造体addrを unpack してアドレス
を返します。返される値は [port, ipaddr]
の配列です。
require 'socket' p Socket.unpack_sockaddr_in(Socket.pack_sockaddr_in("echo", "localhost")) => [7, "127.0.0.1"]
Socket.unpack_sockaddr_un(addr) ((<ruby 1.7 feature>))
pack されたソケットアドレス構造体addrを unpack してソケット パス名をを返します。
require 'socket' p Socket.unpack_sockaddr_un(Socket.pack_sockaddr_un("/tmp/.X11-unix/X0")) => "/tmp/.X11-unix/X0"
accept
新しい接続を受け付けて、新しい接続に対するソケットとアドレスの
ペアを返します。accept(2)
を参照。
bind(addr)
ソケットをaddrに結合します。bind(2)
と同じ働きをします。addrはpackされたソケットアド
レス構造体です。
connect(addr)
connect(2)
と同じ働きをします。addrは
packされたソケットアドレス構造体です。
listen(backlog)
listen(2)
と同じ働きをします。
recvfrom(len[, flags])
recv
と同様にソケットからデータを受け取りますが、
戻り値は文字列と相手ソケットのアドレスのペアです。引数につい
てはrecvと同様です。
ソケット操作の指定のための定数を定義したモジュール。このモジュー ルをインクルードすれば、定数(AF_INETなど)を直接参照できます。
これらの定数はSocketの定数としても定義されています。
AF_INET
AF_UNSPEC
AF_INET6
AF_UNIX
AF_AX25
AF_IPX
AF_APPLETALK
SOCK_STREAM
SOCK_DGRAM
SOCK_RAW
SOCK_RDM
SOCK_SEQPACKET
SOCK_PACKET
IPPROTO_IP
IPPROTO_ICMP
IPPROTO_TCP
IPPROTO_UDP
IPPROTO_RAW
IPPROTO_IGMP
IPPROTO_GGP
IPPROTO_EGP
IPPROTO_PUP
IPPROTO_IDP
IPPROTO_HELLO
IPPROTO_ND
IPPROTO_TP
IPPROTO_XTP
IPPROTO_EON
IPPROTO_BIP
IPPROTO_MAX
AI_PASSIVE
AI_CANONNAME
AI_NUMERICHOST
Socket.getaddrinfo の flags
Mix-inにより再入可能なreader/writerロック機能を提供する。
includeしたクラスではinitializeでsuperを呼び出しておく必要がある。 (ruby 1.7 feature)
ロックされていない状態。
排他ロック。 オブジェクトの状態を更新する場合のように、 1つのスレッドがオブジェクトを独占的に使用したい場合に用いる。 排他ロック中に他のスレッドはオブジェクトを共有/排他ロックできない。
共有ロック。 複数のスレッドが同時にオブジェクトを使用できる場合に用いる。 複数のスレッドが共有ロックしている場合、 どのスレッドもオブジェクトを排他ロックできない。
Sync_m#sync_mode
現在のロック状態を返す。
Sync_m#sync_locked?
Sync_m#locked?
ロックされているかどうかを返す。
Sync_m#sync_shared?
Sync_m#shared?
共有ロックされているかどうかを返す。
Sync_m#sync_exclusive?
Sync_m#exclusive?
排他ロックされているかどうかを返す。
Sync_m#sync_try_lock(mode = EX)
Sync_m#try_lock(mode = EX)
ロック状態を変更する。 変更できたかどうかをtrueかfalseで返し、ブロックしない。
Sync_m#sync_lock(mode = EX)
Sync_m#lock(mode = EX)
ロック状態を変更する。 変更できるまで現在のスレッドの実行をブロックする。
Sync_m#sync_unlock(mode = EX)
Sync_m#unlock(mode = EX)
ロックを解除する。
Sync_m#sync_synchronize(mode = EX) {...}
Sync_m#synchronize(mode = EX) {...}
ロック状態を変更してブロックを実行する。
Sync_mの別名
Sync_mをinclude
したクラスでSynchronizerの別名。
使い方はSync_mを参照してください。
Sync_mをinclude
したクラスSync の別名。
使い方はSync_mを参照してください。
1.6.6以降に標準添付されています。
UNIXのsyslogのラッパークラスです。 執筆者募集
与えられた引数でsyslogを開いて、Syslog
の唯一の
インスタンスを返す。
ブロック付きで呼ばれた場合は、インスタンスを引数として
ブロックを呼び出す。
syslogを既に開いていた場合はRuntimeErrorが
発生する。
ident
はすべてのログにつく識別子で、どのプログラムから
送られたログなのかを識別するために使われる。
options
と facility
については
Syslog::Constants を参照。
例: sl = Syslog.open('ftpd', Syslog::LOG_PID | Syslog::LOG_NDELAY, Syslog::LOG_FTP)
Syslog
の唯一のインスタンスを返す。
(Singleton参照。)
1つの優先度に対するマスクを作成する。
priority
までのすべての優先度のマスクを作成する。
与えられた引数でsyslogを開く。 syslogを既に開いていた場合はRuntimeErrorが 発生する。
最初にcloseしてからopenと同様に開く。
syslogを既に開いていればtrue
を、
開いていなければfalse
を返す。
最後のopenで与えられた対応する引数を返す。
syslogにメッセージを書き込む。 format以降はsprintfと同じです。
例: sl.log(Syslog::LOG_CRIT, "the sky is falling in %d seconds!", 10)
Syslog#log()
のショートカットメソッドです。
システムによっては定義されていないものもあります。
例: sl.crit("the sky is falling in %d seconds!",5)
ログの優先度のマスクを取得または設定する。
マスクは永続的であり、
Syslog::open
/Syslog#open
/Syslog#close
ではリセットされない。
例: sl.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR)
syslogを閉じる。
inspect参照。
このモジュールにはシステムで使用可能なLOG_*定数が定義されている。
例: require 'syslog' include Syslog::Constants
--> Tempfile
テンプラリファイルを操作するためのクラスです。
Tempfile.new(basename[, tempdir])
Tempfile.open(basename[, tempdir])
"basenamepid.n" というファイル名で テンポラリファイルを作成します。
テンポラリファイルは、ディレクトリ tempdir に作成されます。 このデフォルト値は、
ENV['TMPDIR'] || ENV['TMP'] || ENV['TEMP'] || '/tmp'
です。
Tempfile#close([real])
テンポラリファイルをクローズします。
realが偽でなければ、テンポラリファイルはすぐに削除されます。
そうでなければ、GC によって削除されます。realのデフォルト値は
false
です。
Tempfile#open
クローズしたテンポラリファイルを再オープンします。 "r+" でオープンされるので、クローズ前の内容を再度読む ことができます。
Tempfile#path
テンポラリファイルのパス名を返します。
Threadを拡張するライブラリです。rubyインタプリタを デバッグオプション付き($DEBUGを真)で実行したときには、 Thread.abort_on_exceptionをtrueにします*109。
以下のクラスが定義されています。
また、Threadクラスに以下のクラスメソッドを追加定義します。
Thread.exclusive { ... }
ブロック実行中、Threadの切り替えを行いません。
スレッドの同期機構の一つである状態変数を実現するクラス。 ConditionVariable オブジェクトはスレッドが待ち合わせを行う条 件をオブジェクト化したものです。
mutex = Mutex.new cv = ConditionVariable.new Thread.start { mutex.synchronize { ... while (条件が満たされない) cv.wait(m) end ... } }
あるスレッドで上のように条件が満たされるまで wait メソッドで スレッドを止めて、他のスレッドで
Thread.start { mutex.synchronize { # 上の条件を満たすための操作 cv.signal } }
として、signal メソッドで wait を実行しているスレッドに対し て条件が成立したことを通知するのが典型的な使用例です。
以下は 「Pthread プログラミング」にあった ConditionVariable の例をRuby で書いてみた。なぜか最後にデッドロックする。 *113
require 'thread' count_lock = Mutex.new count_hit_threshold = ConditionVariable.new count = 0 COUNT_THRESHOLD = 10 inc_count = proc { loop { count_lock.synchronize { count += 1 p [Thread.current, count] if count >= COUNT_THRESHOLD count_hit_threshold.signal Thread.exit end } } } ths = [] ths << Thread.new(&inc_count) ths << Thread.new(&inc_count) ths << Thread.new { loop { count_lock.synchronize { if count > 0 count -= 1 end p [Thread.current, count] } } } ths << Thread.new { cond_lock.synchronize { while (count < COUNT_THRESHOLD) count_hit_threshold.wait(count_lock) p [Thread.current, count, 'wait'] end } } ths.each {|t| t.join }
状態変数を生成して返します。
状態変数を待っているスレッドをすべて再開します。再開された スレッドは ConditionVariable#wait で指定した mutex のロックを試みます。
実行待ちしていたスレッドの配列を返します。
状態変数を待っているスレッドを1つ再開します。再開された スレッドは ConditionVariable#wait で指定した mutex のロックを試みます。
状態を待っているスレッドがあった場合は、そのスレッドを返します。
そうでなければ nil
を返します。
mutex のロックを開放し、カレントスレッドを停止します。 ConditionVariable#signalまたは、 ConditionVariable#broadcastで送られたシグナルを 受け取ると、mutexのロックを取得し、実行状態となります。
self
を返します。
Mutex(Mutal Exclusion = 相互排他ロック)は共有データを並行アクセスから保護する
ためにあります。Mutex の典型的な使い方は(mを
Mutex
オブジェクトとします):
m.lock begin # mによって保護されたクリティカルセクション ensure m.unlock end
または、より簡単に
m.synchronize { # mによって保護されたクリティカルセクション }
Mutex.new
新しい mutex を生成して返します。
exclusive_unlock { ... }
ロックを開放し、ロック待ちになっているスレッドを実行可能状態に した後、ブロックを実行します。
ブロックの実行が終了するまで、スレッドは切り替わりません。
self
がロックされていなければ nil
を返します。そうでな
ければself
を返します。
lock
mutex オブジェクトをロックします。一度に一つのス レッドだけが mutex をロックできます。既にロックされている mutex に対してロックを行おうとしたスレッドは mutex のロックが開放さ れるまで、実行が停止されます。
self
を返します。
locked?
mutex がロックされている時、真を返します。
synchronize { ... }
mutex をロックし、ブロックを実行します。実行後に必ず mutex のロッ クを開放します。
try_lock
mutex をロックしようとして、ロックが成功した場合、真を返しま す。ロックできなかった場合にはブロックせず偽を返します。
unlock
mutex のロックを開放します。mutex のロック待ちになっていたスレッ ドの実行は再開されます。
self
がロックされていなければ nil
を返します。そうでな
ければself
を返します。
Queueはスレッド間のFIFO(first in first out)の通信路です。ス レッドが空のqueueを読み出そうとすると停止します。queueになんら かの情報が書き込まれると実行は再開されます。
Queue.new
新しいqueueオブジェクトを生成します。
clear
queue を空にします。
empty?
queueが空の時、真を返します。
length
size
queueの長さを返します。
num_waiting
queue を待っているスレッドの数を返します。
pop([non_block])
shift([non_block])
deq([non_block])
queueからひとつ値を取り出します。queueが空の時、呼出元のスレッ ドは停止します。省略可能な引数non_blockが真であれば、 queueが空の時に例外 ThreadError が発生します。
push(value)
self << value
enq(value)
queueの値を追加します。待っているスレッドがいれば実行を再開 させます。
provides synchronization for multiple threads.
ThreadsWait.all_waits(thread1,...)
waits until all of specified threads are terminated. if a block is supplied for the method, evaluates it for each thread termination.
require 'thwait' threads = [] 5.times {|i| threads << Thread.new { sleep 1; p Thread.current } } ThreadsWait.all_waits(*threads) {|th| p th } => #<Thread:0x401a0ca8 run> #<Thread:0x401a0d70 run> #<Thread:0x401a1130 run> #<Thread:0x401a13ec run> #<Thread:0x401a17d4 run> #<Thread:0x401a0ca8 dead> #<Thread:0x401a0d70 dead> #<Thread:0x401a1130 dead> #<Thread:0x401a13ec dead> #<Thread:0x401a17d4 dead>
ThreadsWait.new(thread1,...)
creates synchronization object, specifying thread(s) to wait.
ThreadsWait#threads
list threads to be synchronized
ThreadsWait#empty?
is there any thread to be synchronized.
ThreadsWait#finished?
is there already terminated thread.
ThreadsWait#join(thread1,...)
wait for specified thread(s).
ThreadsWait#join_nowait(threa1,...)
specifies thread(s) to wait. non-blocking.
ThreadsWait#next_wait
waits until any of specified threads is terminated.
ThreadsWait#all_waits
waits until all of specified threads are terminated. if a block is supplied for the method, evaluates it for each thread termination.
ThreadsWait の別名
Timeクラスを拡張して日時を表す文字列とTimeオブジェクトとの変換を行います。
ruby-src:ruby/lib/time.rb参照 執筆者募集
Time.parse(date, now=Time.now)
Time.parse(date, now=Time.now) {|year| year}
dateをParseDate.parsedateによって パースしてTimeオブジェクトに変換します。
ブロック付きで呼ばれた場合、dateの年はブロックによって変換されます。
例:
Time.parse(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}
与えられた時刻に上位の要素がなかったり壊れていた場合、nowの 該当要素が使われます。 下位の要素がなかったり壊れていた場合、最小値(1か0)が使われます。
例:
# 現在時刻が "Thu Nov 29 14:33:20 GMT 2001" で # タイムゾーンがGMTとすると: Time.parse("16:30") #=> Thu Nov 29 16:30:00 GMT 2001 Time.parse("7/23") #=> Mon Jul 23 00:00:00 GMT 2001 Time.parse("2002/1") #=> Tue Jan 01 00:00:00 GMT 2002
ParseDateがdateから情報を取り出せないとき、または Timeクラスが指定された日時を表現できないときにArgumentErrorが 発生します。
このメソッドは他のパース用メソッドのフェイルセーフとして以下のように使用できます:
Time.rfc2822(date) rescue Time.parse(date) Time.httpdate(date) rescue Time.parse(date) Time.xmlschema(date) rescue Time.parse(date)
従ってTime.parseの失敗はチェックすべきです。
Time.rfc2822(date)
Time.rfc822(date)
RFC:2822で定義されているdate-timeとしてdateをパースして Timeオブジェクトに変換します。 この形式はRFC:822で定義されてRFC:1123で更新された形式と 同じです。
dateがRFC:2822に準拠していない、または Timeクラスが指定された日時を表現できないときにArgumentErrorが 発生します。
Time.httpdate(date)
RFC:2616で定義されているHTTP-dateとしてdateをパースして Timeオブジェクトに変換します。
dateがRFC:2616に準拠していない、または Timeクラスが指定された日時を表現できないときにArgumentErrorが 発生します。
Time.xmlschema(date)
Time.iso8601(date)
XML Schema で定義されているdateTimeとしてdateをパースして Timeオブジェクトに変換します。
dateがISO 8601で定義されている形式に準拠していない、または Timeクラスが指定された日時を表現できないときにArgumentErrorが 発生します。
Time#rfc2822
Time#rfc822
RFC:2822で定義されているdate-timeとして表現される以下の形式の文字列を返します:
day-of-week, DD month-name CCYY hh:mm:ss zone
ただし zoneは [+-]hhmm です。
selfがUTC timeの場合、zoneは +0000 になります。
Time#httpdate
RFC:2616で定義されているHTTP-dateのrfc1123-dateとして 表現される以下の形式の文字列を返します:
day-of-week, DD month-name CCYY hh:mm:ss GMT
注意: 結果はいつも UTC (GMT) です。
Time#xmlschema([fractional_seconds])
Time#iso8601([fractional_seconds])
XML Schemaで定義されているとdateTimeして 表現される以下の形式の文字列を返します:
CCYY-MM-DDThh:mm:ssTZD CCYY-MM-DDThh:mm:ss.sssTZD
ただし TZD は Z または [+-]hh:mm です。
If self is a UTC time, Z is used as TZD. [+-]hh:mm is used otherwise.
fractional_secondsは小数点以下の秒を指定します。 fractional_secondsのデフォルト値は0です。
タイムアウトを行うライブラリ。
timeout(sec) {|i| .... }
timeout(sec, exception_class) {|i| .... } ((<ruby 1.7 feature>))
ブロックを sec 秒の期限付きで実行します。 ブロックの実行時間が制限を過ぎたときは例外 TimeoutError が発生します。 exception_class を指定した場合には TimeoutError の代わりに その例外が発生します。
また sec が nil
のときは制限時間なしで
ブロックを実行します。
timeout による割り込みは Thread によって実現されています。C 言語 レベルで実装され、Ruby のスレッドが割り込めない処理*115に対して timeout は無力です。その処理を Ruby で実装しなおすか C 側で Ruby のスレッドを意識してあげる必要があります。 timeoutの落し穴も参照
timeout.rb で定義される例外クラスです。関数 timeout
がタイ
ムアウトすると発生します。
ライブラリで timeout.rb を使う場合は、ユーザが指定した timeout を捕捉しないように、ライブラリ内ではTimeoutError のサブクラスを定義して 使用した方が無難です。
==> foo.rb <== require 'timeout.rb' class Foo FooTimeoutError = Class.new(TimeoutError) def longlongtime_method timeout(100, FooTimeoutError) { ... } end end ==> main.rb <== require 'foo' timeout(5) { Foo.new.longlongtime_method }
--> tracer.rb
WeakRefクラスによりweak referenceを実現する。
WeakRefオブジェクトは与えられたオブジェクトをポイントするが、 ポイント先のオブジェクトはGCされる可能性がある。 アクセスしようとしたときにオブジェクトがGCされていれば WeakRef::RefErrorが発生する。
require 'weakref' foo = Object.new ref = WeakRef::new(foo) ref.some_method_of_foo
weak referenceを提供するクラス。
WeakRef.new(obj)
objへのweak referenceを生成する
WeakRef#weakref_alive?
参照先のオブジェクトがまだ生きていればtrueを返す
GCされたオブジェクトを参照しようとしたときに発生する例外。
--> Delegator
--> Win32API
Win32 API をコールするためのクラスです。
Win32API.new(dllname, proc, import, export)
DLL dllname をロードし、API関数 proc のオブジェクトを 生成します。import には proc の引数の型のリストを、 export には proc の戻り値の型を指定します。
型の指定は以下の文字列または配列です。
"p"
ポインタ"n"
, "l"
long *117"i"
int"v"
voidimport が nil
の場合は引数なしと見なされます。また、
export が nil
の場合は戻り値なし(void
)と見なさ
れます。
Win32API#call([args ...])
Win32API#Call([args ...])
API関数 をコールします。指定する引数と戻り値は new
の引数の
指定に従います。特にポインタを渡してそのポインタの指す領域に値が
設定される場合はその領域をあらかじめ確保しておく必要があります。
例えば、文字列が返る関数をコールする場合は以下のようにします。
obj = Win32API.new 'dllname.dll', 'foo', 'p', 'v' arg = "\0" * 256 obj.call(arg)
ポインタの配列を渡す場合は以下のようにします。*118
obj = Win32API.new 'dllname.dll', 'foo', 'p', 'v' args = ["\0" * 256, "\0" * 256, "\0" * 256,] obj.call(args.pack("p3"))
Cygwin の uname コマンドの代わり
require 'Win32API' module Cygwin def uname uname = Win32API.new 'cygwin1', 'uname', ['P'], 'I' utsname = ' ' * 100 raise 'cannot get system name' if uname.call(utsname) == -1 utsname.unpack('A20' * 5) end module_function :uname end p Cygwin.uname => ["CYGWIN_98-4.10", "hoge", "1.1.7(0.31/3/2)", "2000-12-25 12:39", "i586"]
Cygwin の cygpath コマンドの代わり
require 'Win32API' module Cygwin @conv_to_full_posix_path = Win32API.new('cygwin1.dll', 'cygwin_conv_to_full_posix_path', 'PP', 'I') @conv_to_posix_path = Win32API.new('cygwin1.dll', 'cygwin_conv_to_posix_path', 'PP', 'I') @conv_to_full_win32_path = Win32API.new('cygwin1.dll', 'cygwin_conv_to_full_win32_path', 'PP', 'I') @conv_to_win32_path = Win32API.new('cygwin1.dll', 'cygwin_conv_to_win32_path', 'PP', 'I') def cygpath(options, path) absolute = shortname = false func = nil options.delete(" \t-").each_byte {|opt| case opt when ?u func = [@conv_to_full_posix_path, @conv_to_posix_path] when ?w func = [@conv_to_full_win32_path, @conv_to_win32_path] when ?a absolute = true when ?s shortname = true end } raise ArgumentError "first argument must contain -u or -w" if func.nil? func = absolute ? func[0] : func[1] buf = "\0" * 300 if func.Call(path, buf) == -1 raise "cannot convert path name" end buf.delete!("\0") buf end module_function :cygpath end p Cygwin.cygpath("-u", 'c:\\') p Cygwin.cygpath("-w", '/cygdrive/c') p Cygwin.cygpath("-wa", '.') => "/cygdrive/c" "c:\\" "d:\\home\\arai"
ruby version 1.6 は安定版です。この版での変更はバグ修正がメイン になります。
stable-snapshot は、日々更新される安定版の最新ソースです。
ruby-talk:35122
class C class << self def test @@cv = 5 p @@cv end end test end => -:5:in `test': uninitialized class variable @@cv in C (NameError) from -:9 ruby 1.6.7 (2002-03-01) [i586-linux] => ruby 1.6.6 (2001-12-26) [i586-linux] 5
Marshal.load が 1.7 のメソッド Proc#yield を呼んでいました。 ruby-dev:16178
Marshal.load(Marshal.dump('foo'), proc {|o| p o}) => -:1:in `load': undefined method `yield' for #<Proc:0x401b1b30> (NameError) from -:1 ruby 1.6.7 (2002-03-01) [i586-linux] => ruby 1.6.6 (2001-12-26) [i586-linux] "foo"
追加されました。
バグ修正、機能追加 ruby-dev:16139,ruby-dev:16153。
`_' を置ける場所の規則が見直され、String#hex などの数値変換メソッド の挙動と共に規則が統一されました。rubyist:1018, ruby-dev:15684, ruby-dev:15757
モジュールが再帰的に include されないようになりました。
module Foo; end module Bar; include Foo; end module Foo; include Bar; end p Foo.ancestors => ruby 1.6.6 (2001-12-26) [i586-linux] [Foo, Bar, Foo] => -:3:in `append_features': cyclic include detected (ArgumentError) from -:3:in `include' from -:3 ruby 1.6.6 (2002-01-28) [i586-linux]
以下のメソッドの戻り値が正しくなりました。 ruby-bugs-ja:PR#182, rubyist:1016
C 関数 rb_define_module_under() でモジュールを定義するときに同名の定 数が既に定義されていると失敗していました。ruby-talk:30203
Constants = 1 require 'syslog' p Syslog::Constants => -:2:in `require': Syslog::Fixnum is not a module (TypeError) from -:2 ruby 1.6.6 (2001-12-26) [i586-linux] => ruby 1.6.6 (2002-01-07) [i586-linux] Syslog::Constants
このバグにより 1.6.7 が近いうちにリリースされるかもしれません ruby-talk:30387(やっぱそんなことはなかったようです。 これを見て、1.6.6 の stable-snapshot を使用している方は、2002/1/30 の以下の変更(ChangeLog)
で、メモリリークが起こるようになってることに注意してください。 2002/2/13 以降の修正版で直ってます。っと一度ハマッたので書いておきま す)。
追加されました。
Netscape(バージョンは?) のバグに対処しました ruby-list:32089
フリーズした Time オブジェクトに対して一度だけ呼び出しを許しました。
t = Time.new.freeze p t.gmtime p t.localtime => -:2:in `gmtime': can't modify frozen Time (TypeError) from -:2 ruby 1.6.5 (2001-09-19) [i586-linux] => ruby 1.6.5 (2001-11-01) [i586-linux] Mon Nov 05 18:08:34 UTC 2001 -:3:in `localtime': can't modify frozen Time (TypeError) from -:3
これらは、freeze された文字列になりました。
p File::SEPARATOR.frozen? p File::ALT_SEPARATOR.frozen? p File::PATH_SEPARATOR.frozen? => ruby 1.6.5 (2001-09-19) [i586-linux] false false false => ruby 1.6.5 (2001-11-01) [i586-linux] true false # ここでは実行環境がLinuxなので ALT_SEPARATOR は nil true
大きな値のインデックスに対して例外が発生していました。 ruby-bugs-ja:PR#114
p(-1[10000000000]) => -:1:in `[]': bignum too big to convert into `int' (RangeError) from -:1 ruby 1.6.5 (2001-09-19) [i586-linux] => ruby 1.6.5 (2001-11-01) [i586-linux] 1
整数の負のインデックスに対して 0 を返すようにな・・・ってません。あれ? ruby-bugs-ja:PR#122
p(-1[-1]) => ruby 1.6.5 (2001-09-19) [i586-linux] 1 => ruby 1.6.5 (2001-11-01) [i586-linux] 1
ruby-bugs-ja:PR#110
p( 3.remainder(-3)) p(-3.remainder(3)) => ruby 1.6.5 (2001-09-19) [i586-linux] 3 -3 => ruby 1.6.5 (2001-11-01) [i586-linux] 0 0
END ブロックの中の END ブロックが実行されていませんでした。 ruby-bugs-ja:PR#107
END { p 1 END { p 2 } } => ruby 1.6.5 (2001-09-19) [i586-linux] 1 => ruby 1.6.5 (2001-11-01) [i586-linux] 1 2
ruby-talk:22557
p "***".succ p "*".succ p sprintf("%c", 255).succ p sprintf("*%c", 255).succ p sprintf("**%c", 255).succ => ruby 1.6.5 (2001-09-19) [i586-linux] "**+" "\001+" "\001\000" "\001+\000" "*+\000" => ruby 1.6.5 (2001-11-01) [i586-linux] "**+" "+" "\001\000" "+\000" "*+\000"
以下が Segmentation Fault していました。ruby-dev:14942
Module::constants.each {|c| c = eval c if c.instance_of?(Class) p c c.instance_methods.each {|m| c.module_eval "undef #{m};" } c.module_eval {undef initialize} end } => ruby 1.6.5 (2001-09-19) [i586-linux] NotImplementedError MatchData Exception Numeric MatchData Segmentation fault => ruby 1.6.5 (2001-10-15) [i586-linux] MatchData NotImplementedError FloatDomainError LoadError Float Binding SignalException Module -:6:in `method_missing': stack level too deep (SystemStackError)
% 記法によるリテラル表記でその区切り文字として英数字を指定 できなくなりました。
p %q1..1
=> ruby 1.6.5 (2001-10-10) [i586-linux] ".." => -:1: unknown type of %string p %q1..1 ^ ruby 1.6.5 (2001-10-15) [i586-linux]
String#=~ の呼出で両辺ともリテラルであったときに速度重視のためにメソッ ドコールを行わなくなりました。(実際は、前からこのようにしようとして いたがバグによりメソッドが呼び出されていた(しかもString#=~ でなく Regexp#=~))
class String def =~(arg) ["String#=~", self, arg] end end class Regexp def =~(arg) ["Regexp#=~", self, arg] end end p "foo" =~ /foo/ p "foo" =~ Regexp.new("foo") => -:2: warning: discarding old =~ -:8: warning: discarding old =~ ruby 1.6.5 (2001-09-19) [i586-linux] ["Regexp#=~", /foo/, "foo"] ["String#=~", "foo", /foo/] => -:2: warning: discarding old =~ -:8: warning: discarding old =~ ruby 1.6.5 (2001-10-10) [i586-linux] 0 ["String#=~", "foo", /foo/]
(組込みのメソッドはこのような最適化が行われることがあるのでメソッ ドの再定義の効果が及ばないことがある点に注意というか、メソッドが 再定義されたかどうかで、最適化の on/off をしてほしいなあ)
既にクラスが定義されていて、そのクラスと異なるスーパークラスを明示的 に指定して再定義したとき、指定したスーパークラスが反映されていません でした。ruby-bugs-ja:PR#87
class A p self.id end class A < String p self.id p self.superclass end => ruby 1.6.5 (2001-09-19) [i586-linux] 537760880 -:4: warning: already initialized constant A 537757180 Object => ruby 1.6.5 (2001-10-10) [i586-linux] 537760960 -:4: warning: already initialized constant A 537757200 String
配列リテラル %w(...) が構文解析器により文字列リテラルとして判断されて いたため、以下のようなコードで異常な状態になっていました。 ruby-bugs-ja:PR#91
%w!a! "b" => -:1: tried to allocate too big memory (NoMemoryError) ruby 1.6.5 (2001-09-19) [i586-linux] => -:1: parse error %w!a! "b" ^ ruby 1.6.5 (2001-10-10) [i586-linux]
Thread#status が aborting 状態に対して "run" を返していたバグが修正 されました。また、Thread#priority = val が val でなく self を返して いました。rubyist:0820, ruby-dev:14903
UNIXSocket#addr がゴミを返していました(BSD の場合?)。 ruby-bugs-ja:PR#85
# server require 'socket' File.unlink("/tmp/sss") sock = UNIXServer.new("/tmp/sss").accept # client require 'socket' sock = UNIXSocket.new("/tmp/sss").addr => ["AF_UNIX", "\031((\306\031(\010"] => ["AF_UNIX", ""]
ruby-talk:21722
class Ptr
def initialize(obj) @obj = obj end def []=() @obj = obj end def []() @obj end
end module Kernel
def _ptr() Ptr.new(self) end
end
def foo(int)
int[] += 1
end x = 1._ptr foo(x) puts x[]
=> -:11: [BUG] Segmentation fault
ruby 1.6.5 (2001-09-19) [i586-linux]
=> -:11:in `[]=': wrong # of arguments(1 for 0) (ArgumentError)
from -:11:in `foo' from -:14
ruby 1.6.5 (2001-10-05) [i586-linux]
String, Array のサブクラスで特定のメソッドを呼ぶと、String, Array になっていました。
class Foo < String end p Foo.new("").type p Foo.new("foo")[0,0].type # String ??? p Foo.new("foo")[1,1].type p Foo.new("foo").succ.type p Foo.new("foo").reverse.type p((Foo.new("foo") * 5).type) p Foo.new("foo").gsub(/foo/, "bar").type p Foo.new("foo").sub(/foo/, "bar").type p Foo.new("foo").ljust(10).type p Foo.new("foo").rjust(10).type p Foo.new("foo").center(10).type => ruby 1.6.5 (2001-09-19) [i586-linux] Foo String String String String String String Foo String String String => ruby 1.6.5 (2001-10-05) [i586-linux] Foo String Foo Foo Foo Foo Foo Foo Foo Foo Foo class Bar < Array end bar = Bar.new p bar.type p bar.push(1,2,3) p bar.type p bar[0,0].type # => Array ??? p bar[0,1].type p ((bar * 5).type) => -:9: warning: p (...) interpreted as method call ruby 1.6.5 (2001-09-19) [i586-linux] Bar [1, 2, 3] Bar Array Array Array => -:9: warning: p (...) interpreted as method call ruby 1.6.5 (2001-10-05) [i586-linux] Bar [1, 2, 3] Bar Array Bar Bar
関数の中からThread#runを使うと、そのスレッドとスコープを共有する親スレッ ドの$_, $~が、子スレッドのもので上書きされてしまっていました。 ruby-dev:14743
def foo(t) t.run end t = Thread.start do t = $_= "sub" loop{Thread.stop;puts "sub:#$_"} end $_ = "main" t.run # => sub:sub puts "main:#$_" # => main:main foo(t) # => sub:sub puts "main:#$_" # => main:sub => ruby 1.6.4 (2001-06-04) [i586-linux] sub:sub main:main sub:sub main:sub => ruby 1.6.5 (2001-09-19) [i586-linux] sub:sub main:main sub:sub main:main
Net::Telnet が特定のホストへ接続後、動かない事がありました。 ruby-list:31303
以下のようなスクリプトでTEXT_PLAINが"text/plain; charset=iso-8859-1" のように書き換えられていました。 ruby-dev:14716
require 'cgi' TEXT_PLAIN = "text/plain" cgi = CGI.new print cgi.header("type" => TEXT_PLAIN, "charset" => "iso-8859-1") printf("TEXT_PLAIN: %s\n", TEXT_PLAIN) => ruby 1.6.4 (2001-06-04) [i586-linux] Content-Type: text/plain; charset=iso-8859-1 ^M TEXT_PLAIN: text/plain; charset=iso-8859-1 TEXT_PLAIN: text/plain => ruby 1.6.5 (2001-09-19) [i586-linux] Content-Type: text/plain; charset=iso-8859-1 ^M TEXT_PLAIN: text/plain
環境変数 HOME, LOGDIR のいずれも定義されていないとき引数なしの Dir.chdir で ArgumentError 例外を起こすようになりました
ENV['HOME'] = nil ENV['LOGDIR'] = nil Dir.chdir => -:3:in `chdir': Bad address (Errno::EFAULT)
from -:3
ruby 1.6.4 (2001-08-26) [i586-linux]
=> -:3:in `chdir': HOME/LOGDIR not set (ArgumentError)
from -:3
ruby 1.6.5 (2001-09-19) [i586-linux]
以下のコードが無限ループになっていました。
Dir.mkdir("test?") rescue nil p Dir.glob("test?/*") => ruby 1.6.5 (2001-09-19) [i586-linux] []
バグがいくつか修正されました。ruby-list:31238
〜この間、空白期間〜
Dir.glob("*/**/*")がサブディレクトリのファイルを二度返していました。 ruby-dev:14576
Dir.mkdir('foo') rescue nil Dir.mkdir('foo/bar') rescue nil p Dir.glob('*/**/*') => ruby 1.6.4 (2001-06-04) [i586-linux] ["foo/bar", "foo/bar"] => ruby 1.6.4 (2001-08-26) [i586-linux] ["foo/bar"]
モジュールの UnboundMethod オブジェクトを bind することができませんでした。 rubyist:0728
module Foo def foo :foo end end class Bar include Foo end m = Foo.instance_method :foo p m.bind(Bar.new).call => ruby 1.6.4 (2001-06-04) [i586-linux] -:12:in `bind': first argument must be an instance of Foo (TypeError) from -:12 => ruby 1.6.4 (2001-08-23) [i586-linux] :foo
組込みクラス/モジュール(を代入した定数)への代入を行ったときに警告を 出すようになりました。
Array = nil p Array => ruby 1.6.4 (2001-06-04) [i586-linux] nil => -:1: warning: already initialized constant Array ruby 1.6.4 (2001-08-23) [i586-linux] nil
括弧の数より大きな数のバックリファレンスが何にでもマッチしていました。 ruby-list:30975
p /(foo)\2/ =~ "foobar" => ruby 1.6.4 (2001-06-04) [i586-linux] 0 => ruby 1.6.4 (2001-08-23) [i586-linux] nil
Cygwin で TCPSocket.open がタイミングによってエラー(Errno::EINVAL, EALREADY)になることがある問題に対処しました。(1.6.4 20010712以降) ruby-talk:9939, ruby-talk:16632, ruby-list:24702, ruby-list:27805, ruby-list:30512 等など
追加。rubyで実装したリゾルバ(DNSの名前解決) とSocket関連のクラスでこ のライブラリを使用するためのライブラリです。
rubyで実装したリゾルバは、timeout.rb の制御が効きます(つまり、名前解 決中にThreadが切替え可能ということです)
require 'resolv' p Resolv.new.getaddress("www.ruby-lang.org").to_s => /usr/local/lib/ruby/1.6/resolv.rb:160: warning: timeout (...) interpreted as method call /usr/local/lib/ruby/1.6/resolv.rb:55: warning: instance variable @initialized not initialized /usr/local/lib/ruby/1.6/resolv.rb:113: warning: instance variable @initialized not initialized /usr/local/lib/ruby/1.6/resolv.rb:392: warning: instance variable @initialized not initialized ruby 1.6.4 (2001-08-23) [i586-linux] "210.251.121.214"
SHA1, MD5 は Digest::SHA1, Digest::MD5 に置き換えられました。 Digest::SHA256, Digest::SHA384, Digest::SHA512, Digest::RMD160 も新たに追加されました。
require 'digest/md5' include Digest md = MD5.new md << "abc" puts md puts MD5.hexdigest("123")
フリーズされた構造体オブジェクトが変更できていました。また、$SAFE = 4 のときの変更を禁止するようにしました。ruby-talk:19167
cat = Struct.new("Cat", :name, :age, :life) a = cat.new("cat", 12, 7).freeze a.name = "dog" p a => ruby 1.6.4 (2001-06-04) [i586-linux] #<Struct::Cat name="dog", age=12, life=7> => ruby 1.6.4 (2001-08-06) [i586-linux] -:4:in `name=': can't modify frozen Struct (TypeError) from -:4 cat = Struct.new("Cat", :name, :age, :life) a = cat.new("cat", 12, 7) Thread.new do abort_on_exception = true $SAFE = 4 a.life -= 1 end.join p a.life => ruby 1.6.4 (2001-06-04) [i586-linux] 6 => ruby 1.6.4 (2001-08-06) [i586-linux] -:6:in `life=': Insecure: can't modify Struct (SecurityError) from -:3:in `join' from -:3
rindex に正規表現を渡したときの動作にバグがありました。ruby-dev:13843 (1.6.4 リリース後のバグです)
p "foobar".rindex(/b/) => ruby 1.6.4 (2001-06-04) [i586-linux] 3 => ruby 1.6.4 (2001-06-19) [i386-freebsd5.0] nil => ruby 1.6.4 (2001-08-06) [i586-linux] 3
requireに ~ で始まるファイル名を指定したとき、拡張子がついてな いとロードできなくなっていました。ruby-dev:13756
$ echo p __FILE__ > ~/a.rb $ ruby17 -v -r~/a -e0 ruby 1.7.1 (2001-07-03) [i686-linux] 0: No such file to load -- ~/a (LoadError) $ ruby16 -v -r~/a -e0 ruby 1.6.4 (2001-07-02) [i686-linux] 0: No such file to load -- ~/a (LoadError) $ ruby14 -v -r~/a -e0 ruby 1.4.6 (2000-08-16) [i686-linux] "/home/nobu/a.rb"
正しく汚染が伝搬していませんでした。ruby-dev:13755
"foo\nbar\n".taint.each_line {|v| p v.tainted?} => ruby 1.6.4 (2001-06-04) [i586-linux] false true => ruby 1.6.4 (2001-08-06) [i586-linux] true true
正しく汚染が伝搬していませんでした。ruby-dev:13754
require 'nkf' p NKF.nkf("-j", "a".taint).tainted? => ruby 1.6.4 (2001-06-04) [i586-linux] false => ruby 1.6.4 (2001-08-06) [i586-linux] true
オプション -x を指定したときにスクリ プトを実行せずに終了することがありました。ruby-dev:13752
アクセサに余計な引数を渡してもエラーになりませんでした。 ruby-dev:13748
class C def initialize @message = 'ok' end attr_reader :message end puts C.new.message(1,2,3) => ruby 1.6.4 (2001-06-04) [i586-linux] ok => ruby 1.6.4 (2001-08-06) [i586-linux] -:7:in `message': wrong # of arguments(3 for 0) (ArgumentError) from -:7
追加。GNU Readline ライブラリの変数 rl_completion_append_character
のアクセサ。(この変数は GNU readline 2.1 以降で使えます)
ruby-ext:01760
ソケット関連の定数のうち以下が新規に追加されました(システムに定義さ れている場合に限る)。
SO_PASSCRED SO_PEERCRED SO_RCVLOWAT SO_SNDLOWAT SO_RCVTIMEO SO_SNDTIMEO SO_SECURITY_AUTHENTICATION SO_SECURITY_ENCRYPTION_TRANSPORT SO_SECURITY_ENCRYPTION_NETWORK SO_BINDTODEVICE SO_ATTACH_FILTER SO_DETACH_FILTER SO_PEERNAME SO_TIMESTAMP
Changed to use a new algorithm to locate a library.
Now when requiring "foo", the following directories are searched for the library in the order listed.
$prefix/lib/ruby/site_ruby/$ver/foo.rb $prefix/lib/ruby/site_ruby/$ver/foo.so $prefix/lib/ruby/site_ruby/$ver/$arch/foo.rb $prefix/lib/ruby/site_ruby/$ver/$arch/foo.so $prefix/lib/ruby/site_ruby/foo.rb $prefix/lib/ruby/site_ruby/foo.so $prefix/lib/ruby/$ver/foo.rb $prefix/lib/ruby/$ver/foo.so $prefix/lib/ruby/$ver/$arch/foo.rb $prefix/lib/ruby/$ver/$arch/foo.so ./foo.rb ./foo.so
The previous behavior had a potential security risk because a foo.rb (if exists) in the current directory is located prior to a foo.so in $prefix/lib/ruby/site_ruby/$ver/$arch.
ruby-bugs:PR#140, ruby-ext:01778, ruby-dev:13659
Fixed for obj.extend(Sync_m) and obj.extend(Mutex_m).ruby-dev:13463
$ ruby -v -rsocket -rmutex_m -e 's=TCPSocket.new("localhost",25); s.extend(Mutex_m)' ruby 1.6.4 (2001-06-04) [i386-linux] /usr/lib/ruby/1.6/mutex_m.rb:104:in `initialize': wrong # of arguments (0 for 1) (ArgumentError) from /usr/lib/ruby/1.6/mutex_m.rb:104:in `initialize' from /usr/lib/ruby/1.6/mutex_m.rb:50:in `mu_extended' from /usr/lib/ruby/1.6/mutex_m.rb:34:in `extend_object' from -e:1:in `extend' from -e:1
1 <= $SAFE <= 3 で、第二引数が true のとき汚染されたファイル名を 指定しても load() できてしまうバグが修正されました。ruby-dev:13481
$SAFE = 1 filename = "foo" filename.taint p load(filename, true) => ruby 1.6.4 (2001-06-04) [i586-linux] true => ruby 1.6.4 (2001-08-06) [i586-linux] -:4:in `load': Insecure operation - load (SecurityError) from -:4
以下で、前者がマッチしませんでした。ruby-talk:16233
puts "OK 1" if /(.|a)bd/ =~ "cxbd" puts "OK 2" if /(a|.)bd/ =~ "cxbd" => ruby 1.6.4 (2001-06-04) [i586-linux] OK 2 => ruby 1.6.4 (2001-08-06) [i586-linux] OK 1 OK 2
doc/NEWS には
Fixed so defining a new method is allowed under $SAFE == 4, which previously wasn't.
とあるけど実際にはできません。
$SAFE = 4; def a; end => -:1: Insecure operation `(null)' at level 4 (SecurityError) ruby 1.6.4 (2001-06-04) [i586-linux] => -:1: Insecure: can't define method (SecurityError) ruby 1.6.4 (2001-08-06) [i586-linux]
対応するChangeLogは以下のようです。
Tue Jun 5 15:16:06 2001 Yukihiro Matsumoto <matz@ruby-lang.org> * eval.c (rb_add_method): should not call rb_secure(), for last_func may not be set.
差分は以下のようです。
@@ -227,10 +227,7 @@ rb_add_method(klass, mid, node, noex) NODE *body; if (NIL_P(klass)) klass = rb_cObject; - if (klass == rb_cObject) { - rb_secure(4); - } - if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) { + if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) { rb_raise(rb_eSecurityError, "Insecure: can't define method"); } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
また今度調べ直します。
第二引数に Bignum も受け付けるようになりました(long int の範囲をカバー するため)
ハッシュのイテレート中に、そのハッシュのある要素を削除して、 他のハッシュへreplaceするとAbortしていました。ruby-dev:13432
h = { 10 => 100, 20 => 200 } h2 = { } h.each { |k, v| if (k == 10) h.delete(10) h2.replace(h) # => Abort core dumped end }
File.unlink は引数が汚染されてなくても $SAFE >= 2 の環境下では 禁止するようになりました。ruby-dev:13426
touch foo ruby -v -e '$SAFE=2;File.unlink("foo")' => ruby 1.6.3 (2001-03-19) [i586-linux] => ruby 1.6.4 (2001-06-04) [i586-linux] -e:1:in `unlink': Insecure operation `unlink' at level 2 (SecurityError) from -e:1
凍結したオブジェクトに対してuntaintできないようにしました。ruby-dev:13409
a = Object.new a.taint a.freeze a.untaint => ruby 1.6.3 (2001-03-19) [i586-linux] => ruby 1.6.4 (2001-06-04) [i586-linux] -:4:in `untaint': can't modify frozen object (TypeError) from -:4
オプション -T4 を指定したとき、ARGV を 変更できないためプログラムの実行ができませんでした。 ruby-dev:13401
touch foo ruby-1.6.3 -v -T4 foo => ruby 1.6.3 (2001-03-19) [i586-linux] foo: Insecure: can't modify array (SecurityError)
正規表現中の \1 .. \9 は常にバックリファレンスとして解釈されるように なりました(以前は対応する括弧があればバックリファレンス、なければ8進 の文字コードとして解釈されていました)。
正規表現で8進文字コードを指定するには \001 のように3桁で指定します。
また、対応する括弧のないバックリファレンスや対応する括弧が自身を含む バックリファレンスは常にマッチに失敗するようになりました。
p /(foo)\2/ =~ "foo\002" => ruby 1.6.3 (2001-03-19) [i586-linux] 0 => ruby 1.6.4 (2001-06-04) [i586-linux] 0 => ruby 1.6.4 (2001-08-23) [i586-linux] nil
(上記の通り 1.6.4 にはまだバグがありました 2001-08-23 あたりで修正さ れています ruby-list:30975)
p /(foo\1)/ =~ "foo" => ruby 1.6.3 (2001-03-19) [i586-linux] 0 => ruby 1.6.4 (2001-06-04) [i586-linux] nil
以下は、すべて true を返すようになりました。ruby-dev:13340
# []= s1 = "abc" s2 = "cde".taint s1[0]= s2 p s1.tainted? # => false # crypt s = "abc".taint p s.crypt("cd").tainted? # => false # ljust s = "abc".taint p s.ljust(10).tainted? # => false # rjust s = "abc".taint p s.rjust(10).tainted? # => false # center s = "abc".taint p s.center(10).tainted? # => false
C API から yield されたとき 1 つの引数が 1 要素の配列として渡されていました。 ruby-dev:13299
class X include Enumerable def each(&block) block.call(1,2) block.call(2,3) block.call(3,4) end end x = X.new p x.to_a #=> [[1], [2], [3]] # => ruby 1.6.3 (2001-03-19) [i586-linux] [[1], [2], [3]] # => ruby 1.6.4 (2001-06-04) [i586-linux] [1, 2, 3]
$SAFE = 4 のときグローバル変数のエイリアスを許さないようにしました。 ruby-dev:13287
終了したプロセスが at_exit を呼ばないようにしました。 (exit を exit! に修正) ruby-dev:13170
以下のコードでデッドロックが起こらないようにしました。ruby-dev:13169
ruby -r thread -e 'q = SizedQueue.new(1); q.push(1);'\ -e 'Thread.new{sleep 1; q.pop}; q.push(1);'
maxが現在値より大きい時にその差の分だけ待ちスレッドを起こす処理 の判定に誤りがありました。ruby-dev:13170
Thread#run を呼ぶ直前にスレッドが死んでいた場合に ThreadError が発生する問題に対処しました。ruby-dev:13194
ruby-dev:13195
th1 = Thread.start { begin Thread.stop ensure Thread.pass Thread.stop end } sleep 1
(確認できる限りでは ruby-1.7.0 (2001-05-17) 以降で治ってますが、 1.6 には取り込まれていません)
結果の配列の要素が freeze され変更不可になっていました。ruby-list:29665
(%w(foo bar) & %w(foo baz))[0].upcase! => -:1:in `upcase!': can't modify frozen string (TypeError) %w(foo bar bar baz).uniq[0].upcase! => -:1:in `upcase!': can't modify frozen string (TypeError)
shell.rb 0.6 が標準ライブラリとして新規に追加されました。 (ドキュメントが doc ディレクトリにあります)
forwardable.rb 1.1 が標準ライブラリとして新規に追加されました。 (ドキュメントが doc ディレクトリにあります)
irb と irb-tools がそれぞれ 0.7.4 と 0.7.1 にバージョンアップしました。
夏時間の考慮に不備がありました(?) ruby-bugs-ja:PR#46
env TZ=America/Managua ruby -e 'p Time.local(1998,12,1,0,59,59)' => Mon Nov 30 01:59:59 EST 1998 env TZ=America/Managua ruby -e 'p Time.local(1998,12,1,0,59,59).tv_sec' => 912409199
4.4BSD のシグナル SIGINFO に対応しました。ruby-bugs-ja:PR#45
Thread.stop で SEGV することがありました。ruby-dev:13189
以下が 1.6.3 で parse error になっていたバグが修正されました。 ruby-dev:13073, ruby-dev:13292
raise "" rescue [] raise "" rescue (p "foo"; true) raise "" rescue -1 raise "" rescue (-1)
以下は dead lock にならなくなりました。
Thread.start { Thread.stop } sleep => deadlock 0x40199b58: 2:0 - -:1 deadlock 0x401a2528: 2:4 (main) - -:2 -:2:in `sleep': Thread: deadlock (fatal) from -:2 ruby 1.6.3 (2001-03-19) [i586-linux]
これらのメソッドが定数以外にアクセス可能になっていたバグが修正されました ruby-dev:13019
Float を dump するときの精度が "%.12g" から "%.16g" になりました。 ruby-list:29349
sizeof(long) > sizeof(int) なシステムでのバグが修正されたようです。
まれなバグが2件修正されました ruby-talk:13658, ruby-talk:13744
以下が 1.6.3 で正常に機能しませんでしたruby-talk:13957
def WHILE(cond) return if not cond yield retry end i=0 WHILE(i<3) { print i i+=1 } ruby 1.6.2 (2000-12-25) [i586-linux] => 012 ruby 1.6.3 (2001-03-19) [i586-linux] => 0 ruby 1.6.4 (2001-05-02) [i586-linux] => 012
1G byte 以上のファイルに対して正しくファイルサイズを返していませんでした。
File.open("/tmp/1GB", "w") {|f| f.seek(2**30-1, 0) f.puts f.flush p f.stat.size } # => ruby 1.6.3 (2001-04-03) [i586-linux] -1073741824 # => ruby 1.6.4 (2001-04-19) [i586-linux] 1073741824
なんか修正されたみたいです ruby-dev:12718
不正に例外を返す場合がありました。
stdio が内部で malloc() を呼び出す場合、Thread と相性が悪かったことに対 処しました。(setvbuf() を使用することで malloc() が呼ばれるのを避けた) ruby-dev:12795
File#flock がロック済みの場合に false を返さず Errno::EACCES 例外を あげる場合がありました(flock()がないシステムの場合)
追加 ruby-dev:12803
% の計算に誤りが出ることがあるバグが(再度)修正されました
a = 677330545177305025495135714080 b = 14269972710765292560 p a % b #=> 0 p -a % b #=> => ruby 1.6.3 (2001-04-02) [i386-cygwin] 0 14269972710765292560 => ruby 1.6.4 (2001-04-19) [i586-linux] 0 0
Bignum を dump -> load した結果が元の値と異なる場合がありました。
これに関連する修正が 1.6.3 リリース後、3回ほど行われています。 stable-snapshot の
ruby 1.6.3 (2001-03-22)
以降を使用してください。
UNC 形式のパス名 (//host/share) がサポートされました。
バックスラッシュ(`\
')ではなくスラッシュ(`/
')を使います。
(元もとサポートされてたのがバグ修正された??)
カレントディレクトリ(./)に対するglobが失敗していました。
p Dir["./*.c"] => []
結合強度の違いがなくなっていたバグが修正されました。
1.6.0 から 1.6.2 までのバージョンでは、
method v { .. } method v do .. end
の両者に違いがありませんでした。本来の挙動はイテレータ に書かれた通りです。
% の計算に誤りが出ることがあるバグが修正されました
ruby-1.6.2 -ve 'p 6800000000%4000000000' => ruby 1.6.2 (2000-12-25) [i586-linux] -1494967296 ruby-1.6.3 -ve 'p 6800000000%4000000000' => ruby 1.6.3 (2001-03-10) [i586-linux] 2800000000
通常のメソッド定義と同様に rescue, ensure 節の指定が可能になりました
obj = Object.new def obj.foo rescue ensure end
'\-' で '-' を指定可能になりました(tr! 等、bang method も同様)。 以前は、文字列の先頭または末尾の'-'だけを'-'と見なしていました。
p "-".tr("a-z", "+") # => "-" p "-".tr("-az", "+") # => "+" p "-".tr("az-", "+") # => "+" p "-".tr('a\-z', "+") # => "+" # シングルクォート文字列であることに注意 p "-".tr("a\\-z", "+") # => "+" # "" では二重に\が必要
すべてのオプションも同じならば同じと判断するようになりました。 以前は、漢字コード指定と /i (case-insensitive) の指定が同じで あれば同じと判断していました。
リテラルの終了文字(`)'など)をバックスラッシュエスケープ可能になりました。
"**/" がシンボリックリンクを辿らなくなりました。
"a"[1,2] が "" を返すようになりました。
p "a"[1,2] => ""
これは本来の挙動です。過去のバージョン(1.4.6など)もこの値を返していました。
1.6.0 以降 1.6.2 までは上記は nil
になります。
p "a"[2,1]
は、nil
を返します。
freeze したオブジェクトに対して taint
できなくなりました
obj = Object.new.freeze obj.taint => -:2:in `taint': can't modify frozen object (TypeError) from -:2
ruby version 1.7 は開発版です。以下にあげる機能は将来削除されたり互換 性のない仕様変更がなされるかもしれません。
refine. ruby-dev:16193, ruby-dev:16213
ruby-dev:16126
複数のモジュールを渡したときにインクルードされる順序が変更されました。 ruby-dev:16035 extend も同様だそうです。ruby-dev:16183
module Foo; end module Bar; end module Baz; end include Foo, Bar, Baz p Object.ancestors => ruby 1.6.7 (2002-03-01) [i586-linux] [Object, Baz, Bar, Foo, Kernel] => ruby 1.7.2 (2002-03-01) [i586-linux] [Object, Foo, Bar, Baz, Kernel]
一つ一つ include した場合とは逆順になります。
module Foo; end module Bar; end module Baz; end include Foo include Bar include Baz p Object.ancestors => ruby 1.7.2 (2002-03-01) [i586-linux] [Object, Baz, Bar, Foo, Kernel]
追加
ruby-bugs-ja:PR#98
pack/unpack のテンプレートにコメントを記述できるようになりました。
p [1,2,3,4].pack("s # short (fixed 2 bytes) i # int (machine dependent) l # long (fixed 4 bytes) q # quad (fixed 8 bytes)") => ruby 1.7.2 (2002-02-21) [i586-linux] "\001\000\002\000\000\000\003\000\000\000\004\000\000\000\000\000\000\000"
これら疑似変数に特異メソッドが定義できるようになりました。
class <<true def foo "foo" end end p true.foo => -:1: no virtual class for true (TypeError) ruby 1.6.6 (2001-12-26) [i586-linux] => ruby 1.7.2 (2002-02-20) [i586-linux] "foo"
追加
def foo proc { return 10 } end begin foo.call rescue LocalJumpError p $!.exitstatus end => ruby 1.7.2 (2002-02-14) [i586-linux] 10
追加。Socket#listenと同じ。
追加
継承関係のないクラス/モジュール同士の比較で例外があがるようになりま した。
p Array <=> String => ruby 1.6.6 (2001-12-26) [i586-linux] 1 => -:1:in `<=>': non related class/module (ArgumentError) from -:1 ruby 1.7.2 (2002-02-14) [i586-linux]
追加
64 bit 整数のテンプレート文字 Q/q が追加されました(Quad の意)。 Q は unsigned、q は、signed です。 perl と異なり 64 bit 整数をサポートしないプラットフォームでも 使用できます。
p [ 1].pack("Q") p [-1].pack("Q") p [ 1].pack("q") p [-1].pack("q") p [ 1].pack("Q").unpack("Q") p [-1].pack("Q").unpack("Q") p [ 1].pack("q").unpack("q") p [-1].pack("q").unpack("q") => ruby 1.7.2 (2002-02-13) [i586-linux] "\001\000\000\000\000\000\000\000" "\377\377\377\377\377\377\377\377" "\001\000\000\000\000\000\000\000" "\377\377\377\377\377\377\377\377" [1] [18446744073709551615] [1] [-1]
特異メソッドに対する出力形式がより意味のあるものになりました。 ruby-bugs-ja:PR#193
obj = [] def obj.foo end p obj.method(:foo) => ruby 1.6.6 (2001-12-26) [i586-linux] #<Method: Array(Array)#foo> => ruby 1.7.2 (2002-02-05) [i586-linux] #<Method: [].foo>
ブロックの評価結果を fill する値として指定できるようになりました。ブ ロックは要素毎に評価されるので、下のような例では "val" が毎回生成さ れます。
ary = Array.new(3, "val") p ary.collect {|v| v.id } # => [537774036, 537774036, 537774036] ary = Array.new(3) { "val" } p ary.collect {|v| v.id } # => [537770040, 537770028, 537770016]
追加
s = File.stat("/dev/null") p s.rdev_major p s.rdev_minor => ruby 1.7.2 (2002-01-28) [i686-linux] 1 3
ブロックを指定できるようになりました。重複したキーに対する振舞いを制 御できます。
Numeric など immutable なオブジェクトは clone できなくなりました。 ruby-bugs-ja:PR#94, rubyist:0831
$DEBUG=true true.clone rescue nil false.clone rescue nil nil.clone rescue nil :sym.clone rescue nil (10**10).clone rescue nil 0.clone rescue nil => Exception `TypeError' at -:2 - can't clone true Exception `TypeError' at -:3 - can't clone false Exception `TypeError' at -:4 - can't clone nil Exception `TypeError' at -:5 - can't clone Symbol ruby 1.6.6 (2001-12-26) [i586-linux] => Exception `TypeError' at -:2 - can't clone TrueClass Exception `TypeError' at -:3 - can't clone FalseClass Exception `TypeError' at -:4 - can't clone NilClass Exception `TypeError' at -:5 - can't clone Symbol Exception `TypeError' at -:6 - can't clone Bignum Exception `TypeError' at -:7 - can't clone Fixnum ruby 1.7.1 (2001-10-10) [i586-linux]
汚染された Proc は、ブロックにできなくなる(かも) ruby-dev:15682
引数に基数(2,8,10,16)を指定できるようになりました。
p "010".to_i(16) => ruby 1.7.2 (2002-01-11) [i586-linux] 16
ハッシュのデフォルト値としてブロックを指定できるようになり ました。ブロックを指定すると空のハッシュ要素の参照に対して その都度ブロックを実行し、その結果を返します。 ブロックにはハッシュ自身と、ハッシュを参照したときのキーが渡されます
h = Hash.new("foo") p h.default.id p h.default(0).id # Hash#default はブロックに渡すキーを指定できます p h[0].id p h[0].id p h[1].id => ruby 1.7.2 (2001-12-10) [i586-linux] 537774276 537774276 537774276 537774276 h = Hash.new { "foo" } p h.default.id p h.default(0).id p h[0].id p h[0].id p h[1].id => ruby 1.7.2 (2001-12-10) [i586-linux] 537770616 537770352 537770316 537770280 h = Hash.new { raise IndexError, "undefined!!" } p h[0] => -:1: undefined!! (IndexError) from -:1:in `yield' from -:2:in `default' from -:2:in `[]' from -:2 ruby 1.7.2 (2001-12-10) [i586-linux]
追加
# ブロックを与えなかった場合は、indexes/indicies と同じです。 # (注: indexes/indicies は obsolete となっています) p [1,2,3].select(0,1,2,3) p [1,2,3].select(-4,-3,-2,-1) p( {1=>"a", 2=>"b", 3=>"c"}.select(3,2,1) ) => ruby 1.7.2 (2001-12-10) [i586-linux] [1, 2, 3, nil] [nil, 1, 2, 3] ["c", "b", "a"] # ブロックを与えた場合はこれまでの Enumerable#select と同じです。 p [1,2,3,4,5].select {|v| v % 2 == 1} p( {1=>"a", 2=>"b", 3=>"c"}.select {|k,v| k % 2 == 1} ) => ruby 1.6.6 (2001-12-04) [i586-linux] [1, 3, 5] [[1, "a"], [3, "c"]] => ruby 1.7.2 (2001-12-10) [i586-linux] [1, 3, 5] [[1, "a"], [3, "c"]]
追加。
m = /(foo)(bar)(baz)/.match("foobarbaz") p m.select(0,1,2,3,4) # same as m.to_a.indexes(...) p m.select(-1,-2,-3) => ruby 1.7.2 (2001-12-10) [i586-linux] ["foobarbaz", "foo", "bar", "baz", nil] ["baz", "bar", "foo"]
追加 re.match(str) と同じ。
Module.new, Class.new でブロックが与えられた場合、生成した モジュール/クラスのコンテキストでブロックを実行するように なりました。
第二引数に汚染された文字列を渡すと例外 SecurityError が 起こるようになりました。1.6 では、汚染された文字列をセーフレ ベル4で評価するようになっていました。 ruby-list:32215
puts は、配列を特別扱いしなくなり、Array#to_s が出力されるようになりました。Array#to_s は、 デフォルトで間に改行を挟んだ文字列を出力するように変更され たため挙動に違いはありません(ただし $, の 値に影響されます)。ruby-dev:15043
この変更は、まだ試験的ですが元に戻りそうな気配。。。ruby-dev:15313
$, = "," puts %w(foo bar baz) => ruby 1.6.5 (2001-11-01) [i586-linux] foo bar baz => ruby 1.7.2 (2001-11-25) [i586-linux] foo,bar,baz
・・・元に戻ったようです。
=> ruby 1.7.2 (2001-12-10) [i586-linux] foo bar baz
引数に基数を指定できるようになりました。
p 10.to_s(16) => ruby 1.7.2 (2001-11-25) [i586-linux] "a"
$/ が "\n" (デフォルト)のとき、どの行末形式("\r\n", "\r", "\n" のいずれでも)でもそれらを取り除くようになりました。
p "aaa\r\n".chomp => ruby 1.6.5 (2001-11-01) [i586-linux] "aaa\r" => ruby 1.7.2 (2001-11-25) [i586-linux] "aaa"
Complex#to_i, #to_f, #to_r はなくなりました。 ruby-bugs-ja:PR#102, rubyist:0879
メソッド名と括弧の間に空白があるとその括弧は引数を括る括弧ではなく 式の括弧と解釈するようになりました。 *120 *121
p (1+2)*3 => -:1: warning: p (...) interpreted as method call -:1: warning: useless use of * in void context ruby 1.6.5 (2001-09-19) [i586-linux] 3 -:1: undefined method `*' for nil (NameError) => -:1: warning: p (...) interpreted as command call ruby 1.7.1 (2001-06-05) [i586-linux] 9
構造体クラスのサブクラスをダンプしたものがロードできませんでした。 ruby-bugs-ja:PR#104
S = Struct.new("S", :a) class C < S end p Marshal.load(Marshal.dump(C.new)) => -:4: warning: instance variable __member__ not initialized -:4:in `dump': uninitialized struct (TypeError) from -:4 ruby 1.6.5 (2001-09-19) [i586-linux] => ruby 1.7.1 (2001-10-19) [i586-linux] #<C a=nil>
グローバル変数のエイリアスが効いていませんでした。 ruby-dev:14922
$g2 = 1 alias $g1 $g2 p [$g1, $g2] $g2 = 2 p [$g1, $g2] => ruby 1.6.5 (2001-09-19) [i586-linux] [1, 1] [1, 2] => ruby 1.7.1 (2001-10-19) [i586-linux] [1, 1] [2, 2]
ブロックを持てるようになりました。ブロックの実行は module_eval と同じように、そのモジュール/クラスのコンテキ スト(self が そのモジュール/クラス)で実行されます
Module.new {|m| p m} => ruby 1.7.1 (2001-10-15) [i586-linux] #<Module:0x401afd5c>
追加
p "foobarbaz"[/(foo)(bar)(baz)/, 1] p /(foo)(bar)(baz)/.match("foobarbaz").to_a[1] => -:2: warning: ambiguous first argument; make sure ruby 1.7.1 (2001-10-05) [i586-linux] "foo" "foo" str = "foobarbaz" p str[/(foo)(bar)(baz)/, 2] = "BAR" # => "BAR" p str # => "fooBARbaz"
str[/re/, 0] は、str[/re/] と同じです。
Array.new の引数に配列を渡すとそのコピーを生成するようになりました。
ary = [1,2,3] ary2 = Array.new ary p ary, ary2 p ary.id, ary2.id => ruby 1.7.1 (2001-10-05) [i586-linux] [1, 2, 3] [1, 2, 3] 537758120 537755360
String.new の引数を省略できるようになりました。
p String.new => -:1:in `initialize': wrong # of arguments(0 for 1) (ArgumentError) from -:1:in `new' from -:1 ruby 1.7.1 (2001-08-29) [i586-linux] => ruby 1.7.1 (2001-10-05) [i586-linux] ""
追加
p Dir.open(".").path => ruby 1.7.1 (2001-10-05) [i586-linux] "."
〜この間、空白期間〜
Readline.readline 実行中に Ctrl-C により中断した後でも、端末状態を 復帰するようにしました。ruby-dev:14574
追加(Module#included の再定義)
追加。
while, until, class, def が式として値を返すようになりました。
p(while false; p nil end) p(while true; break "bar" end) p(class Foo; true end) p(module Bar; true end) p(def foo; true end) => -:1: void value expression -:2: void value expression -:3: void value expression -:4: void value expression -:5: void value expression ruby 1.7.1 (2001-08-20) [i586-linux] => -:1: warning: void value expression -:2: warning: void value expression -:3: warning: void value expression -:4: warning: void value expression -:5: warning: void value expression ruby 1.7.1 (2001-08-23) [i586-linux] false "bar" true true nil
while/until は途中で nil を返すように修正されました。 ruby-dev:15909
=> -:1: warning: void value expression -:2: warning: void value expression -:3: warning: void value expression -:4: warning: void value expression -:5: warning: void value expression ruby 1.7.2 (2002-02-20) [i586-linux] nil "bar" true true nil
文字列の範囲オブジェクトと文字列との比較を行う場合に、 以前は範囲の両端と比較していましたが、String#upto により1要素ずつ 比較を行うようになりました。
p(("a" .. "ab") === "aa") => ruby 1.7.1 (2001-08-20) [i586-linux] true => ruby 1.7.1 (2001-08-23) [i586-linux] false
追加。ruby-dev:8986以降で提案された Schwartzian transform を行うための sort です。
Updated. New methods and constants for using the mouse, character attributes, colors and key codes have been added.
追加。step ごとの要素で繰り返します。
条件式中の正規表現リテラルは警告が出るようになりました。
$_ との正規表現マッチは、明示的に ~/re/ (単項の ~ メソッ ド)などとすることが推奨されます。
$_ = "foo" p $_ if /foo/ p $_ if /bar/ => -:2: warning: regex literal in condition -:3: warning: regex literal in condition ruby 1.7.1 (2001-08-14) [i586-linux] "foo"
追加。左端あるいは右端の空白類を取り除きます。
追加。ソケットアドレス構造体(INET domain)のpack/unpack。
追加。ソケットアドレス構造体(UNIX domain)のpack/unpack。
追加。アルファベットの大小を無視した文字列比較。
$= の値に関らず常にアルファベットの大小を区別するよ うになりました。
Added. ruby-dev:13941
Changed to warn only when invoked from multiple threads or no block is given. ruby-dev:13823
Dir.chdir("/tmp") pwd = Dir.pwd #=> "/tmp" puts pwd Dir.chdir("foo") { pwd = Dir.pwd #=> "/tmp/foo" puts pwd Dir.chdir("bar") { # <-- previously warned pwd = Dir.pwd #=> "/tmp/foo/bar" puts pwd } pwd = Dir.pwd #=> "/tmp/foo" puts pwd } pwd = Dir.pwd #=> "/tmp" puts pwd
追加 ruby-dev:13597
引数の数をチェックしない点を除けば Proc#call と同じです。
追加
このメソッドで使用するフラグ FNM_NOESCAPE, FNM_PATHNAME, FNM_PERIOD, FNM_CASEFOLD もFile::Constants モジュールに定義されました。
p %w(foo bar bar.bak).reject! { |fn| File::fnmatch?("*.bak", fn) } => ruby 1.7.1 (2001-06-12) [i586-linux] ["foo", "bar"]
追加
多重代入の規則を見直しました。変更は以下の点だけです。
# *a = nil p a => ruby 1.7.1 (2001-06-05) [i586-linux] [nil] => ruby 1.7.1 (2001-06-12) [i586-linux] []
以下の挙動を修正しました。
a = *[1] p a #=> [1]
現在は、1要素の配列も正常に展開されます。
a = *[1] p a #=> 1
NameError を StandardError のサブクラスに戻しました。 クラス階層は以下のようになりました。
NoMethodError < NameError < StandardError.
第2引数を数値(File::RDONLY|File::CREATとか)で指定した場合に限り、第3 引数を用いていましたが、第3引数が与えられれば常に有効にするように しました。 ruby-bugs-ja:PR#54
無名のクラス/モジュールは dump できないようになりました。
p Marshal.dump(Class.new) => ruby 1.6.4 (2001-06-04) [i586-linux] "\004\005c\031#<Class 0lx401a6b44>" => -:1:in `dump': can't dump anonymous class #<Class 0lx401a73dc> (ArgumentError) from -:1 ruby 1.7.1 (2001-08-24) [i586-linux]
モジュールのロードの型チェックに誤りがありました。この変更によりdump フォーマットのマイナーバージョンが1あがりました
p Marshal.dump(Object.new).unpack("CC").join(".") => ruby 1.6.4 (2001-06-04) [i586-linux] "4.5" p Marshal.dump(Object.new).unpack("CC").join(".") => ruby 1.6.4 (2001-06-11) [i586-linux] "4.6"
内部のハッシュテーブルを使用することにより定数参照の速度を改善したそうです。 (ChangeLogの
Tue Jun 5 16:15:58 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
に該当するようです)
以下のようなコード(pの後の空白に注意)
p ("xx"*2).to_i
は、
(p("xx"*2)).to_i
ではなく
p (("xx"*2).to_i)
とみなすようになりました(これはまだ実験的な変更です)。
追加。これにより(配列への暗黙の変換が適用されるので)以下のように書く ことができます。
a, b, c = 1..3
break, next は、引数を指定することでイテレータや yield の値を返す ことができるようになりました。(この機能はまだ実験です)
break [n] はイテレータを終了させ、n がそのイテレータの返り値になります。 next [n] はブロックを抜け、n が yield の返り値になります。
def foo p yield end foo { next 1 } def bar yield end p bar { break "foo" } => ruby 1.7.1 (2001-08-20) [i586-linux] 1 "foo"
to_str を定義したオブジェクトはより広範囲にStringとして振舞うように なりました。
文字列を引数に取るほとんどの組込みメソッドは、to_str による暗黙の 型変換を試みます。
foo = Object.new class <<foo def to_str "foo" end end p File.open(foo) => -:7:in `open': wrong argument type Object (expected String) (TypeError) ruby 1.6.4 (2001-04-19) [i586-linux] => -:7:in `open': No such file or directory - "foo" (Errno::ENOENT) ruby 1.7.0 (2001-05-02) [i586-linux]
範囲演算子式中の単独の数値リテラルが $.
と比較されるのは
-e オプションによる1行スクリプトの中だけになりました。
発生した例外 $! と rescue 節の例外クラスとは Module#=== を使って比較するようになりました。
以前は kind_of? による比較なので基本的な動作に変わりはありませんが、 SystemCallError.=== は特別に errno が一致する例外を同じと見なすよう に再定義されました。これにより、例えば Errno::EWOULDBLOCK と Errno::EAGAIN が同じ意味(同じerrno)の場合にどちらを指定しても rescue できるようになりました。
Array#collect がブロックを伴わない場合に self.dup を返していました。 そのため、Array 以外を返すことがありましたruby-list:30480。
Foo = Class.new Array a = Foo.new p a.map.class p a.collect.class => ruby 1.7.1 (2001-06-12) [i586-linux] Array Foo => ruby 1.7.1 (2001-07-31) [i586-linux] Array Array
dup のバグ修正 ruby-list:30481
class Foo < Array attr_accessor :foo end a = Foo.new a.foo = 1 b = a.dup b.foo b.foo = 99 p b.foo # => ruby 1.6.4 (2001-06-04) [i586-linux] nil # => ruby 1.6.4 (2001-07-31) [i586-linux] 99
追加
追加 ruby-talk:14289
ary[n,0] = [other,...]
と同じ(ただし self を返す)
ary = [0,1,2,3] ary[2, 0] = [4, 5, 6] p ary ary = [0,1,2,3] ary.insert(2, 4, 5, 6) p ary
Array#pack, String#unpack のテンプレート文字 "p", "P" は、nil と NULLポインタの相互変換を行うようになりましたruby-dev:13017。
p [nil].pack("p") p "\0\0\0\0".unpack("p") => ruby 1.7.0 (2001-05-17) [i586-linux] "\000\000\000\000" [nil]
常にself返すようになりました。
将来にわたってこのことが保証されるわけではないそうです ruby-dev:12506。
(注: Class#inherited ではありません)
以前は、クラスのサブクラスの定義を禁止するために定義されていましたが、 (TypeError例外を発生させるメソッドとして定義されていました) こ の役割は Class.new が担保するようになりました。そのため、 Class.inherited メソッドの定義はなくなりました。
class SubClass < Class end #=> -:1:in `inherited': can't make subclass of Class (TypeError) from -:1 ruby 1.7.1 (2001-06-12) [i586-linux] #=> -:1: can't make subclass of Class (TypeError) ruby 1.7.1 (2001-07-31) [i586-linux]
ブロックを伴う場合File.openと同様に、ブロックの結果がメソッドの
戻り値になりました。(1.6以前は nil
固定)
ブロックを指定できるようになりました。
先行するバックスラッシュにより、ワイルドカードをエスケープ できるようになりました。 また、空白類に特殊な意味はなくなりました('\0'の効果は残っています)。
追加
追加
追加
追加。ruby-talk:9460が実装に至った経緯だと思う
Interrupt は、SignalExceptionのサブクラスになりました。 (1.6以前はExceptionのサブクラス)
追加。Marshal が出力するダンプフォーマットのバージョン番号です。 ruby-dev:14172
追加 ruby-dev:12766
Regexp#match の利便のために用意されました。以前は、
foo, bar, baz = /(\w+?)\s+(\w+?)\s+(\w+)/.match("foo bar baz").to_a[1..-1] p [foo, bar, baz]
とする必要がありましたが、これにより
_, foo, bar, baz = /(\w+?)\s+(\w+?)\s+(\w+)/.match("foo bar baz") p [foo, bar, baz]
とすることができます。
追加
追加。Module#append_feature の後に呼ばれるhook
追加
追加。商を返します。
追加 ruby-dev:12763
旧称は削除されました。NotImplementedErrorを使ってください
追加
省略可能な引数 all が追加されました。
class Foo def foo end end obj = Foo.new module Bar def bar end end class <<obj include Bar def baz end end p obj.singleton_methods #=> ["baz"] p obj.singleton_methods true #=> ["baz", "bar"]
Time.times から移動しました。 (Time.times も残っていますが、warningが出ます)
追加。$?
の値も整数からこのクラスのインスタンスになりました。
追加
追加
追加。to_a と同じ
optional な引数が追加されました。
追加
追加。大文字小文字の区別をせずに文字列を比較。
追加
str[n, 0] = other
と同じ(ただし self を返す)
追加 ruby-dev:12921
追加
追加 (上記 「rescue 節の...」 を参照のこと) ruby-dev:12670
追加
ローカル側アドレスを省略可能な第3,4引数で指定できるようになりました。
追加。Thread固有データのキーの配列を返します。
負の time_t を扱えるようになりました(OSがサポートしている場合に限る)
p Time.at(-1) => Thu Jan 01 08:59:59 JST 1970
gmtime なタイムゾーンに対して"UTC"を返すようになりました (以前は環境依存。大抵の場合"GMT")
以下、未検証 (ruby-dev:13476 まだ仕様が確定してないらしい。メモの 意味も込めてそのまま残します。ruby-dev:14601, ruby-dev:15927 も参照)
Sat Feb 24 03:15:49 2001 Yukihiro Matsumoto <matz@ruby-lang.org> * io.c (set_stdin): preserve original stdin. * io.c (set_outfile): preserve original stdout/stderr.
以下に挙げる変数名、メソッド名、オブジェクト名は古い名前です。 使用すると、警告が出たり、ある日突然なくなったりするかもしれません。
version 1.7 では、使用すると
warning: Array#indexes is deprecated; use Array#select
と警告が出ます。
メソッド名として動作を正確に表してない、index との混同がややこしいため ということです。 ruby-talk:10830 とか ruby-talk:11066 で議論が起こってい ました。
警告メッセージにあるように select がその候補になっています。 (どこで、select になったのかがわかりません。どなたか教えてください) *123
version 1.7では、旧称は削除されました。
MatchDataの旧称
Array#collect! に置き換えられました。
このメソッドを使用すると警告メッセージが出ます。 (1.7 ではこのメソッドはなくなりました。)
version 1.7 から Process.times に移動しました。version
1.7 で Time.times
を使用すると警告メッセージが出ます。
メソッドに付いたブロックが必ずしも繰り返さないことからイテレータはブ ロック付きメソッドの総称ではなくなりました。そのためブロック付きで呼 ばれたかどうかの判断は関数 block_given? に名称が変更されました。
が、イテレータという用語自体は依然使われ続けています。(このマニュア ルでも使っています)そのためこの関数が消えることもないかもしれません。
p オプションはなくなりました。入れ代わりに m オプションが導入されましたが これは p オプションとは意味がまったく違います。
//p はメタ文字 ".", "^", "$" の意味を変えるオプションでしたが、 //m は "." の意味だけを変えます("." が改行にマッチするようになる)。 //p は、定義が複雑であること、//m と 正規表現 \A \Z を使って表現可能 であることから廃止されました。詳細はruby-list:22483を参照のこと。
$~
, $!
等
なくなることはないと思いますが、基本的に使わないのが最近のスタイルです。 (少なくとも増えることはないそうです) これら特殊変数を使わないようにするために追加されたメソッドや文 法が存在します。(Regexp.last_match, Process.waitpid2, rescue => var など)
だからといって、無理に特殊変数を使わないようにする必要はありません。 各人の好みに応じて使い分けてください。
なお、$=
(文字列の比較における大文字小文字の無視)は、使いにくい
という理由から obsolete であることが明言されました
(ruby-dev:12978)。version 1.7 では警告が出ます。
$= = 1 => ruby 1.7.1 (2001-06-12) [i586-linux] => -:1: warning: modifying $= is deperecated ruby 1.7.1 (2001-07-31) [i586-linux]
version 1.7 では、文字列のハッシュ値は、$= の値に依存しなくなっています。 ruby-bugs-ja:PR#61
str = "foobar" $= = false a = str.hash $= = true b = str.hash p a,b => ruby 1.6.4 (2001-07-31) [i586-linux] 594908901 -24977883 => -:3: warning: modifying $= is deperecated -:5: warning: modifying $= is deperecated ruby 1.7.1 (2001-08-06) [i586-linux] 594908901 594908901
(一部憶測を含む解説)
昔も今もこれらは定数であり値(オブジェクト)ではありませんが、(はるか)
昔は、true, false, nil を参照するにはこれらの定数を通してしか行えま
せんでした。現在、疑似変数 true
, false
, nil
によっ
て直接これらの特殊なオブジェクトを参照することが出来るためわざわざ定
数を使う必要はなくなりました。(疑似変数はパーサが解釈するのでほんの
わずか速いかもしれません:-)
大文字をこよなく愛する汎用機系の人(偏見)は使い続けても問題ないでしょ う:-)
RUBY_VERSION,RUBY_RELEASE_DATE,RUBY_PLATFORMの旧称。
使用すると warning が出ます。これらのメソッドは以前 final.rb で提供 されていた
ObjectSpace.define_finalizer ObjectSpace.undefine_finalizer
が組み込まれたことによって obsolete になりました(従って、final.rb も obsolete になりました)。
ruby version 1.7 では、DOSISH対応(DOS/Windows のパス名の扱いに対する変 更)が含まれています*124。 (現在の)変更点を以下に示します。
なお、これらの変更は mswin32版、mingw32版, human68k版, os2_emx版の Ruby にのみあてはまります。
とりあえずの目標として、
への対応が挙げられていますが、ドライブレター対応などの微妙な部分については現在もruby-listなどで議論が継続されています。 現時点では、Fileの各メソッドに対する\対応, マルチバイトパス名対応, UNC 対応が実装されています。ruby-dev:13817, ruby-dev:14097
以下、各メソッドの挙動について...
パスセパレータとして従来の/に加えて\も認識するようになっています。 これに合わせて、マルチバイトで記述されたパス名への対応も行われています。
p File.dirname("C:\\foo\\bar") => ruby 1.6.4 (2001-06-04) [i586-mswin32] "." => ruby 1.7.1 (2001-08-16) [i586-mswin32] "C:\\foo"
ドライブレター対応に関しては、下記のような案が提示されています。
p File.dirname("C:/foo") p File.dirname("C:\\foo") p File.dirname("C:foo") => ruby 1.6.4 (2001-06-04) [i586-mswin32] "C:" "." "." => ruby 1.7.1 (2001-08-16) [i586-mswin32] "C:" "C:" "." => Cheng 案 ((<ruby-dev:13817>)) "C:/" "C:\\" "C:" => なかだ案 ((<ruby-list:31073>)) "C:/" "C:\\" "C:."
パスセパレータとして従来の/に加えて\も認識するようになっています。 これに合わせて、マルチバイトで記述されたパス名への対応も行われています。
p File.basename("C:\\foo\\bar") => ruby 1.6.4 (2001-06-04) [i586-mswin32] "C:\\foo\\bar" => ruby 1.7.1 (2001-08-16) [i586-mswin32] "bar"
File.dirname と File.basename が変更されているので、File.split もそれに準じた 結果を返します。
ドライブレター対応に関して、下記のような案が提示されています。
Dir.chdir("D:/") p File.expand_path("C:foo", "C:/bar") p File.expand_path("D:foo", "C:/bar") => ruby 1.6.4 (2001-06-04) [i586-mswin32] "C:/bar/C:foo" "C:/bar/D:foo" => なかだ案 ((<ruby-dev:13914>)) "C:/bar/foo" "D:/foo" => 新井案 ((<ruby-list:30970>)) "C:/bar/foo" (なんらかの例外)
ドライブレター対応に関して、下記のような案が提示されています。
p File.join("c:", "foo") p File.join("c:/", "foo") p File.join("c:.", "foo") p File.join("c:", "/foo") => ruby 1.6.4 (2001-06-04) [i586-mswin32] "c:/foo" "c://foo" "c:./foo" "c://foo" => なかむら(う)案 ((<ruby-list:31103>)) "c:/foo" "c:/foo" "c:./foo" "c://foo" => 新井案 ((<ruby-list:31185>)) "c:./foo" "c:/foo" "c:./foo" "c:./foo"
以下に疑似BNFによるRubyの文法を示します。より詳しくは parse.y を
参照してください。sample/exyacc.rb
を使うと規則だけを取り出せますので
活用しましょう。
PROGRAM : COMPSTMT COMPSTMT : STMT (TERM EXPR)* [TERM] STMT : CALL do [`|' [BLOCK_VAR] `|'] COMPSTMT end | LHS `=' COMMAND [do [`|' [BLOCK_VAR] `|'] COMPSTMT end] | alias FNAME FNAME | undef (FNAME | SYMBOL)+ | STMT if EXPR | STMT while EXPR | STMT unless EXPR | STMT until EXPR | STMT rescue STMT | `BEGIN' `{' COMPSTMT `}' | `END' `{' COMPSTMT `}' | EXPR EXPR : MLHS `=' MRHS | return CALL_ARGS | EXPR and EXPR | EXPR or EXPR | not EXPR | COMMAND | `!' COMMAND | ARG CALL : FUNCTION | COMMAND COMMAND : OPERATION CALL_ARGS | PRIMARY `.' FNAME CALL_ARGS | PRIMARY `::' FNAME CALL_ARGS | super CALL_ARGS | yield CALL_ARGS FUNCTION : OPERATION [`(' [CALL_ARGS] `)'] | PRIMARY `.' FNAME `(' [CALL_ARGS] `)' | PRIMARY `::' FNAME `(' [CALL_ARGS] `)' | PRIMARY `.' FNAME | PRIMARY `::' FNAME | super [`(' [CALL_ARGS] `)'] ARG : LHS `=' ARG | LHS OP_ASGN ARG | ARG `..' ARG | ARG `...' ARG | ARG `+' ARG | ARG `-' ARG | ARG `*' ARG | ARG `/' ARG | ARG `%' ARG | ARG `**' ARG | `+' ARG | `-' ARG | ARG `|' ARG | ARG `^' ARG | ARG `&' ARG | ARG `<=>' ARG | ARG `>' ARG | ARG `>=' ARG | ARG `<' ARG | ARG `<=' ARG | ARG `==' ARG | ARG `===' ARG | ARG `!=' ARG | ARG `=~' ARG | ARG `!~' ARG | `!' ARG | `~' ARG | ARG `<<' ARG | ARG `>>' ARG | ARG `&&' ARG | ARG `||' ARG | defined? ARG | PRIMARY PRIMARY : `(' COMPSTMT `)' | LITERAL | VARIABLE | PRIMARY `::' identifier | `::' identifier | PRIMARY `[' [ARGS] `]' | `[' [ARGS [`,']] `]' | `{' [(ARGS|ASSOCS) [`,']] `}' | return [`(' [CALL_ARGS] `)'] | yield [`(' [CALL_ARGS] `)'] | defined? `(' ARG `)' | FUNCTION | FUNCTION `{' [`|' [BLOCK_VAR] `|'] COMPSTMT `}' | if EXPR THEN COMPSTMT (elsif EXPR THEN COMPSTMT)* [else COMPSTMT] end | unless EXPR THEN COMPSTMT [else COMPSTMT] end | while EXPR DO COMPSTMT end | until EXPR DO COMPSTMT end | case [EXPR] (when WHEN_ARGS THEN COMPSTMT)+ [else COMPSTMT] end | for BLOCK_VAR in EXPR DO COMPSTMT end | begin COMPSTMT [rescue [ARGS] [`=>' LHS] THEN COMPSTMT]+ [else COMPSTMT] [ensure COMPSTMT] end | class identifier [`<' identifier] COMPSTMT end | module identifier COMPSTMT end | def FNAME ARGDECL COMPSTMT [rescue [ARGS] [`=>' LHS] THEN COMPSTMT]+ [else COMPSTMT] [ensure COMPSTMT] end | def SINGLETON (`.'|`::') FNAME ARGDECL COMPSTMT end WHEN_ARGS : ARGS [`,' `*' ARG] | `*' ARG THEN : TERM | then | TERM then DO : TERM | do | TERM do BLOCK_VAR : LHS | MLHS MLHS : MLHS_ITEM `,' MLHS_ITEM [(`,' MLHS_ITEM)*] [`,' `*' [LHS]] | MLHS_ITEM `,' `*' [LHS] | MLHS_ITEM [(`,' MLHS_ITEM)*] `,' | `*' [LHS] | `(' MLHS `)' MLHS_ITEM : LHS | '(' MLHS ')' LHS : VARNAME | PRIMARY `[' [ARGS] `]' | PRIMARY `.' identifier MRHS : ARGS [`,' `*' ARG] | `*' ARG CALL_ARGS : ARGS | ARGS [`,' ASSOCS] [`,' `*' ARG] [`,' `&' ARG] | ASSOCS [`,' `*' ARG] [`,' `&' ARG] | `*' ARG [`,' `&' ARG] | `&' ARG | COMMAND ARGS : ARG (`,' ARG)* ARGDECL : `(' ARGLIST `)' | ARGLIST TERM ARGLIST : identifier(`,'identifier)*[`,'`*'[identifier]][`,'`&'identifier] | `*'identifier[`,'`&'identifier] | [`&'identifier] SINGLETON : VARNAME | self | nil | true | false | `(' EXPR `)' ASSOCS : ASSOC (`,' ASSOC)* ASSOC : ARG `=>' ARG VARIABLE : VARNAME | self | nil | true | false | __FILE__ | __LINE__ LITERAL : numeric | SYMBOL | STRING | HERE_DOC | WORDS | REGEXP STRING : LITERAL_STRING+ TERM : `;' | `\n'
以下のものは字句解析機で解釈されます。
OP_ASGN : `+=' | `-=' | `*=' | `/=' | `%=' | `**=' | `&=' | `|=' | `^=' | `<<=' | `>>=' | `&&=' | `||=' SYMBOL : `:'FNAME | `:'`@'identifier | `:'`@@'identifier | `:'GLOBAL FNAME : OPERATION | `|' | `^' | `&' | `<=>' | `==' | `===' | `=~' | `>' | `>=' | `<' | `<=' | `+' | `-' | `*' | `/' | `%' | `**' | `<<' | `>>' | `~' | ``' | `+@' | `-@' | `[]' | `[]=' | __LINE__ | __FILE__ | BEGIN | END | alias | and | begin | break | case | class | def | defined | do | else | elsif | end | ensure | false | for | if | in | module | next | nil | not | or | redo | rescue | retry | return | self | super | then | true | undef | unless | until | when | while | yield OPERATION : identifier | identifier'!' | identifier'?' VARNAME : GLOBAL | `@'identifier | `@@'identifier | identifier GLOBAL : `$'identifier | `$'any_char | `$''-'any_char LITERAL_STRING : `"' any_char* `"' | `'' any_char* `'' | ``' any_char* ``' | `%'(`Q'|`q'|`x')char any_char* char HERE_DOC : `<<'(identifier|STRING) any_char* identifier | `<<-'(identifier|STRING) any_char* space* identifier WORDS : `%'`w'char any_char* char REGEXP : `/' any_char* `/'[`i'|`m'|`x'|`o'|`e'|`s'|`u'|`n'] | `%'`r' char any_char* char
エイホ(A)、ワインバーガー(W)、カーニハン(K)による 小型のスクリプト言語。
ml archive (blade/ruby)
数値の型変換を行うメソッド。数値計算のメソッドは自分の知らな
いインスタンスが引数として渡された時にはcoerce
メソッドを使って変換を行うように取り決められている。
coerce
メソッドは引数として与えられた値(を変換し
た値)と自分(必要ならば変換した値)のペアを返す。
Rubyのライブラリの数値型の変換順序は
Fixnum -> Bignum -> Rational -> Float -> Complex
になっている。
CレベルのポインタをRubyオブジェクトとして見せるためのラッパー。 Cポインタと、mark関数、free関数から作る。Cを使ってRubyに機能 を追加しようとする人はぜひこのクラスの使い方をマスターする必 要がある。逆にいうとそういう予定のない人には用事がないクラス でもある。
defined?
いろいろなもの(式)が本当に定義されているかどうか調べてくれる
演算子。定義されていなければnil
、定義されてい
ればその式の種別を示す文字列を返す。defined?
は
メソッドのようにみえるがRubyの文法に組み込まれた演算子で、引
数の評価を行わない。よって
defined? print("abc\n")
はなにも出力しない。
オブジェクト指向プログラミング言語。matzは昔この言語の作者の
本(Object-oriented Software Construction 邦訳「オブジェクト
指向入門」)を読んで目から鱗が落ちたらしい。その割にはRubyは
Eiffelに似ていない。似ているのはブロックがend
で
終るところと、rescue
という予約語だけか。
end
ブロック構造を終える予約語。ある統計によればRubyを最初に見た 人の33%がこれを見てPascalを連想するという(嘘)。しかし、実際 にはbeginと対にならないこの形式はPascalというよりAdaやEiffel に近い。
RubyがCやPerlで慣れ親しんだ {}
を使わなかったの
は以下の理由である
単文・復文問題の回避
たとえばCでは
if (a==b) c();
に文を追加しようとして
if (a==b) c(); d();
などとするとややこしいバグの元になる。この問題はPascalにも存 在する。
ぶらさがりelse
問題の回避
上記と類似だが、
if (a==b) if (c==d) foo(); else bar();
などと書いてしまうと面倒なことになる。上のプログラムは実は
if (a==b) { if (c==d) foo(); else bar(); }
という意味である。
可読性の向上
異論はあるようだが、endという単語でブロックを閉じた方がプロ グラムが読みやすいと考えている人がいる。
begin
, case
の構文上の問題
正直言うと、matzはendという名前の変数を使おうとして痛い目に
あったことが何度かある。そこで、一度は { }
を使っ
た文法にしようと検討したが、begin
とcase
の文法がきれいにまとまらずに断念した。実をいうとこれが最大の
理由であったりする。
ENV
環境変数をアクセスするためのHash と同様の動作をするオブジェクト。実際には特異メソッドを付加し たObjectクラスのイン スタンスである。このオブジェクトによって 環境変数を変更すると、 Rubyの子プロセスにも引き継がれる。
よくある質問とその答え集。 Ruby FAQはまだまだ発展途上である。質問と答えは随時募集中。
Rubyにないもの。gotoがないのはそれが「あるべきでないから」ではなく、
「実装するのが面倒だったから」である。
gotoの代りはcatch/throw
や例外で実現する。
main
トップレベルでのself。
self
がないわけにはいかないので、ただそこにある
ためだけの単なるObject
クラスのインスタンスであるが、
Objectクラスを操作するため、いくつかの特異メソッドを定義して
ある。
定義されている特異メソッド
Rubyの作者。まつもと ゆきひろとも言う。 <URL:http://www.st.rim.or.jp/~fuku/cmail/> と3人の子供の父親でもある。
アイスクリームにいろんなものをまぜて新しい味を作ること。転じ てモジュールをクラスに混ぜて機能を追加 すること。継承を参照。
Rubyでは多重継承を採用せず、is-aの関係のための継承と、機能の 共有のためのMix-inを用意している。これは多重継承を濫用すると 関係が混乱するというmatzの信念のためである。
何だったっけ?
Principle of least surprise
Rubyのライバル。「年を経た蛇」。matzがPythonに満足していれば Rubyは生まれなかったであろう。一番気になっているのは名前の長 さ(6文字)である。
Ruby Application Archive(RAA)
Ruby Change Request
Ruby Document
オブジェクト指向スクリプト言語。Rubyの名前は「Perlに続く (pearlは6月の誕生石、Rubyは7月の誕生石)」という程度の意味で 名付けられた。Rubyは別に何かの略ではない。
オブジェクト指向プログラミング言語。matzは EiffelよりもSatherが好きだ。しかし、 SatherもやっぱりRubyには全然似ていない。
self
レシーバを参照する式。なぜ
self
かというと、メソッド
を動詞と考えるとレシーバは主語に当たり、メソッドから見ると
自分であるからという説があるが、Rubyでは深
く考えず、単にSmalltalkを真似ただけ
だ、という説が有力である。
super
オーバーライドしたメソッドから上位のメソッドを呼び出す方法。 引数を省略した時には呼び出し元のメソッドと同じ引数で呼び出さ れる。
問題:
引数として与えられた変数の値を変更した場合には、
super
で元の値が渡るか、変更した値が渡るか。
def foo(a) print a end def self.foo(a) a=25 super end foo(5) # 5 or 25??
答え:
元の値(5)
もとはThread of controlの略。一連の制御の流れのこと。Rubyでは 一つのプログラムの中に複数のスレッドが存在できる。
undef
メソッドを未定義状態にすること。継承
もMix-inもクラスにメソッドを追加するこ
とだが、undef
を使えばメソッドを取り除くことがで
きる。ただし、クラスの実装に必要なメソッド(メソッド内部から
呼ばれているメソッド)を外してしまうと痛い目に遭う。
繰り返し子。メソッドに渡すことのできるあるコードの集まりをブ ロックと呼び、ブロックが与えられたメソッドをイテレータと呼ぶ (こともある)。一般にブロックは複数回実行されるので繰り返し子 (iterate=繰り返す)と呼ばれるが、慣習として一度しか実行しな かったり、繰り返さない場合にもブロックの与えられたメソッドを イテレータと呼ぶことがある。しかし、一回でもゼロ回でも繰り返 しには違いないので嘘つきとは呼ばないように。
イテレータの中では yieldを使って ブロックを実行することができる。
あ、そうそう。内部でブロックを評価しないメソッドにブロックを 与えてもなにも起きない。エラーも起きないが、がっかりしないよ うに。
オブジェクトのこと。オブジェクトがある クラスに所属することを強調する意味あいがあるらしい。オブジェ クトなんだかインスタンスなんだか混乱してオブジェクト指向に挫 折する人は多いと聞く。
オブジェクトに固有の変数のこと。Rubyのインスタンス変数は識別
子の直前に@
をつけたものであり、メソッドの中から
しか参照できない。
再定義のこと。スーパークラスまた はincludeしているモジュールで定義され ているメソッドと同じ名前のメソッドを定義すること。オーバーラ イドした上位のメソッドは superを使って呼び出すこと ができる。
もののこと。「愛」は多分オブジェクトではな いが、「ラブレター」はオブジェクトである。あるものがものであ るか、そうでないかは多分に哲学的である。この辺がオブジェクト 指向は難しいといわれる原因かも知れない。コンピュータ業界では メモリ中の特定の空間のことをオブジェクトと呼ぶ人がいたりする 人がいる。困ったものだ。カプセル化、 抽象データ型参照。
オブジェクトを基本にしたパラダイム。 英語の"Object-Oriented"という形容詞が、日本に来て名詞化した。 オブジェクトを考え方の中心に置けば、なんでも良いようにも思え るが、一般的には
が必要らしい。 なんでも解決できる「魔法」のように考える人もいるが、世の中そ んなに甘くない。誕生から20数年を経てようやっと実用的に使われ るようになった…んだろうな、多分。
オブジェクトを基本にしたシステム設計
オブジェクトを基本にしたプログラミング。
オブジェクトを基本にしたシステム分析。
データに対する直接的な操作はデータの型に付随する特定の手続き (メソッドと呼ぶ)からだけ行うことにより、 内部構造や処理のアルゴリズムを外部から隠してしまうこと。 抽象データ型参照。
Rubyはインスタンス変数はメソッドからしか参照できないので、カ プセル化が強制されているといえる。
親プロセスから子プロセスに対して受け渡される値。 ENVでアクセスされる。 子プロセスに渡るのは環境変数のコピーなので、子プロセスから親 プロセスに環境変数を使って情報を受け渡すことはできない。 親はなかなか子供に耳を傾けないものである。
厳密にいうとRubyに関数はない。しかし、レシーバを省略したメソッ ド呼び出しは外見が関数に似ているし、 selfやインスタンス変数など レシーバの情報を全く参照しない事実上の関数として働いていると いっても良いメソッドもある。だから厳密でない言い方としてそう いうメソッドを関数と呼ぶこともある。
そういう関数(的メソッド)は大抵レシーバを省略した形式でしか呼 び出せないように可視性がprivateに 設定してある。このようなメソッドの代表として モジュール関数がある。
クラスのメソッド。全てのクラスのクラス
Classで定義されている
全てのクラスで共有されているメソッドとクラスそれぞれが固有に持っている
特異メソッドとがあるが、そんな
ことは大した問題ではない。
クラスメソッド内でのself
はクラスであるので勘違いしないように。
プログラム全体から参照できる変数。危険。多用しないこと。
先祖や親戚から受け継いだものに頼り切って、 自分では最低限のことしかしないこと。現実世界では嫌な奴。 転じて、あるクラスに機能を追加した新しいクラス を作ること。継承はis-aの関係を表現するのに有効である。たとえ ば、学生一般の性質を記述した「学生」クラスを継承して、実験に 苦しめられる「工学部生」クラスを作ることができる。is-aの関係 がなく、単に性質や機能を共有する場合にはMix-in を使うことが望ましいとされる。
オーバーライドのこと。
項目からその定義を取り出すことができるもの。転じて ハッシュの別名。オブジェクト指向の起源と も呼べるSmalltalkにおいてハッシュに 相当するデータ構造が「辞書」と呼ばれていたせいで辞書という用 語になじんでいる一群の人々がいる。
オブジェクト(あるいは「なにか」)を「使える」状態にすること。
インスタンスの初期化には
Object#initialize
メソッドを再定義する。クラスのメソッド
Class#newのデフォルトの
定義は新たに生成したインスタンスに対して、
initialize
を実行する。new
への
引数はそのままinitialize
に渡される。また、
new
がブロックとともに呼び出された時には
initialize
にそのブロックがそのまま与えられる。
ということはClass#new を再定義する必要はないはずだ。
台本。転じて、インタープリタが解釈する比較的短いプログラムの こと。もちろん中には超大作の台本もある。
スクリプトに従ってバッチ処理を行うイン タープリタのこと。人間も台本を読むという点においてスクリプト 言語である。
参照ではなく、実際の値が変数に格納さ れるもの。Rubyの現在の実装ではFixnumとnil/true/falseだけが即 値である。しかし、Fixnumが即値でないRubyの実装があっても構わ ないし、モデル上全ての値がオブジェクトへの参照であると考えて も差し支えない。
順番に並べ替えること。Ruby は数え上げる事ができて
(Enumerable
がincludeされていて)、各要素に順序
が定義されて(<=> が定義されて)いれば、配列に限らずどん
な複雑なオブジェクトの集まりもソートしてくれる。
break,
next,
redo,
retry,
return
などのメソッドの範囲内での脱出ではなく、捕捉されない限りメソッ
ド呼び出しの階層を遡って中断するタイプのものを大域脱出と呼ぶ。
Rubyの大域脱出には、例外によるものとcatch/throw
がある。
ほとんどの例外は(exit
で発生するSystemExit
を含めてrescue
で捕捉できるが、捕捉することに意味がない例外
(例:メモリ割当に失敗した/インタプリタそのもののバグ)は
捕捉の対象にならない。
catch/throw
はthrowされると指定されたタグと同じ
タグを持つcatchまで一気にジャンプするものである。
ローカル変数 の一種。Rubyのローカル変数はスコープが 静的に決まるためコンパイル時に変数が作成されるが、ダイナミックローカ ル変数は、実行の都度変数が作成される。ブロックの中で初めて代入された ローカル変数はダイナミックローカル変数となり、そのスコープはブロック の中だけとなる。これは、Thread 毎に独立した変数を持 つためにある。
データの構造とそのデータに対する操作をひとまとめにしたものを 抽象データ型と呼ぶ。抽象データに対する操作は必ずその操作を経 由する必要がある。結果、データ構造は外部からは直接参照されず、 内部構造の変更が外部に悪影響を及ぼさない。このことを カプセル化と呼ぶ。
一度定義したら値を変えることができない変数。 でも、この定義は矛盾しているなあ。
操作の対象のデータ型に合わせて適切な手続き(メソッド)が実行時 に選択されること。プログラムの柔軟性を高める働きがある。 オブジェクト指向の要件のひとつ。 Rubyでは変数に型が無いので動的結合は必然である。
ある特定のオブジェクトだけのための仮想的なクラス。
ある特定のオブジェクトにだけ定義されたメソッド。 メソッド参照。 特異メソッドは以下の場合に他のオブジェクトにも引き継がれる。
特異メソッドで元のクラスのメソッドをオーバーライドした場合は もとのメソッドはsuperで呼び 出すことができる。
matzの苦手なもの。彼は普段から「ソースがドキュメントだ。バグ も完全に記述されている」と主張しているが、誰も受け入れない。 当り前だ。
0x01020304
という4バイトデータを1,2,3,4
と配置するか、4,3,2,1
と配置するかということ。前
者をビッグエンディアン、後者を
リトルエンディアンと呼ぶ。どちらが
良いかという論争は時のはじめから続いていてまだ結論が出ていない。
String#chop!, Array#concat などの メソッドは、レシーバの状態を変化させるので、 「破壊的な作用をする」という。 めったにコンピュータを壊すことはない。
Rubyにおけるキーから値へのマッピングを表すデータ構造。 連想配列とか 辞書とも呼ばれる。ハッシュがハッシュ と呼ばれるのはその実現に「ハッシュ表」と呼ばれるアルゴリズム が使われているからである。ハッシュというのは「切り刻む」とい う意味で、「ハッシュド・ビーフ」の「ハッシュ」である。
「考え方」の難しい表現。素直に分かりやすい言葉を使えばいいのに…。
アメリカ大陸原住民…はインディアン。 こっちはエンディアンで語源はスウィフトの「ガリバー旅行記」に出て来る 卵を丸い端から食べる人たちである。 当然、尖った端から食べる人たちは リトルエンディアンである。 コンピュータ業界ではCPUなどがデータを並べる時の形式のひとつで、 ネットワーク族はビッグエンディアンを好むという。 バイトオーダー参照
Rubyインタプリタ組み込みでインスタンスの構造が 通常のオブジェクトと異なるクラス。 これらのクラスを継承したクラスを定義することはお勧めしない。 Rubyのビルトインクラスは以下の通りである (本当はもっとあるけど気にしないように、ちゃんと 組込みクラス/モジュール/例外クラス に列挙されてるのだから)
ループを構成したり、家や塀を建てたり、人を殴ったりするもの。
オブジェクトにつける名札。Rubyの変数には グローバル変数、 ローカル変数、 インスタンス変数がある。 それと定数は値を変えることができない ので、変数ではないが、名札であるという点に おいては変数と同じである。
対象になるオブジェクトによって実際の操作が決定されること。 Rubyではレシーバのオブジェクトに応じ てメソッドが選択されることによって実現されている。
例
obj = "abc" print obj.length, "\n" # => 3 obj = [1,2,3,4] print obj.length, "\n" # => 4
関数のように用いられるメソッドの中で、 モジュールのメソッドとしても、特異メソッドとしても定義されて いるものはモジュール関数と呼ばれる。例えば Mathモジュールのほとんどのメソッドは モジュール関数である。これらのメソッドは、例えば
Math.sqrt(2)
という形式でも
include Math sqrt(2)
という形式でも使えて便利である。
オブジェクトに対する操作。操作対象のオ ブジェクト(レシーバ)は selfで参照できる。 Rubyの場合ビルトインクラスのオブ ジェクトを除けば、オブジェクトの構造は動的に決まるので、ある オブジェクトの性質はそのオブジェクトに定義されているメソッド によって決定される。
最初10人いて段々減っていく。コンピュータ業界ではデータを並べ る時の形式のひとつで、非常に大きなシェアを持つあるCPUメーカー はリトルエンディアンを好むという。バイトオーダー参照
例外的な状況で発生するもの。例外が発生すると
beginの
rescue
節を使って明示的に捕捉されない限り、
呼び出し階層を遡ってプログラム(thread)の実行は中断される。例外の
おかげでRubyプログラムはほとんどの場合例外的な状況についていちいち
チェックせずにすむ。例外の発生した場所の情報は
$@に、例外そのものに関する情報は$!
に格納されている。
メソッドの実行主体。メソッド呼び出し式の`.
'の左
側にあるもの。メソッド内では
selfで参照できる。レシーバ
のインスタンス変数は
@変数名
という形式でアクセスできる。
ハッシュの別名。ハッシュが任意のキーから 値を取り出すことができるので、「連想」と、またハッシュは添字 が数字でない配列とみなすことができるので「配列」と呼ぶらしい。 昔々は連想配列(連想記憶と呼ばれていた)はハードウェアによって 実現されるものだと考えられていたが、計算速度の向上や適切なア ルゴリズムの発見(「ハッシュ表」と呼ぶ。ハッシュの語源)により ソフトウェアのみによって実現されるようになった。
ある範囲内でのみ参照可能な変数。その範囲をスコープと呼ぶ。 Rubyのスコープは
で、ブロックだけは外側のスコープのローカル変数もアクセスでき る。ローカル変数の有効範囲はスコープでの最初の代入が現れた場 所からスコープの終りまでである。有効範囲は静的に決まり、実際 に実行されるかどうかは関係ない。
以下にあげるものは、Array#pack、String#unpack のテンプレート文字の一覧です。テンプレート文字は後に「長さ」を表す数字 を続けることができます。「長さ」の代わりに`*'とすることで「残り全て」 を表すこともできます。
長さの意味はテンプレート文字により異なりますが大抵、
"iiii"
のように連続するテンプレート文字は
"i4"
と書き換えることができます。
下記の説明の中で short や long はシステムによらずそれぞれ 2, 4バイトサ イズの数値(32ビットマシンで一般的なshort, longのサイズ)を意味していま す。`s', `S', `l', `L' に対しては直後に `_'または`!'を("s!"のように) 続けることでシステム依存のshort, long のサイズにすることもできます。 *129
`i', `I' (int)のサイズは常にシステム依存であり、`n', `N', `v', `V' のサイズは常にシステム依存ではない(`!'をつけられない)ことに注意してください。
テンプレート文字列中の空白類は無視されます。 ruby 1.7 feature: また、`#' から改行あるいはテンプレート文字列の最後まではコメントとみな され無視されます。
説明中、Array#packとString#unpackで違いのあるものは/で区切って 「Array#packの説明/String#unpackの説明」としています。
a
ASCII文字列(null文字を詰める/後続するnull文字やスペースを残す)
A
ASCII文字列(スペースを詰める/後続するnull文字やスペースを削除)
Z
null終端文字列(a
と同じ / 後続するnull文字を削除)
b
ビットストリング(下位ビットから上位ビット)
B
ビットストリング(上位ビットから下位ビット)
h
16進文字列(下位ニブルが先)
H
16進文字列(上位ニブルが先)
c
char
C
unsigned char
s
short
S
unsigned short
i
int
I
unsigned int
l
long
L
unsigned long
q
ruby 1.7 feature: long long (64 bit 符号付き整数)
Q
ruby 1.7 feature: unsigned long long (64 bit 符号なし整数)
m
base64された文字列。60 オクテットごと(と最後)に改行コードが付加されます。
Base64は、3オクテット(8bits * 3 = 24bits)のバイナリコードをASCII文字の うちの65文字 ([A-Za-z0-9+/]の64文字とpaddingのための'=')だけを使用して 4オクテット(6bits * 4 = 24bits)の印字可能文字列に変換するエンコーディ ング法です。RFC2045で定義されています。
M
quoted-printable encoding された文字列
n
ネットワークバイトオーダー(ビッグエンディアン)のunsigned short
N
ネットワークバイトオーダー(ビッグエンディアン)のunsigned long
v
"VAX"バイトオーダー(リトルエンディアン)のunsigned short
V
"VAX"バイトオーダー(リトルエンディアン)のunsigned long
f
単精度浮動小数点数(機種依存)
d
倍精度浮動小数点数(機種依存)
e
リトルエンディアンの単精度浮動小数点数(機種依存)
E
リトルエンディアンの倍精度浮動小数点数(機種依存)
g
ビッグエンディアンの単精度浮動小数点数(機種依存)
G
ビッグエンディアンの倍精度浮動小数点数(機種依存)
p
ナル終端の文字列へのポインタ
P
構造体(固定長文字列)へのポインタ
u
uuencodeされた文字列
U
utf-8
w
BER圧縮整数
1バイトあたり7ビットを使用して必要最小限のバイト数で任意サイズの 0以上の整数を表す数値表現。各バイトの最上位ビットはデータの最後 を除いて必ず1が立っている(つまり最上位ビットはどこまでデータがあ るかを示している)。
BER は Basic Encoding Rules の略(BER自体 は整数のエンコーディングだ けを表すわけではない。ASN.1 のエンコーディングで使用される)
x
ナルバイト/1バイト読み飛ばす
X
1バイト後退
@
絶対位置への移動
以下、pack/unpack の使用例の一部です。
pack を使用しなくても同じことができる場合はその例も載せています。 pack は暗号になりやすい面があることを考慮し、pack を使いたくない人 に別解を示すためです。
数値(文字コード)の配列を文字列に変換する例
p [82, 117, 98, 121].pack("cccc") => "Ruby" p [82, 117, 98, 121].pack("c4") => "Ruby" p [82, 117, 98, 121].pack("c*") => "Ruby" s = "" [82, 117, 98, 121].each {|c| s << c} p s => "Ruby" p [82, 117, 98, 121].collect {|c| sprintf "%c", c}.join => "Ruby" p [82, 117, 98, 121].inject("") {|s, c| s << c} => "Ruby"
文字列を数値(文字コード)の配列に変換する例
p "Ruby".unpack('C*') => [82, 117, 98, 121] a = [] "Ruby".each_byte {|c| a << c} p a => [82, 117, 98, 121]
"x" でナルバイトを埋めることができる
p [82, 117, 98, 121].pack("ccxxcc") => "Ru\000\000by"
"x" で文字を読み飛ばす事が出来る
p "Ru\0\0by".unpack('ccxxcc') => [82, 117, 98, 121]
Hexダンプを数値の配列に変換する例
p "61 62 63 64 65 66".delete(' ').to_a.pack('H*').unpack('C*') => [97, 98, 99, 100, 101, 102] p "61 62 63 64 65 66".split.collect {|c| c.hex} => [97, 98, 99, 100, 101, 102]
バイナリと16進数のpackでは長さ指定は生成されるバイト数ではなく、 ビットやニブルの個数を表す
p [0b01010010, 0b01110101, 0b01100010, 0b01111001].pack("C4") => "Ruby" p ["01010010011101010110001001111001"].pack("B32") # 8 bits * 4 => "Ruby" p [0x52, 0x75, 0x62, 0x79].pack("C4") => "Ruby" p ["52756279"].pack("H8") # 2 nybbles * 4 => "Ruby"
テンプレート文字'a'の長さ指定は1つの文字列だけに適用される
p ["RUBY", "u", "b", "y"].pack("a4") => "RUBY" p ["RUBY", "u", "b", "y"].pack("aaaa") => "Ruby" p ["RUBY", "u", "b", "y"].pack("a*aaa") => "RUBYuby"
テンプレート文字"a"は、長さが足りない分をヌル文字で補う
p ["Ruby"].pack("a8") => "Ruby\000\000\000\000"
リトルエンディアンとビッグエンディアン
p [1,2].pack("s2") => "\000\001\000\002" # ビッグエンディアンのシステムでの出力 => "\001\000\002\000" # リトルエンディアンのシステムでの出力 p [1,2].pack("n2") => "\000\001\000\002" # システムによらずビッグエンディアン p [1,2].pack("v2") => "\001\000\002\000" # システムによらずリトルエンディアン
ネットワークバイトオーダの signed long
s = "\xff\xff\xff\xfe" n = s.unpack("N")[0] if n[31] == 1 n = -((n ^ 0xffff_ffff) + 1) end p n => -2
ネットワークバイトオーダの signed long(その2)
s = "\xff\xff\xff\xfe" p n = s.unpack("N").pack("l").unpack("l")[0] => -2
IPアドレス
require 'socket' p Socket.gethostbyname("localhost")[3].unpack("C4").join(".") => "127.0.0.1" p "127.0.0.1".split(".").collect {|c| c.to_i}.pack("C4") => "\177\000\000\001"
sockaddr_in 構造体
require 'socket' p [Socket::AF_INET, Socket.getservbyname('echo'), 127, 0, 0, 1].pack("s n C4 x8") => "\002\000\000\a\177\000\000\001\000\000\000\000\000\000\000\000"
ruby 1.7 feature: pack/unpack を使う代わりに Socket.pack_sockaddr_in, Socket.unpack_sockaddr_in メソッドがあります。
'\0'終端文字列のアドレス
テンプレート文字 "p" や "P" は、C 言語レベルのインタフェースのた めにあります(例えば ioctl)。
p ["foo"].pack("p") => "8\266\021\010"
結果の文字列はゴミに見えますが、実際は文字列"foo\0"を指すアドレ ス(のバイナリ表現)です。以下のようにすれば見慣れた表記で見ること が出来ます
printf "%#010x\n", "8\266\021\010".unpack("L")[0] => 0x0811b638
アドレスが指す先のオブジェクト(この例で "foo\0") は、pack の結 果が GC されるまではGCされないことが保証されています。
unpack("p"), unpack("P") は、pack の結果からしか unpack できません。
p ["foo"].pack("p").unpack("p") => ["foo"] p "8\266\021\010".unpack("p") => -:1:in `unpack': no associated pointer (ArgumentError) from -:1
ruby 1.7 feature: "p" や "P" は、nil を特別に扱い NULL ポインタとして解釈します。(以下は、32bitマシンで一般的な結果)
p [nil].pack("p") #=> "\000\000\000\000" p "\0\0\0\0".unpack("p") #=> [nil]
構造体のアドレス
例えば、
struct { int a; short b; long c; } v = {1,2,3};
を表す文字列は
v = [1,2,3].pack("i!s!l!")
です。(byte alignment の問題から実際は適当な padding が必要に なるかもしれません)
この構造体を指すアドレスは
p [v].pack("P") => "\300\265\021\010"
で得られます。
Ruby の sprintf フォーマットは基本的に C 言語の sprintf(3) のものと同じです。ただし、short や long などの C 特有の型に対する修飾子が ないこと、2進数の指示子(%b)が存在すること。sprintf のすべての方言をサ ポートしていないこと(': 3桁区切り)などの違いがあります。
rubyのsprintfフォーマットに関する完全な説明は以下の通りです。
以下はsprintfフォーマットの書式です。[]
で囲まれた部分は省略可
能であることを示しています。
%[引数指定$][フラグ][幅][.精度]指示子
`%' 自身を出力するには `%%' とします。
以下それぞれの要素に関して説明します。
フラグには `#', `+', ` '(スペース), `-', `0' の5種類があります。
2進、8進、16進の指示子(`b', `o', `x', `X') ではそれぞれプレフィック スとして"0b", "0", "0x", "0X" を付加します。 *131
p sprintf("%#b", 10) # => "0b1010" p sprintf("%#o", 10) # => "012" p sprintf("%#x", 10) # => "0xa" p sprintf("%#X", 10) # => "0XA"
浮動小数点数 (`f', `e', `E', `g', `G') に対しては必ず出力に"."をつけます。
p sprintf("%.0f", 10) # => "10" p sprintf("%#.0f", 10) # => "10." p sprintf("%.0e", 10) # => "1e+01" p sprintf("%#.0e", 10) # => "1.e+01"
また `g', `G' では上記に加えて末尾の余分な0が残ります。
p sprintf("%.05g", 10) # => "10" p sprintf("%#.05g", 10) # => "10.000"
出力文字列を符号付きにします。特に正の数では`+'が付加されます。 数値の指示子 (`d', `i', `b', `o', `x', `X', `u', `f', `e', `E', `g', `G') に対してだけ意味を持ちます。 また、特に `b', `o', `x', `X', `u' に対しては、負数に対して `-' を付加することを示します。
p sprintf("%d", 1) # => "1" p sprintf("%+d", 1) # => "+1" p sprintf("%x", -1) # => "..f" # ".." は無限に f が続くことを表している p sprintf("%+x", -1) # => "-1"
`+' と同じですが正の符号`+'の代わりに空白を用います。数値の指示子 (`d', `i', `b', `o', `x', `X', `u', `f', `e', `E', `g', `G') に対してだけ意味を持ちます。
p sprintf("%d", 1) # => "1" p sprintf("%+d", 1) # => "+1" p sprintf("% d", 1) # => " 1" p sprintf("%x", -1) # => "..f" p sprintf("% x", 1) # => " 1" p sprintf("% x", -1) # => "-1"
出力を左詰めにします「幅」の指定がなければ 意味がありません。
出力が右詰めの場合に余った部分に空白の代わりに `0' を詰めます。
数値の指示子(`d', `i', `b', `o', `x', `X', `u', `f', `g', `G')に対し てだけ意味を持ちます(`e', `E' には意味がない)
p sprintf("%010d", 10) # => "0000000010"
`#' と一緒に指定した場合の出力は以下のようになります。
p sprintf("%#010x", 10) # => "0x0000000a" p sprintf("%#010o", 10) # => "0000000012" p sprintf("%#010b", 10) # => "0b00001010"
これは、以下と同じです。
p sprintf("%#10.8x", 10) # => "0x0000000a" p sprintf("%#10.9o", 10) # => "0000000012" p sprintf("%#10.8b", 10) # => "0b00001010"
通常は、以下のようになります。
p sprintf("%#10x", 10) # => " 0xa" p sprintf("%#10o", 10) # => " 012" p sprintf("%#10b", 10) # => " 0b1010"
0以外の数字で始まる数字列は幅指定になります。幅は生成文字列の長さを示 します。後述の「精度」の値によらずこの幅分だ けの文字列が生成されます。
幅の指定は「フラグ」で付与される " ", "+", "-", "0b", "0", "0x", "0X" の長さも考慮されます。
p sprintf("%#05x", 10) # => "0x00a"
幅は「最低限必要な幅」の指定になります。結果の文字列が指定した幅を超 える場合は幅の指定は無効になります。
幅として `*' を指定すると幅の値を引数から得ることになります。
p sprintf("%10s", "foo") # => " foo" p sprintf("%*s", 10, "foo") # => " foo"
"." の後に続く数字列は精度を表します("." のみの場合 ".0" と同じです)。精度は 整数の指示子 (`d', `i', `b', `o', `x', `X', `u') に対しては、数値列部分の長さを意味します。
p sprintf("%10.5d", 1) # => " 00001" p sprintf("%#10.5x", 1) # => " 0x00001" p sprintf("%+10.5x", 1) # => " +00001"
浮動小数の指示子 (`f') に対しては小数部の桁数を意味します。
p sprintf("%10.5f", 1) # => " 1.00000" p sprintf("%10.5f", 10) # => " 10.00000"
浮動小数の指示子 (`e', `E', `g', `G') に対しては有効桁数を意味します。
p sprintf("%10.5e", 1) # => "1.00000e+00" p sprintf("%10.5e", 10) # => "1.00000e+01" p sprintf("%10.5g", 10) # => " 10" p sprintf("%#10.5G", 10) # => " 10.000"
文字列の指示子(`s') に対しては引数の文字列のうち指定した数を超える分を切り捨てます。 幅と精度を同じ値にすれば、どのような引数に対してもその 長さだけの出力を行うことになります。
p sprintf("%10.2s", "foo") # => " fo" p sprintf("%5.5s", "foo") # => # => " foo" p sprintf("%5.5s", "foobar") # => # => "fooba"
精度として `*' を指定すると精度の値を引数から得ることになります。
p sprintf("%.5s", "foobar") # => "fooba" p sprintf("%.*s", 5, "foobar") # => "fooba"
指示子は引数の型の解釈を示します。指示子を省略することはできません。 指示子には大きく分けて
があります
引数の数値(0〜255)を文字コードとみなして対応する文字を出力します。 引数が数値、String、 nil, true, false 以外のオブジェクトでは to_int メソッドによる変換を試みます。
文字列を出力します。
引数がStringオブジェクトでなければ to_s メソッドにより文字列化 したものを引数として扱います。
引数の数値を10進表現の整数として出力します。
浮動小数 Float オブジェクトは整数に変換されます(小数部切捨て)。
文字列はInteger()と同じ規則で数値に変換されます。 nil, true, false 以外のオブジェクトでは to_int メソッドによる変換を 試みます。
引数の数値を符号なし整数とみなして10進表現の整数として出力します。
p sprintf("%u", -1) # => "..4294967295"
は、p ".." + 0xffff_ffff.to_s を出力しています。
整数をそれぞれ2進、8進、16進、16進(大文字)表現の文字列で出力します。
`#' フラグを指定すれば "0b", "0", "0x", "0X" を先頭に付加します。
`+', ` ' フラグがない場合、負の数には".."が先頭(`#' フラグがあれば "0x"などの後)に付加されます。これは最上位桁の文字が無限に続くことを 意味し、2の補数表現で負の数を表しています。
p sprintf("%#10b", -1) # => "0b..111111" p sprintf("%10x", -1) # => "..ffffffff" p sprintf("%-10x", -1) # => "..f " p sprintf("%.10x", -1) # => "ffffffffff" p sprintf("%-.10x", -1) # => ".........f"
`f' は小数点表現(xxx.xxx)で数値を出力します。
`e' は指数表現(x.xxxe+xx)で数値を出力します。
`g' は 指数が -4 より小さいか精度以上の場合に `e' と同じ出力をそれ以 外では `f' と同じ出力を行います。ただし、小数部の末尾の0は取り除かれ ます。
大文字の指示子(`E', `G')は出力のアルファベットを大文字にします。
p sprintf("%f", 1.0) # => "1.000000" p sprintf("%e", 1.0) # => "1.000000e+00" p sprintf("%g", 1.0) # => "1" p sprintf("%f", 10.1) # => "10.100000" p sprintf("%e", 10.1) # => "1.010000e+01" p sprintf("%g", 10.1) # => "10.1" p sprintf("%g", 10 ** 6) # => "1e+06" p sprintf("%g", 10 ** -5) # => "1e-05"
精度の省略値は 6 です。
無限大、NaN(Not a Number) に対する出力は以下のとおりです。
p sprintf("%f", 1.0/0) # => "inf" p sprintf("%f", -1.0/0) # => "-inf" p sprintf("%f", 0.0/0) # => "nan" p sprintf("%E", 1.0/0) # => "INF" p sprintf("%E", -1.0/0) # => "-INF" p sprintf("%E", 0.0/0) # => "NAN"
利用頻度が低いので最後に説明します。
nth番目の引数のフォーマットを行うことを示します。
p sprintf("%1$d, %1$x, %1$o", 10) => "10, a, 12" p sprintf("%3$d, %2$x, %1$o", 1, 2, 3) => "3, 2, 1"
状況によってフォーマットを変えたいが引数の順序を変えたくない場合に使 用します。
case ENV['LC_TIME'] when /^ja_JP/ fmt = "%1$d年%2$d月%3$d日" else fmt = "%2$02d/%03$2d/%1$02d" end p sprintf(fmt, 1, 4, 22) => "04/22/01"
"*" の後に指定することで「幅」や 「精度」を引数で指定することもできます。
p sprintf("%5.2f", 1); # => " 1.00" p sprintf("%*.*f", 5, 2, 1); # => " 1.00" p sprintf("%1$*2$.*3$f", 1, 5, 2); # => " 1.00"
*
がついた引数は何ですか&
がついた引数は何ですかProc.new
では手続きオブジェクトが作られませんが:exit
等の:
のついた識別子は何ですかloop
は制御構造ですかa +b
がエラーになりますがs = "x"; puts s *10
がエラーになりますがp {}
で何も表示されません'\1'
と'\\1'
はどう違いますかp true or true and false
はtrue
を表示するのに、a=true if true or true and false
では、a
にtrue
が代入されません。p(nil || "")
はなんでもないのに、 p(nil or "")
はパースエラーだと言われます+
や-
は演算子ですかprivate
とprotected
の違いが分かりませんsuper
がArgumentError
になりますがload
とrequire
はどう違いますかinclude
とextend
はどう違いますかself
というのは何ですかMatchData
の begin
、end
は何を返しますかinstance_methods(true)
は何を返しますかrand
がいつも同じ乱数列を出しますがFixnum
、true
、nil
、false
が即値だということですが、参照との違いは何ですかnil
とfalse
はどう違いますかless
に文字列を渡したのですが、表示されませんFile
オブジェクトはどうなりますかclose
しないのは気持ちが悪いのですがtrue
になります"abcd"[0]
は、何を返しますかsub
とsub!
はどう違うのですか..
と...
はどう違いますかthread
とfork
はどう使い分けるのですかtrap
はどのように使いますか-K
と $KCODE
の違いはなんですか?一言で言えば、
シンプルかつ強力なオブジェクト指向スクリプト言語
です。
perlのようにテキスト処理の分野に威力を発揮します。もちろんそれだけでは なく、Rubyで実用的なサーバーアプリケーションを作成するなどということも 可能です。
Rubyにはたくさんの言語のよい部分が取り込まれており、その結果どの言語とも 異なる言語になっています。
Rubyは以下のような特長を持っています。
以下はまつもとさんのruby-talk:00394(June 11, 1999)での紹介の翻訳です。
まつもとさんは、自分の新しい言語の名前をPerlのように何か宝石の 名前からとろうとし、同僚の誕生石がRubyだったので、Rubyとした そうです。
その後、誕生石としては、pearl => 6月、ruby => 7月、活字の 大きさとしては、pearl => 5pt、ruby => 5.5ptなど、rubyが pearlの直後に来ている例があるのに気づき、Perlより新しく、できれば より良い言語の名前としてRubyが新しいスクリプト言語の名前として ふさわしいと思ったそうです。
まつもとさんは、RubyがPerlの代わりになる日を待っています(^^)。
まつもとさんのruby-talk:00382(June 4, 1999)での紹介の翻訳です。 Rubyの誕生日はruby-list:15997により修正されました。
Rubyは1993年2月24日に生まれました。その日同僚とオブジェクト指向 言語の可能性について話していました。Perl(Perl4で、Perl5ではありません。) は知っていましたが、おもちゃのにおいがして(今もありますが)好きになれ ませんでした。オブジェクト指向スクリプト言語は期待が持てました。
Pythonも知っていましたが、本当のオブジェクト指向言語とは思えません でした。オブジェクト指向がとってつけたもののように感じられたのです。 15年来言語マニアでオブジェクト指向のファンでしたので、真にオブジェクト 指向のスクリプト言語が心底欲しかったのですが、そのようなものは さがしてもさがしてもありませんでした。
そこで自分で作ろうと決心したのです。数ヶ月たってインタプリタが 動き始めました。イテレータ、例外処理、ガーベージコレクションなど 欲しかったものをいれこみました。
さらにPerlの特徴をクラスライブラリとして取り込みました。 Ruby 0.95を日本国内のニューズグループに投稿したのは、1995年12月の ことでした。
すぐにメーリングリストを始め、ホームページを作りました。メーリング リストでは活発な意見の交換がなされました。最初からあるruby-listは 今では14789通のメールを数えています。
Ruby 1.0 は1996年12月に、1.1 は1997年8月に、安定バージョンとしての 1.2 と開発バージョンの 1.3 が1998年12月にリリースされています。
Rubyの最新版は<URL:ftp://ftp.ruby-lang.org/pub/ruby/>で手に入ります。
ミラーサイトは次のとおりです。
cygwin版とmingw版とdjgpp版はRuby Binariesにバイナリがあります。
なお、Windows(cygwin)では初心者向けにRuby Entry Packageが用意されています。 そのインストール方法については初心者のためのRubyインストールガイドを見てください。*134
Rubyの公式ページは <URL:http://www.ruby-lang.org/> です。
現在Rubyの話題を扱う公式のメーリングリストは主に五つあります。
詳しくはRubyメーリングリストをご覧ください。
メイリングリスト検索用のフォームが、 <URL:http://blade.nagaokaut.ac.jp/ruby/ruby-list/index.shtml> や <URL:http://ruby.freak.ne.jp/>にあります。
また、ML Topicsには、 過去メールの主な話題がピックアップされています。
まつもとさんによると、rubyistとRuby hackerは次のような定義だそうです。
Rubyに対して単なるお客さん以上の気持を持っている人がrubyistです。たとえば
一方、Rubyに関して技術レベルの高さをあわらす人はRuby hackerと呼びましょう。 たとえば
などはRuby hackerでしょう。
これらは称号は自称されるもので別に私が公式認定をするようなものではあり ませんが、上の例でほとんど名指しされている人は、まつもとがこの人たちを {rubyist、Ruby hacker}として尊敬を込めて認めていることを表します。
Rubyの正式な表記は"Ruby"です。ただし、コマンド名は"ruby"ですし、 また並列して違和感がない限り、Rubyの代わりにrubyを使うことは 許容されます。
ただし、「RUBY」、「ルビー」、「るびー」は言語名としては許容されていません。
歴史的には"ruby"が正式名称だった時代があります。
『オブジェクト指向スクリプト言語Ruby』 まつもと ゆきひろ・石塚圭樹共著 アスキー(ISBN4-7561-3254-5)の他に何冊か刊行されています。 詳しくは「Rubyに関する書籍」をご覧ください。
正規表現に関しては、Jeffrey E. F. Friedl著「詳説正規表現」(ISBN4-900900-45-1)が オライリージャパンから出ています。様々な正規表現の実装に触れており、 Rubyの正規表現を理解するにも有用です。
Rubyは、基本的な構文はRuby1.0以来大きくは変わっていませんが、絶えず 拡張、修正が行われていますので、ドキュメントが最新バージョンに追い 付いていないところがあります*135。 また、ソースがドキュメントだという説もあります。
分からなくなったら、遠慮なくruby-listで 質問すると、教祖まつもとさんをはじめ、尊師の方々や私もはまったという 人たちに分かりやすく教えていただけます。
質問をするには、ruby -vの結果と、はまったスクリプト (長い場合は本質的なところを切り出して)を示せばよいでしょう。
irbを使っている場合は、irb固有の問題もありますので、 irb --single-irbで試してみるか、rubyで実行し直して 確認することをおすすめします。
MLを検索すれば、かなりの疑問が解決するとは思いますが、メールも 大量になってしまって、ありふれた検索では絞り込みにくくなっています。 最近のものくらいはチェックしておくのがネチケット(RFC1855の3.1.1、3.1.2参照) というものだとは 思いますが、言うは易く、行うは難しですし、新しい視点も生まれるかも しれません。思い切って質問してみましょう。
羊、ハチドリ、うさぎ...*136
*
がついた引数は何ですか&
がついた引数は何ですか変数や定数は、あるオブジェクトを指しています。何も代入しなくても nilオブジェクトを指しています。代入は、変数や定数が新しいオブジェクトを 指すようにします。
したがって、代入によりオブジェクトがコピーされて新しく作られることは なく、右辺の表現の表しているオブジェクトを左辺の変数や定数が指すように することが代入によって行われます。
という説明で満足していただければいいのですが、これでは満足できない という方もいらっしゃるかもしれません。このような理解で問題が 生じることはないのですが、実は、Fixnum、NilClass、TrueClass、FalseClass のインスタンスは、直接変数や定数が保持していますので、これらは 代入によってコピーされることになります。これら以外のクラスのインスタンスは メモリの別の場所にあり、それを変数や定数が参照することになります。 即値と参照を参照してください。
トップレベル、クラス(モジュール)定義、メソッド定義のそれぞれで 独立したスコープになっています。ブロック内では、新たなスコープが 導入されるとともに、外側のローカル変数を参照できます。
ブロック内が特別になっているのは、Threadや手続きオブジェクトの
中でローカル変数を局所化できるようにするためです。
while
、until
、for
は制御構造であり、新しいスコープを
導入しません。
loop
はメソッドで、後ろについているのはブロックです。
Rubyスクリプトは、Rubyインタプリタに実行させようとすると、 まず最後まで一度読みこまれ、構文解析されます。構文上問題が生じなければ、 構文解析で作られた構文木が最初から実行に移されます。
ローカル変数が参照可能になるのは、この構文解析の時にローカル変数への 代入文が見つかった時です。
for i in 1..2 if i == 2 print a else a = 1 end end
test.rbというファイルにいれて、このスクリプトを実行すると、
test.rb:3: undefined local variable or method `a' for #<Object:0x40101f4c> (NameError) from test.rb:1:in `each' from test.rb:1
ということで、i
が1の時は、エラーが起こらず、i
が2になった時に
エラーが起こります。構文解析の時には、最初のprint a
が実際には
a
への代入が行われてから実行されるというところまで解析されず、
この文を構文解析する時までにa
への代入文が現われていないので、
ローカル変数は参照されません。実行時にはa
というメソッドが
ないか探しますが、これも定義されていないのでエラーになります。
逆に、次のスクリプトは、エラーになりません。
a = 1 if false; print a #=> nil
ローカル変数のこのような振舞いに悩まされないためには、ローカル変数が
参照される文より前に、a = nil
といった代入文を置くことがすすめられて
います。こうすると、ローカル変数の参照が速くなるというおまけもついて
います。
クラス/モジュールで定義された定数は、そのクラス/モジュールの中で 参照できます。
クラス/モジュール定義がネストしている場合には、内側のクラス/モジュール から外側の定数を参照できます。
またスーパークラス及びインクルードしたモジュールの定数を参照できます。
トップレベルで定義された定数は、Objectクラスに追加されますので、 すべてのクラス/モジュールから参照できます。
直接参照できない定数は、::
演算子を使って、クラス/モジュール名を
指定することにより参照できます。
実引数は、メソッド呼出しによって仮引数に代入されます。Rubyにおける 代入の意味は、変数への代入を 参照してください。 実引数が参照しているオブジェクトが、自分の状態を変更するメソッドを 持っている時には、副作用(それが主作用かもしれませんが)に注意する 必要があります。破壊的メソッド参照。
仮引数は、ローカル変数であり、仮引数に代入を行うと他のオブジェクトを 指すようになるだけで、元の実引数のオブジェクトには何の影響もありません。
仮引数の指すオブジェクトは、実引数の指しているオブジェクトですから、 そのメッセージによってオブジェクトの状態が変化する場合には、呼出し側に 影響が及ぶことになります。破壊的メソッド参照。
*
がついた引数は何ですかCウィザードのみなさん、これはポインタではありません。Rubyでは引数に
*
を付けることで、不定個の引数を配列に格納した形で受け取ることがで
きます。
def foo(*all) for e in all print e, " " end end foo(1, 2, 3) #=> 1 2 3
またメソッド呼び出しで*
を付けた配列を渡すと配列を展開して渡すこと
ができます。
a = [1, 2, 3] foo(*a)
現在、*
をつけることができるのは
case
のwhen
節の末尾だけです。(1)は
x, *y = [7, 8, 9]
のような形式で、この場合 x = 7
、y = [8, 9]
になり
ます。
x, = [7, 8, 9]
のような記述もでき、この場合、x = 7
で
x = [7, 8, 9]
なら、x = [7, 8, 9]
になります。
&
がついた引数は何ですか手続きオブジェクトをブロックとして受け渡しするための引数です。 引数列の一番最後に置きます。
できます。
しかもこのデフォルト値は関数の呼び出し時に評価されます。Rubyのデフォル ト値は任意の式が可能で(C++はコンパイル時に決まる定数のみ)、評価はメソッ ドのスコープで呼び出し時に行われます。
ブロックの先頭に、仮引数を||で囲って置くと、実引数が多重代入されます。 この仮引数は、普通のローカル変数で、ブロックの外側ですでに使われて いる変数の場合は、そのスコープになりますので、注意が必要です。
次のような例でしょうか。
A = a = b = "abc"; b << "d"; print a, " ", A #=> abcd abcd
変数や定数への代入は、オブジェクトを後でその変数や定数で参照する ために用いられます。変数や定数にオブジェクトそのものが代入されて いるのではなく、オブジェクトの参照を保持しているだけです。変数は、 この参照を変更して異なるオブジェクトを参照するようにすることが できますが、定数では一度保持した参照を変更することができません。
変数や定数にメソッドを適用すると、そのメソッドは、変数や定数が 指しているオブジェクトに適用されます。上の例では、<<というメソッドが オブジェクトの状態を変えてしまうために、「予期せぬ」結果が生まれて います。オブジェクトが数値の場合には、数値の状態を変えるメソッドが ないため、このような問題は生じません。数値にメソッドを適用した時には 新しいオブジェクトが返されます。
この例では、文字列で示しましたが、配列やハッシュなど、オブジェクトの 状態を変更するメソッドを持っているオブジェクトでも同様のことが起こり 得ます。
定数があるオブジェクトを指しているとき、別のオブジェクトを指すように すると、warningが出ます。
そのオブジェクトが破壊的メソッドを持っていれば、オブジェクトの内容は変更できます。
Proc.new
では手続きオブジェクトが作られませんがブロックや手続きオブジェクトを活用するメソッドをイテレータと呼びます。
イテレータは制御構造(特にループ)の抽象化のために用いられるメソッド の一種です。
といってもよくわかりませんね。実際の例を見た方が早いかもしれません。イ テレータはコレクションの各要素に対して同じ処理を繰り返したいような場合 によく使われます。例えばこんな感じです。
data = [1, 2, 3] data.each do |i| print i, "\n" end
このコードの出力はこのようになります。
$ ruby test.rb 1 2 3
つまりdo
とend
で囲まれたブロックが配列dataの各要素に対して繰
り返されるわけです。
これをCで書くと次のようになります。
int data[3] = {1, 2, 3}; int i; for (i = 0; i < 3; i++) { printf("%d\n", data[i]); }
このようにfor
を使って書く場合、境界条件の判定ミスでバグが生まれる
可能性がありますが(こんな単純な場合なら大丈夫でしょうが)、イテレータを
使えばそのような心配はありませんね:-)
また、do
...end
の代わりに{
...}
を使うこともできます。
data = [1, 2, 3] data.each { |i| print i, "\n" }
このコードは先の例と全く同じ動作をします。ただし、do
...end
と
{
...}
で動作が異なる場合があります。
foobar a, b do .. end # foobar がイテレータとして呼び出されます foobar a, b { .. } # b がイテレータとして呼び出されます
これは{ }
の方がdo
ブロックよりも結合強度が強いためです。
イテレータにブロックを渡すには、メソッドの後ろにブロックを置く 方法の他に、手続きオブジェクト(を指す変数、定数)の前に&を つけて引数として渡す方法があります。
メソッドの中からブロックを使用するには、yield
制御構造、ブロック引数、
Proc.new
の3種類の方法で行うことができます。( Cで書かれた拡張ライブラリ
の中では、rb_yield
が使われます。)
yield
の場合には、yield
の後ろに続く引数が、ブロック
パラメータとしてブロックに渡され、ブロックが実行されます。
ブロック引数は、メソッド定義の引数の最後に&method
という形で
置かれ、メソッドの中で、method.call(args...)
という形で呼ばれます。
Proc.new
は、メソッドの中で使われたときには、引数としてそのメソッドに
渡されたブロックをとり、そのブロックを内容とする手続きオブジェクトを
生成します。proc
またはlamda
も同様です。
def a (&b) yield b.call Proc.new.call proc.call lambda.call end a{print "test\n"}
Proc.new
では手続きオブジェクトが作られませんがProc.new
は、ブロックを与えられないと手続きオブジェクトを生成できず、
エラーになります。メソッド定義の中で
使われるブロックなしのProc.new
は、メソッド呼出しにブロックが与えられて
いることを仮定しています。
:exit
等の:
のついた識別子は何ですかloop
は制御構造ですかa +b
がエラーになりますがs = "x"; puts s *10
がエラーになりますがp {}
で何も表示されません'\1'
と'\\1'
はどう違いますかp true or true and false
はtrue
を表示するのに、a=true if true or true and false
では、a
にtrue
が代入されません。p(nil || "")
はなんでもないのに、 p(nil or "")
はパースエラーだと言われます:exit
等の:
のついた識別子は何ですかシンボルと呼ばれる、識別子と1対1対応するオブジェクトです *137。 "exit".internとしても求められます。catch, throw, autoloadなどでは、 引数として文字列もシンボルも使えます。
method_missing、method_added、singleton_method_addedはシンボルを 要求します。*138
symbol
のスコープでeval( (:symbol).id2name)
とすると、
値が取り出せます。
a = 'This is the content of "a"' b = eval(:a.id2name) a.id == b.id
loop
は制御構造ですかメソッドです。ブロックは新しいローカル変数のスコープを導入します。
a +b
がエラーになりますがa(+b)
と解析されています。+
の両側の空白をなくすか、いれるか
のどちらかにしてください。
s = "x"; puts s *10
がエラーになりますがputs s *10
のところが、s(*10)というメソッド呼出しと解析されて
しまいます。s*10
にするか、s * 10
にしてください。
p {}
で何も表示されません{}がハッシュのコンストラクタではなく、ブロックと解析されています。 p({}) か p Hash.new のようにして回避してください。
これは以下のような例です。
class C attr_reader :pos def pos=(n) @pos = n * 3 end def set pos = 1 #A end end a = C.new a.set p a.pos #=> nil (3 を期待していた)
最後の行で 3 を期待しても、実際には nil になります。
Ruby は A の行をローカル変数への代入と解釈するからです。
pos=() の呼びだしにするには self.pos = 1
としてください。
'\1'
と'\\1'
はどう違いますか同じです。シングルクォートの中では、\'
と\\
、行末の\
(改行を無効にします)だけが解釈され、それ以外は解釈されません。
p true or true and false
はtrue
を表示するのに、a=true if true or true and false
では、a
にtrue
が代入されません。最初の式は、(p true) or true and false
と解釈されます。
and/or
は
文の構成要素として解釈され、p
の引数を結ぶ演算子としては解釈され
ません。
2番目のは、a=true if (true or true and false)
と解釈されています。
if
の方がand/or
より優先順位が低いこと、
or
とand
の優先順位が同じなので、
左から順に解釈されることによります。
p(nil || "")
はなんでもないのに、 p(nil or "")
はパースエラーだと言われます|| は引数を結ぶことができますが、or は文と文を結ぶことしかできず、 引数を結ぶことができないからです。この違いは、たとえば以下のふたつの 式の結果がどうなるか試してみればわかります。
p nil || "" p nil or ""
+
や-
は演算子ですかprivate
とprotected
の違いが分かりませんsuper
がArgumentError
になりますが特異メソッド、自クラスで定義されたメソッド、スーパークラス(Mix-inされた
モジュールを含む。クラス名.ancestorsで表示される。)で定義されたメソッドの順に
最初に見つかったメソッドが実行されます。メソッドが見つからなかった
場合には、method_missing
が同じ順で捜されます。
Module Indexed def [](n) to_a[n] end end Class String include Indexed end p String.ancestors # [String, Indexed, Enumerable, Comparable, Object, Kernel] p "abcde".gsub!(/./, "\\&\n")[1]
は、残念ながら期待するように"b\n"を返してくれず、10を返してきます。 []がStringクラスで捜され、Indexedで定義されたものを捜し出す前に マッチしてしまうからです。Class Stringで直接[]を再定義すれば、 期待どおりになります。
+
や-
は演算子ですか+
や-
などは演算子ではなくメソッド呼び出しです。したがって
オーバーロードすることもできます。
class MyString < String def +(other) print super(other) end end
ただし、以下のもの及びこれらを組み合わせたもの(!=、!~)は制御構造であり、 オーバーロードできません。
=, .., ..., !, not, &&, and, |, or, ~, ::
単項演算子をオーバーロード(もしくは定義)するには、メソッド名として
+@
や-@
を使います。
=
は、インスタンス変数へのアクセスメソッドとして,
クラス定義の中で次のようにメソッドを定義することができます。
また、+
や-
なども定義することにより、+=
などの自己代入演算も可能になります。
def attribute=(val) @attribute = val end
Rubyにおいて関数のように見えるものはすべてレシーバ(self)を省略した形の メソッドです。例えば
def writeln(str) print(str, "\n") end writeln("Hello, World!")
のように一見関数のように見えるものも、Objectクラスに定義された
メソッドであり、隠されたレシーバーself
に送られているというわけです。
したがってRubyを純粋なオブジェクト指向言語と呼ぶことができます。
組込み関数のように、self
が何であっても同じ結果を返すメソッドは、
レシーバーを意識する必要がありませんので、関数と考えてもいいという
ことになります。
直接はできません。あらかじめそのオブジェクトにインスタンス変数を 参照するためのメソッド (アクセサと言います) を定義しておく必要が あります。たとえば以下のようにします。
class C def name @name end def name=(str) # name の後に空白を入れてはいけない! @name = str end end c = C.new c.name = 'やまだたろう' p c.name #=> "やまだたろう"
またこのような単純なメソッド定義は Module#attr
、attr_reader
、
attr_writer
、attr_accessor
などを使って簡潔に行うことができます。
たとえば上にあったクラス定義は以下のように書き直せます。
class C attr_accessor :name end
なんらかの理由でアクセスメソッドは作りたくないけれど参照はしたい場合は
Object#instance_eval
を使って参照することもできます。
private
とprotected
の違いが分かりませんprivate
の意味は、メソッドを関数形式でだけ呼び出せるようにし、
レシーバー形式では呼び出せないようにするという意味です。したがって、
可視性がprivate
なメソッドは、自クラス及びサブクラスからしか参照
できません。
protected
も同様に、自クラス及びサブクラスからしか参照できませんが、
関数形式でもレシーバー形式でも呼び出せます。
メソッドのカプセル化に必要な機能です。
インスタンス変数をpublicにすることはデータのカプセル化という観点から見
て好ましくありませんので、Rubyではインスタンス変数へのアクセスはアクセス
メソッドを使って行います。attr
メソッドを使うことで外部からみると
変数にアクセスしているかのように振舞わせることが可能です。
class Foo def initialize(str) @name = str end attr("name") # これはこういうことです。 # def name # return @name # end end foo = Foo.new("Tom") print foo.name, "\n" # Tom
attr(name, public)
で省略可能な二番目の引数にtrue
を指定するこ
とで書き込みメソッドを提供することも可能です。
class Foo def initialize(str) @name = str end attr("name", true) # これはこういうことです。 # def name # return @name # end # def name=(str) # @name = str # end end foo = Foo.new("Tom") foo.name = "Jim" print foo.name, "\n" # Jim
Module#attr_reader
, attr_writer
, attr_accessor
も
参照してください。
最初に断わっておくと、Rubyでは関数形式(レシーバを省略した形)でしか呼び 出すことのできないメソッドのことをprivateなメソッドと呼びます。ちょっ と変ってますね。
クラスのメソッドをprivateにすれば外部から呼び出すことができなくなりま す(ただしそのクラスのサブクラスからは呼び出すことができます)。クラス 内でしか呼び出すことのないメソッドはprivateにしておくとよいでしょう。
次のようにすればメソッドをprivateにすることができます。
class Foo def test print "hello\n" end private :test end foo = Foo.new foo.test #=> test.rb:9: private method `test' called for #<Foo:0x400f3eec>(Foo)
クラスメソッドをprivateにするにはprivate_class_method
を使います。
class Foo def Foo.test print "hello\n" end private_class_method :test end Foo.test #=> test.rb:8: private method `test' called for Foo(Class)
同様にpublic
、public_class_method
を用いることでメソッドを
publicにすることができます。
デフォルトでは、クラス内でのメソッド定義はinitializeを除いてpublic、 トップレベルではprivateになっています。
使えます。ただし、引数の無いメソッド呼出しに対して引数を括る()を省略できません。
super
がArgumentErrorになりますがメソッド定義中でsuper
と呼び出すと、引数がすべて渡されますので、
引数の数が合わないとArgumentErrorになります。異なる数の引数を
指定するには、super()
に引数を指定してやります。
super
は、1段上の同名のメソッドを呼び出します。それより上の同名の
メソッドを呼び出すには、あらかじめそのメソッドをaliasしておきます。
メソッド定義の中ではsuper
が使えます。再定義する前にalias
しておくと、元の定義が保たれます。
Kernelの特異メソッドとしても呼べます。
オブジェクトの内容を変更してしまうメソッドで、文字列や配列、ハッシュ などにあります。同名のメソッドがあって、一方はオブジェクトのコピーを 作って返し、もう一方は変更されたオブジェクトを返すようになっている場合、 !のついた方が破壊的メソッドです。String#concatのように!がつかない メソッドでも破壊的なものはあります。
実引数であるオブジェクトに対して、メソッドの中から破壊的メソッドを 適用した場合です.
def foo(str) str.sub!(/foo/, "baz") end obj = "foo" foo(obj) print obj #=> "baz"
この場合、引数となったオブジェクトが変更されています。でも、これは、プログラム の中で必要があって副作用のあるメッセージをオブジェクトに対し て送っているので当たり前です。
Rubyでは、メソッドの戻り値は一つしか指定できませんが、 配列を使うことによって、複数の戻り値を返すことができます。
return 1, 2, 3
とすると配列が返されます。つまり、
return [1, 2, 3]
とするのと同じです。
さらに多重代入を利用すると、複数の戻り値を戻すのとほとんど同じことがで きます。たとえば、
def foo return 20, 4, 17 end a, b, c = foo print "a:", a, "\n" #=> a:20 print "b:", b, "\n" #=> b:4 print "c:", c, "\n" #=> c:17
こんなことができるわけです。
load
とrequire
はどう違いますかinclude
とextend
はどう違いますかself
というのは何ですかMatchData
の begin
、end
は何を返しますか同じクラスを再定義すると、前のクラス定義に追加されていきます。 メソッドを再定義した場合には後のものが上書きしますので、前のものは 失われます。
1.6より実装されました。`@@'で始まる変数はクラス変数です。
class Foo @@F = 0 def foo @@F += 1 print @@F, "\n" end end
1.4以前までは定数に代入されたコンテナクラス(Array、Hashなど) がクラス変数の代わりに使用されていました。
class Foo F = [0] def foo F[0] += 1 print F[0], "\n" end end
class Foo @a = 123 # (1) def foo p @a # (2) ... 123でなくnilになる。 end end
(1)がクラスのインスタンス変数、(2)が通常のインスタンス変数です。(2)は
クラスFoo
のインスタンスに属するのに対し、(1)はFoo
というクラ
スオブジェクト(Classのインスタンス)に属します。
インスタンスメソッドからクラスのインスタンス変数に直接アクセスすること はできません。
上のように初期化されていないインスタンス変数とみなされ、nil
になり
ます。
特異メソッドは特定のインスタンスに固有のメソッドです。
こんな感じで使います。
foo = Foo.new def foo.hello print "Hello\n" end foo.hello
クラスにあるメソッドを追加したいが、わざわざサブクラスを作るほどのこと でもない、といった場合に有効です。
Javaをやってる人は匿名のインナークラスに似てると思うかもしれませんね。
クラスの特異メソッドをクラスメソッドと呼びます。特異メソッドは オブジェクトの固有のメソッドだと説明したばかりですが、Rubyには、 メタクラスという概念があり、すべてのクラスは、同名のメタクラスと いうものを持っていて、これは、Classクラスのインスタンスになって います。ここにクラスメソッドが定義されます。
形式的にはクラス名をレシーバーとして呼べるメソッドということに なります。
ClassのインスタンスであるFoo
の特異メソッドを考えてみま
しょう。
class Foo def Foo.test print "this is foo\n" end end
呼び出す時はこうです。
Foo.test
何か気付きませんか?
そう、これはいわゆるクラスメソッドですね。
もちろんClassで定義されているメソッドもクラスメソッドとして使えま す。
すでに特異メソッドについては 触れました。
簡単におさらいするとRubyではオブジェクト(インスタンス)に対してメソッド を追加することができるわけです。
この考えをもう少し進めるとクラスに対する他の操作をオブジェクトに対して も行えるようにしたくなってきませんか?
なってこないよ、と言わないで(^^;
これを可能にするのが特異クラスという機構です。
class Foo def hello print "hello.\n" end end foo = Foo.new foo.hello #=> hello. class << foo attr :name, true def hello print "hello. I'm ", @name, ".\n" end end foo.name = "Tom" foo.hello #=> hello. I'm Tom.
なんかすごいですよね。
ではここで問題。
Q. private_class_method
を使わずにクラスメソッドをprivateにするにはどうすればよいでしょう?
ヒント: クラスメソッドはクラスの特異メソッドでしたね。
ちょっとトリッキーですが、こんなふうにできます。
class Foo # ... end class << Foo def class_method print "class method\n" end private :class_method end Foo.class_method #=> Error
特異メソッドを定義するには、このように特異クラスで定義する方法と 直接 def obj.method という風に定義してしまう方法があります。
ちょっと性格は違いますが、モジュールでは、モジュール関数にする ことにより、特異メソッド(と同時にprivateメソッド)を定義する ことができます。
モジュールの特異メソッドとして、また同時にprivateメソッドして定義されて いるメソッドをRubyではモジュール関数と呼びます。例えば
Math.sqrt(2)
のように用いることも、
include Math sqrt(2)
のようにinclude
して用いることもでき、とても便利です。
あるメソッドをモジュール関数にするには、モジュール定義の中で
module_function :method_name
とします。
モジュールはインスタンスを作れません。 クラスはincludeすることができません。
モジュールは、クラス(モジュール)にincludeされることにより、多重継承に 相当するMix-inを実現します。これは直接の継承であるサブクラスとは 異なりますが、includeされたクラスは、モジュールとis_a?の関係を 持ちます。
前者では定数を直接参照することができます。後者ではクラス名をつけて参照 しなければなりません。
load
とrequire
はどう違いますかload
はRubyで書かれたソース(*.rb
)のみロードします。
require
は*.o
ファイルもロードします。さらに一度
require
したファイルは2度require
してもロードしません。
ロードパスも違います。
include
とextend
はどう違いますかinclude
はmodule
をクラス(モジュール)にインクルードして、
メソッドを関数形式で呼べるようにし、extend
は
module
をオブジェクト(インスタンス)にインクルードして、メソッドを
特異メソッドとして追加します。
self
というのは何ですかself
は、メソッドが適用されるオブジェクトそれ自身を表わします。
関数形式のメソッドは、self
をレシーバーとします。
begin
、end
は何を返しますか$~
に作用して、$0
、$1
などの元の文字列での開始位置、
終了位置を返します。タブ展開の例を参照
してください。
instance_methods(true)
は何を返しますかrand
がいつも同じ乱数列を出しますがFixnum
、true
、nil
、false
が即値だということですが、参照との違いは何ですかnil
とfalse
はどう違いますかless
に文字列を渡したのですが、表示されませんFile
オブジェクトはどうなりますかclose
しないのは気持ちが悪いのですがtrue
になります"abcd"[0]
は、何を返しますかsub
とsub!
はどう違うのですか..
と...
はどう違いますかthread
とfork
はどう使い分けるのですかtrap
はどのように使いますかinstance_methods(true)
は何を返しますかklass
.instance_methods は、あるクラス(またはモジュール)
klass
で定義されたインスタンスメソッドだけを返しますが、
klass
.instance_methods(true) は、
スーパークラスから引き継いだものも含めてすべてのインスタンスメソッドを返します。
(ただし、public メソッドのみ)
private_instance_methods、 protected_instance_methods の引数の意味も同様です。
rand
がいつも同じ乱数列を出しますがruby 1.4.2以前ではrand
は、プログラムが実行される度に同じ乱数列を生成します。
異なる乱数列を生成させるためには、srand
で毎回異なる乱数の
種を与えてやる必要があります。srandを引数なしで呼ぶと、その時の
時間を種にしますので、異なる乱数列を生成させることができます。
次のメソッドは、0からnまでの数の中からm個をランダムに選んだ配列を返します。
def sample(n, m) if m.zero? [] else s = sample(n-1, m-1) t = rand(n+1) s.concat s.include?(t) ? [n] : [t] end end
再帰形でなく書けば、次のとおりです。
def sample(n, m) s = [] ((n-m)...n).each do |j| t = rand(j+2) s.concat s.include?(t) ? [j+1] : [t] end s end
true
、nil
、false
が即値だということですが、参照との違いは何ですか特異メソッドを定義できないという制限があります。また、同じ数を 表わすFixnumのインスタンスは常に同じものになりますので、 インスタンス変数を定義した場合には、それも同じものを示すことに なります。
nil
とfalse
はどう違いますか持っているメソッドの違いは、nil.methods
- false.methods
と
false.methods
- nil.methods
を表示してください。
メソッドが真偽を返す時は、true
、false
を、そうでない
時は値かnil
を返すようにすることが好まれます。
?
のつくメソッドは、真偽を返すのが一般的ですが、
そうでないものもあります。
open("example", "r+").readlines.each_with_index{|l, i| l[0,0] = (i+1).to_s + ": "}
とやっても、example
に行番号がつきません。
ファイルを書き換えているのではなく、readlines
で読み込んだ文字列を
変えているだけです。ファイルに書き戻してやらなければいけません。
io = open("example", "r+") ary = io.readlines ary.each_with_index{|l, i| l[0,0] = (i+1).to_s + ": "} io.rewind io.print ary io.close
この例の場合、ファイルサイズは増える方向なので問題ないのですが ファイルサイズが小さくなるような変更に対しては
io.flush io.truncate(io.pos)
を io.close の直前に実行する必要があります。
コマンドラインオプションの-i
、もしくは、組込み変数$-i
に""を指定することにより、同じ名前のファイルに書き戻すことができます。
上の問題は、次のように書くことができます。
$ ruby -i -ne 'print "#$.: #$_"' example
元のファイルを残しておきたければ、-i.bak
などとしてください。
open('file', 'w').print "This is a file.\n" system 'cp file copy'
とやったのでは、コピーする時にfile
に内容がフラッシュされて
いません。きちんとclose
してからコピーしましょう。
f = open('file', 'w') f.print "This is a file.\n" f.close system "cp file copy"
less
に文字列を渡したのですが、表示されませんf = open '|less', 'w' f.print "abc\n"
とやっても、直ちに終了してしまい、less
で眺めることができません。
close
してやると、そこでless
の終了を待ちます。
f = open '|less', 'w' f.print "abc\n" f.close
最初の行は、f = IO.popen 'less', 'w'
としても同じ結果となります。
open("file").read
というように参照されないFile
オブジェクトは、次のガーベッジコレクションでclose
されて
捨てられます。
close
しないのは気持ちが悪いのですが参照されなくなったFileオブジェクトは、GCで自動的にクローズ されますが、明示的にクローズするには、次の3つの構文から選んで下さい。
a = open "file" begin a.each {|l| print l} ensure a.close end
IO.foreach("file") {|l| print l}
IO.readlines("file").each {|l| print l}
Dir.glob("*").collect{|f| [File.mtime(f), f]}. sort{|a,b| b[0]<=>a[0]}.collect{|e| e[1]}
とすると、カレントディレクトリの"."、".."以外のファイルを更新時間の 新しい順にソートした配列を返します。更新時間の古い順にソートする なら、sortの後ろのブロックはなしにしても、いいですね。
Dir.glob("*").sort{|a,b| File.mtime(b)<=>File.mtime(a)}
でもソートすることができますが、比較する度にファイルにアクセスして 更新時間を調べますので、ソートするのに時間がかかります。
この問題を解決するもう一つの方法に個々のファイルの更新時間を キャッシュするオブジェクトを用意する方法があります。
cache = {} def cache.mtime(x) self[x] ||= File.mtime(x) end Dir.glob("*").sort{|a,b| cache.mtime(b) <=> cache.mtime(a)} cache = nil
version 1.7 では、前者の例を簡単に実行するためのメソッド Enumerable#sort_by が追加されています。
Dir.glob("*").sort_by {|f| File.mtime(f)}.reverse
ハッシュのデフォルト値に0を指定して、次のようにすることができます。
freq = Hash.new(0) open("file").read.scan(/\w+/){|w| freq[w] += 1} freq.keys.sort.each {|k| print k, "--", freq[k], "\n"}
true
になりますRubyでは、nil
とfalse
だけが偽で、それ以外はすべて真に
なります。文字列が空かどうかを知るには、""と比較、empty?
を使う、
length
を0
と比較するなどの方法があります。
ary.collect{|f| [f.downcase, f]}.sort.collect{|e| e[1]}
とします。downcase
で等しくなった場合に、元の文字列で比較を行うのが
tipsです。
"abcd"[0]
は、何を返しますか文字aのコード97(Fixnum)を返します。これが文字aと一致するかどうか 調べるには、?aと比較します。
aに展開したい文字列があるとして、次のどれかを使えばいいでしょう。
1 while a.sub!(/(^[^\t]*)\t(\t*)/){$1+' '*(8-$1.size%8+8*$2.size)} 1 while a.sub!(/\t(\t*)/){' '*(8-$~.begin(0)%8+8*$1.size)} a.gsub!(/([^\t]{8})|([^\t]*)\t/n){[$+].pack("A8")}
Regexp.quote('\\')
で、エスケープされます。
gsub
を使う場合には、gsub(/\\/, '\\\\')
では、置換文字列が
構文解析で一度'\\'に変換され、実際に置き換えるときにもう一度'\'と
解釈されるので、
gsub(/\\/, '\\\\\\')
とする必要があります。\&がマッチ文字列を
あらわすことを使えば、gsub(/\\/,'\&\&')
と書けます。
gsub(/\\/){'\\\\'}
とブロックを使う形にすれば、エスケープが1回しか
解釈されませんので、求める結果が得られます。
sub
とsub!
はどう違うのですかsub
の場合はレシーバの状態は変化しません。文字列のコピーが
作られ、それに置換がほどこされて(置換が必要なければそのまま)返されます。
sub!
ではレシーバそのものが変更されます。変更がない時には
nil
が返されます。
sub!
のようにレシーバの状態を変化させるメソッドを
破壊的メソッドと
呼びます。Rubyでは同名のメソッドで破壊的なものとそうでないものがある場
合、破壊的なメソッドには慣例的に!
をつけます。
def foo(str) str = str.sub(/foo/, "baz") end obj = "foo" foo(obj) print obj #=> "foo" def foo(str) str = str.sub!(/foo/, "baz") end foo(obj) print obj #=> "baz"
sub!
のように破壊的なメソッドは予期しない効果をもたらすことがある
ので、使用する場合は十分注意してください。
\Zは、文字列の最後の文字が\nでない時は文字列の末尾に、 \nのときはこの改行の前にマッチします。
\n に関らず、文字列の最後にマッチさせたい場合は \z を使います。
..
と...
はどう違いますか..
は終端を含み、...
は終端を含みません。
Proc.new
、proc
、lambda
でProcオブジェクトを作れば、
関数ポインタのような働きをさせることができます。
また、MethodオブジェクトやUnboundMethodオブジェクトも関数 ポインタに近いものです。
thread
とfork
はどう使い分けるのですかthread
、fork
はそれぞれ以下のような特徴を持っています。
fork
は重い/thread
は軽いfork
はメモリ空間を共有しないfork
の切替えのタイミングは不正確/thread
はもっと不正確thread
ではスラッシングが起きないthread
はDOSでも動くthread
がなんらかの理由でブロックすると全体が止まる一般にfork
とthread
を混ぜるのはよくないようです。
あと、Rubyのthread
はタイムシェアリング方式なので、thread
を使
うことによって処理が速くなることはありません。
オブジェクトをファイルや文字列に格納しておき、後で再生できる ようにするものです。格納は
Marshal.dump obj, io, lev
という形式で行います。ioには書き込み可能なIOオブジェクト、levは オブジェクトが内容として他のオブジェクトを持っている時に、どこ までオブジェクトの内容を格納するかを決めます。lev段までオブジェクト をdumpしてもまだオブジェクトがある時には、そのオブジェクトのdumpは オブジェクトの参照になりますので、再生した時には、参照が変わって いるでしょうから、再生できないことになります。levのデフォルトは 100になっています。ioを省略した時には、文字列でdumpされます。
再生は
obj = Marshal.load io
または、
obj = Marshal.load str
という形式で、ioはdumpしたファイルを読み込み可能でopenしたもの、 strはdumpした文字列を指定します。
他の先進的な言語と同様にRubyも例外処理をサポートします。
begin (例外が発生しそうな処理) rescue (例外クラス) (例外が発生した場合の処理) else (例外が発生しなかった場合の処理) ensure (必ず実行したい処理) end
begin
節で例外が発生するとrescue
節が実行されます。
例外が発生しなければelse
が実行されます。
ensure
節は例外が発生してもしなくても必ず実行されます。rescue
,
else
,ensure
節はそれぞれ省略できます。
rescure
の後ろに例外クラスが
指定されなかった場合は
StandardErrorが指定されたものとみなされ、StandardErrorの
サブクラスである例外が捕捉されます。
この式の値は、ensure
節を実行する直前の値です。
もっとも最近起った例外はグローバル変数$!
により参照できます。
発生した例外の種類は$!.type
により調べることができます。
trap
はどのように使いますか以下により、シグナル SIGPIPE が発生するとブロックが実行されます (そして、例外が発生します)。
trap("PIPE") {raise "SIGPIPE"}
ファイルの最後にも改行があるものと仮定すれば、次の方法が一番簡単でしょう。
open("file").read.count("\n")
array という配列があった場合、
h = Hash[*array]
とすれば、array の奇数番目の値をキー、偶数番目の値を値とした h というハッシュが作られます。このとき array の要素は偶数個 でなければいけません。
array = [1,2,3,4] h = Hash[*array] p h => {1=>2, 3=>4}
なお、arrayの前の「*」は、メソッド呼び出しのところで紹介されている、 引数の展開用の記号です。
Arrayのように直接Hashを作るリテラルはありません。 そのかわり、
p h = Hash[*%w(1 foo 2 bar)] => {"1"=>"foo", "2"=>"bar"}
などと、いったんArrayを作るようにすれば、そこから簡単にHashを作れます。 (ただし、この場合ハッシュのキーと値は文字列に限定されます)
Tcl/Tk
のインターフェースはありますかirb というスクリプトがあります。
$ irb irb(main):001:0> 1 + 2 * 3 7 irb(main):002:0> if true irb(main):003:1> :true irb(main):004:1> else irb(main):005:1* :false irb(main):006:1> end :true irb(main):007:0>
のように使えます。
使い方の詳細は irb.rb を参照してください。
バイナリパッケージのrubyを利用している場合 irb は別パッケージになって いる可能性があります。各ディストリビューションの状況を調べてみてくださ い。
あります。Rubyを次のように起動してください。詳細は debug.rb を参 照してください。
ruby -r debug your_script
RubyはCで書かれています。さらに、Cで書かれたライブラリを Rubyで利用できるようにするための部品もととのっていますので、 Cで書かれたライブラリとRubyとの間のインターフェースを書くことに より、Rubyから使えるライブラリができます。
まず、Rubyのソースを展開したディレクトリにある、 ruby-src:ruby/README.EXT.ja を読んでみましょう。この文書はRuby そのものについて知るためにもよいドキュメントになっています。
次にext/ディレクトリの下にあるサブディレクトリを覗いてみると 実例が出てきます。ftpサイトのcontribにあるものも参考になる ことでしょう。
標準で添付されている拡張ライブラリに、Tcl/Tkのインターフェースが あります。一つは、ext/tcltk/以下のrequire "tcltk"で ロードされるインタ ーフェースで、TclスクリプトをRubyスクリプト中に埋め込むよ うな記述になります。
もう一つはext/tk/以下のrequire "tk"でロードされるインターフェースで、 こちらはよりRubyらしい記述でTkのGUIを実現することができます。
お使いのTkのバージョンが古い可能性があります。新しいものと交換してみて ください。
RAA:Ruby/GTK, RAA:Ruby/Forms を参照してください。
Timeオブジェクトは、1970年1月1日から2038年1月19日までしか表せま せん。標準添付ライブラリ date.rb を使ってください。 ruby-src:ruby/sample/cal.rb も参照してください。
基本的にドキュメントされてない機能はありません。 書いてないことがあればそれは記述洩れです。
-K
と $KCODE
の違いはなんですか?ruby 1.6以降、デフォルトで漢字コードを特別に解釈しなくなりました。 漢字を扱いたい場合は ruby -Ke などとして$KCODE を適切に設定しておく必要があります。
Windows 上で SJIS を使用している場合、ruby -Ksを、 UNIX 系 OS 上で EUC を使用している場合、ruby -Keを 指定する必要があります。
なお、スクリプトの先頭行に
#! ruby -Ks
などと書けばオプションの指定をスクリプトに埋め込むことができます。 これがもっとも無難でポピュラーな方法です。
-K
と $KCODE
の違いはなんですか?効果が及ぶタイミングが違います。
例えばSJISコードのファイルで以下のスクリプトがあった場合
$KCODE = 'SJIS' s = "表"
$KCODE に値を設定する段階ではスクリプトは解析された後です。文字列リテ ラルは($KCODE のデフォルトが "NONE" であるため)マルチバイトとして解釈 されていません。
オプション -K による漢字コードの指定ならばスクリプトを読む前に漢字コー ドが指定されるので、スクリプト解析の段階で漢字コードを認識します。
ちなみに漢字コードを含んだスクリプトで問題が発生する理由は「表」などの 文字がシフトJISコードでバックスラッシュ("\")と同じコードを含むからです。
-K オプションを正しく指定すれば、漢字で始まる変数名は英小文字に相当するもの として使えます。ポータビリティが低いのでおすすめできません。
Hash を使えば似たようなことができます、こちらの方がより安全と言えます。
var = {'変数' => '値'} var['変数'] = 1
$KCODE を設定した上で split(//) や scan(/./) を使います。
組込みの String#tr は、バイトごとに変換します。
require "jcode"
とすると、日本語を文字ごとに扱えます。
(jcode.rb を参照)
以下は、ひらがなの濁音、半濁音、拗音、撥音の文字を無視してソートを行う例です。 *141
require "jcode" a = "ぁぃぅぇぉがぎぐげござじずぜぞだぢづでど" \ "ばびぶべぼぱぴぷぺぽゃゅょっゎ" b = "あいうえおかきくけこさしすせそたちつてと" \ "はひふへほはひふへほやゆよつわ" ary = %w(ふー ばー ばず) p ary.sort p ary.collect{|l| [l.tr(a,b), l]}.sort.collect!{|e| e[1]} # => ["ばー", "ばず", "ふー"] # ["ばー", "ばず", "ふー"]
余談ですが、version 1.7 以降なら Enumerable#sort_by を 使って最後の行を
p ary.sort_by {|l| l.tr(a,b)}
と書けます。
正規表現で[あ-ん]というような範囲表現が使えますが、機種依存文字を直接 書くことはプログラムの可読性を損ないます。かといって
gsub(/[\x84\xbf-\x88\x9f]/s, ' ')
と書くことはできません。このような場合は以下のトリックを使うことで
gsub(Regexp.compile("[\x84\xbf-\x88\x9f]", nil, 's'), ' ') または gsub(/#{"[\x84\xbf-\x88\x9f]"}/s, ' ')
2バイトコードの範囲をうまく数値で表現して、空白に置き換えることができ ます。(余談ですが、このようなときには空白でなくゲタ("〓")に置き換えま すけどね)
標準ならば nkf.so ライブラリを使う方法と jcode.rb ライブラ リを使って変換を行う方法があります。あと RAA:Kakasi ライブラリな どでも可能です。
ruby-list:10505, ruby-list:25839, ruby-list:31238, ruby-list:31240, ruby-list:31508 などなど*142
Ruby はいわゆる半角カナを完全にはサポートしてません。
# 以下の例で "ア" は半角文字としてみてください ruby -Ks -e 'p "あア"' => "あ\261"
開発中の M17N版 ruby ではこのようなことにはならないそうです。
多バイト文字の切り出しでは、文字の泣き別れが問題になるのです が、これに対しては $KCODE を設定したとき /./ が、分断された 文字にマッチしないことを利用できます。
$KCODE = "e" p /./ =~ "あ"[0,1] # => nil # 注:漢字の要素になり得ない文字コードにはマッチします。 p /./ =~ "\xff" # => 0
以下は、文字列の左からたかだか len バイトまでを切り出すメソッ ド jleft のサンプルです。
class String def jleft(len) return "" if len <= 0 str = self[0,len] if /.\z/ !~ str str[-1,1] = '' end str end end $KCODE = 'e' s = "あいうえお" for i in -2 .. s.size+2 p [i, s.jleft(i)] end => [-2, ""] [-1, ""] [0, ""] [1, ""] [2, "あ"] [3, "あ"] [4, "あい"] [5, "あい"] [6, "あいう"] [7, "あいう"] [8, "あいうえ"] [9, "あいうえ"] [10, "あいうえお"] [11, "あいうえお"] [12, "あいうえお"]
もう一つ EUC コード限定で以下のような方法があります。
class String def jleft(len) return "" if len <= 0 str = self[0, len] if str.count("\xa1-\xfe") % 2 == 1 str[-1, 1] = '' end str end end
注:いずれも 3 バイト文字には対応してません。
NKF の -f
オプションが利用できます。
require 'nkf' p NKF.nkf("-ef11", "あいうえお、かきくけこ")
ただ、こちらは禁則処理やスペースの調整などを行ってくれて 賢すぎるので細かく制御できない場合があります。
自力でやるには 10.10 の方法を応用します。
class String def jfold(len) return "" if len <= 0 right = self.delete("\r\n") while right and not right.empty? left, right = right.unpack("a#{len} a*") if /.\z/ !~ left right[0,0] = left[-1,1] left[-1,1] = '' end yield left end end end "あいうえお、かきくけこ".jfold(11) {|s| puts s } # => あいうえお 、かきくけ こ
ただ、これは n バイト毎の folding です。TAB の桁位置を考慮し ていません。また、nkf に比べれば格段に遅いです。
RAA に、試験的に作成された x86 向けの Just In Time コンパイラが あります。ただしバージョン 1.5 用ですし、実用にもならないでしょう。
コンパイルしたい理由がソースコードの隠蔽なら、近いうちに進展が あるかもしれません。速度についてはかなり意欲的に改良が進んでいます。
JRuby( <URL:http://jruby.sf.net/> ) という処理系が現在開発されています。
現在のところありません。最初の一人を狙うのもいいですね。*143
これもありません。基本的に Ruby スクリプトの解析は非常に面倒です。 しかしユーザが増えればかなり実現可能性は高いでしょう。
ネイティブスレッドは、現在の GC (ガベージコレクション……自動メモリ回収) の実装と非常に相性が悪いため実現していません。またインタプリタおよび 基本ライブラリには C レベルでスレッドセーフでない部分がありますので その部分を洗いだして修正する必要もあります。
GC は現在の Ruby インタプリタの最大のボトルネックになりつつあるようで、 特に大規模なプログラムにおいては顕著です。これを解決するのが次の安定版 に向けての核となるでしょう。たとえば世代別 GC のような新アルゴリズムが 試験実装されたりしています。それまでの対処としては 1. 黙って耐える 2. 生成されるオブジェクトを減らす 3. 大量にオブジェクトを生成するのが わかっているならそのあいだだけ GC を止めておく……などが考えられます。
ただし通常のプログラムではそうそう GC の影響を受けることはありません。 安易に GC のせいにせず、どこが遅いのかちゃんと計測してみましょう。
MacOS X ならば .pkg フォーマットのRubyがRAAで公開されています。 MacOS 9 以前でも動いていたことは あるそうですが現在のバージョンは動いていません。消えゆく OS に積極的に 対応しようとする人もあまりいないのでは……。 ++
結合強度の話
Range オブジェクトのリテラル(あるいは範囲式)を表す ..
,
...
は結合強度(演算子式参照)が低いので、以下はエラーにな
ります
1..3.to_a => -:1: bad value for range (ArgumentError)
上記は、以下のように解釈されています。
1..(3.to_a)
範囲式は括弧で囲むのが無難です。
(1..3).to_a # => [1, 2, 3]
メソッド呼出のかっこ省略による誤解釈
上の例の続きで、以下は意図通りにはなりません
p (1..3).to_a => 1..3
これは以下のように解釈されます。
(p (1..3)).to_a
これは範囲式に限らず、メソッドの後に括弧があれば括弧の中身だけが引数 であると解釈されるためです。以下も同様です。
Time.gm (19+1)*100,2,11,12,34,56 => -:1: parse error Time.gm (19+1)*100,2,11,12,34,56 ^
このような場合は、引数全体を括弧で囲む必要があります。 *144
p ((1..3).to_a) => [1, 2, 3] Time.gm((19+1)*100,2,11,12,34,56) => Fri Feb 11 12:34:56 UTC 2000
メソッド呼出のかっこ省略による誤解釈(2)
以下のようなメソッド呼び出しと代入を含む式は parse error になります。
p obj = String.new "foo" => -:1: parse error
以下のようにする必要があります。
p obj = String.new("foo") p ((obj = String.new "foo"))
and/or の優先順位
p :a if true || false && false p :b if true or false and false #=> :a
&& が || よりも優先順位が高いのに対し、 and と or の優先順位が同じであることに注意。上記は以下のように解釈さ れています。
p :a if true || (false && false) p :b if (true or false) and false
式と文
p (true && true) #=> true p (true and true) #=> parse error p ((true and true)) #=> true
true and falseは文と解釈されるので式として解釈されるための括弧とpの 引数をくくる括弧が必要になります。
ruby-list:24664式を要求するコンテキストでは、以下のものが直接 は書けません。
do..end の parse error
(1..5).sort do |a,b| b <=> a end.reverse # parse error (1..5).sort() do |a,b| b <=> a end.reverse # [1,2,3,4,5]
ハッシュ引数
p {1=>2} #=> parse error (ブレースがブロックと解釈される) p ({1=>2}) #=> {1=>2} p (1=>2) #=> {1=>2} (引数がハッシュと解釈される) p (1=>2, 3) #=> parse error (ブレースを省略したハッシュが引数にかけるのは最後だけ) p (0,1=>2) #=> 0 1=>2
大文字で始まるメソッドの呼出し
大文字で始まるメソッドを :: 記法により呼び出す場合やレシーバを省略し て呼び出す場合、そのままでは定数と判断されるので注意が必要。()により メソッドコールであることを明示することで回避できる。
obj = Object def obj.Foo p "ok" end def Bar p "ok" end obj.Foo # => "ok" obj::Foo # => uninitialized constant Foo::Bar (NameError) obj::Foo() # => "ok" Bar # => uninitialized constant Foo::Bar (NameError) Bar() # => "ok"
空白に注意
a=1; b = a+2; # a と 2 の和 b = a +2; # a(+2) と解釈される. b = a + 2; # a と 2 の和
注:ブラウザや環境によって\が¥に見えます。
sub(gsub, sub!, gsub!)の引数
第一引数に文字列を渡すのは止めましょう
第一引数に文字列を渡すと
が順に行われ、混乱の元だからです。例えば
p "foo".sub!("\\w+", 'bar') # => "bar"
は、以下と同じです。
p "foo".sub!(/\w+/, 'bar') # => "bar"
シングルクォートを使っても
p "\\".sub!('\\', 'bar') # => "bar" => -:1:in `sub!': invalid regular expression; '\' can't be last character: /\/ (RegexpError)
などと混乱する場合があります。この例では正規表現 `\
' をコンパイル
しようとして失敗しています。以下が正解です。
p "\\".sub!(/\\/, 'bar') # => "bar"
第二引数に \1, \2 などを渡すのは慣れないうちは止めましょう
第二引数に文字列を渡すと
が順に行われ、混乱の元だからです。慣れないうちはブロックを使います。 (ブロックを使えば (2) は行われません)例えば
p "foo".sub!(/(\w+)/, "\\1bar") # => "foobar" p "foo".sub!(/(\w+)/, '\1bar') # => "foobar"
は、以下と同じです。
p "foo".sub!(/(\w+)/) { "#$1bar" } # => "foobar"
ブロックを使えば以下のようなこともできます。
p "foo".sub!(/(\w+)/) { "#$1bar".upcase } # => "FOOBAR"
ブロックを使わなければ sub! 実行前に upcase を行うので無効です。
p "foo".sub!(/(\w+)/, "\\1bar".upcase) # => "fooBAR"
第二引数はあくまでも短く書くためのものだと割り切った方が良いでしょ う。以下で何が行われてるのかヒト目でわかるような人は良いかも知れま せんが:p。
p "\\".sub!(/(\\)/, "\1") # => "\001" p "\\".sub!(/(\\)/, "\\1") # => "\\" p "\\".sub!(/(\\)/, "\\\1") # => "\\\001" p "\\".sub!(/(\\)/, "\\\\1") # => "\\1" p "\\".sub!(/(\\)/, "\\\\\1") # => "\\\001" p "\\".sub!(/(\\)/, "\\\\\\1") # => "\\\\" p "\\".sub!(/(\\)/, "\\\\\\\1") # => "\\\\\001" p "\\".sub!(/(\\)/, '\1') # => "\\" p "\\".sub!(/(\\)/, '\\1') # => "\\" p "\\".sub!(/(\\)/, '\\\1') # => "\\1" p "\\".sub!(/(\\)/, '\\\\1') # => "\\1" p "\\".sub!(/(\\)/, '\\\\\1') # => "\\\\" p "\\".sub!(/(\\)/, '\\\\\\1') # => "\\\\" p "\\".sub!(/(\\)/, '\\\\\\\1') # => "\\\\1"
この例で、メソッド p は `\
' を `\\
' と出力することにも
注意してください。
さらに、以下のようなことはできないことにも注意してください
p "foo".sub!(/(.*)/, "#{\\1}") # => -:1: compile error in string expansion (SyntaxError)
式展開 #{..}
の解釈はsub, gsub 実行前(引数解釈時)に行われます。こ
の時点では \1
は \1
のままです。やはりブロックを使うの
が正解です。
p "foo".sub!(/(.*)/) { "#$1" }
ローカル変数と等号付きメソッド
レシーバを省略するとメソッドではなくローカル変数として扱われます。 普通のメソッドはselfのレシーバを省略できますが、この場合は不可。
class Foo def bar=(v) end def baz bar = 0 # ローカル変数 bar への代入 self.bar = 0 # メソッド bar= の呼出し end end
制御構造(ifやwhileなど)はスコープを作らない。
while や for がスコープを作らないのに対し、loop や each などのイテレー タはスコープを作ります。
while true var = true break end p var # => true loop { var = true # このブロックの中でローカル break } p var # => -:5: undefined local variable or method `var' for #<Object:0x401a7b28> (NameError) for i in 1..3 var = true end p var # => true (1..3).each { var = true # このブロックの中でローカル } p var # => -:4: undefined local variable or method `var' for #<Object:0x401a7b28> (NameError)
多重ループを抜ける
重複したループを抜けるには、break
ではなく catch
/throw
を使用します。
catch(:last) { while true (1..5).each{|x| throw :last if x == 3 print "#{x}\n" } end }
ローカル変数は本当にローカル。Perl の my とかとは違う
# Ruby local = "hoge" def hoge print local, "\n" # 未定義。エラー end hoge # Perl my $local = "hoge"; sub hoge { print $local, "\n"; #=> hoge } hoge;
組込み関数
loadのように組み込み関数と同じ名前のメソッドを定義しているクラスで、 組み込み関数のloadを呼び出すにはKernel::をつけます。
class Hoge def call_load load "nosuchfile.rb" self.load "nosuchfile.rb" Kernel::load "nosuchfile.rb" end def load(arg) puts "Hoge#load #{arg}" end end Hoge.new.call_load # => Hoge#load nosuchfile.rb # Hoge#load nosuchfile.rb # LoadError: No such file to load -- nosuchfile.rb
[nil]
ではなく[]
となる。""
なのに、puts nil
や print nil
が nil
を表示する。16 進数文字列を 10 進数文字列に変換する
i = "f".hex print i, "->" ,format("%x",i)
oct の挙動
String#oct は文字列の形式により8進以外への変換を行う
p '0b10'.oct #=> 2 p '10'.oct #=> 8 p '010'.oct #=> 8 p '0x10'.oct #=> 16
String#hex は常に16進変換を行う
p '0b10'.hex #=> 2832 p '10'.hex #=> 16 p '010'.hex #=> 16 p '0x10'.hex #=> 16
配列への nil の挿入
a = [1,2,3] a[1,1] = nil # a[1.1] = nil.to_a を行っている p a # [1,3] a = [1,2,3] a[1,1] = [nil] p a # [1,nil,3]
これは、nil.to_a が [] (空の配列)を返すために起こります。 ちなみに nil.to_s は "" (空の文字列)を返します。
数値演算の誤差ruby-list:25173(Rubyに限らない)
(500.5 * 1).round #=> 501 (500 * 1.001).round #=> 500 printf "%10.20f\n", (500.5) #=> 500.50000000000000000000 printf "%10.20f\n", (500*1.001) #=> 500.49999999999994315658
変更しなかったときにnilを返す。
'a'.sub!(/a/,'b') #=> "b" 'b'.sub!(/a/,'b') #=> nil
破壊的メソッドの定義
class String def sample! self.replace('sample') # self = 'sample' # これは誤り end end
配列内の値の変換
a = [1,2,3] a.each{|item| item = item + 10} # 誤り a.collect!{|item| item + 10}
代入した時点で元の item (配列に格納されているもの)とは別の オブジェクトをさすためです。従って、
a = ['a','b','c'] a.each{|item| item.replace('x')}
など、破壊的メソッドは有効となります。
メソッド呼び出しで 配列を展開した変数列を渡す
def sum(a,b,c) print a+b+c,"\n" end a = [1,2,3] sum(*a) # -> sum(1,2,3) -> 6
同様にProcをブロックとして渡せる。
def foo yield(2) end pr = proc {|i| i*i} foo(&pr) #=> 4
逆に仮引数でまとめて受け取ったりProcとして受け取ったりできる。
def foo(*arg, &block) block.call arg[1] end foo(0,1,2) do |i| puts i #=> 1 end def test(*a) @b = [a] #正しくは、@b = a end def a = (b) #正しくは、a=(b) @a = b end
superとsuper(...)の違い。
class Foo def initialize end end class Bar < Foo def initialize(a) super end end obj = Bar.new(1) => -:8:in `initialize': wrong # of arguments(1 for 0) (ArgumentError)
上のはバグります。引数なしの super は上の例では super(a) と見なされ るからです。呼び出したメソッドと異なる引数で呼び出すには引数を明示し ます。
class Foo def initialize end end class Bar < Foo def initialize(a) super() # <- 0個 の引数であることを明示している end end obj = Bar.new(1)
Rubyの真偽値はつぎの通り。trueは真な値のうちの代表的な値である。0も偽じゃない。
以下の式の結果は、/foobar/ ではなく nil になります。*147 *148 *149 *150
nil || /foobar/ #=> nil
これは、「条件式に単体の正規表現リテラルだけを書くと$_との正規表現マッ チを行う」というルールがあるためです。つまり、上記の式は
nil || /foobar/ =~ $_
のように解釈されています。
これを避けるには現状
nil || Regexp.new("foobar")
のように単体の正規表現リテラルを書かないようにするしか方法がありません。
論理演算子式の項に現れた正規表現リテラルの特殊解釈はなくす方向で検討さ れていますruby-list:30836
Array.new([size[, val]])
初期値 val は、そのコピーで初期化するわけではないことに注 意してください。以下のようにすべての要素は同じオブジェクトを指し ます。
ary = Array.new(3, "foo") p ary # => ["foo", "foo", "foo"] ary.each {|v| p v.id} # => 537713734 537713734 537713734
したがって、このような配列の要素のうち1つを破壊的に変更すれば、 すべての要素が変更されます。
ary = Array.new(3, "foo") ary[0].replace "bar" p ary # => ["bar", "bar", "bar"]
これを避けるには例えば以下のようにします。
ary = Array.new(3).collect { "foo" } ary[0].replace "bar" p ary # => ["bar", "foo", "foo"]
ruby 1.7 feature: version 1.7 では、ブロックを指定することでこ れを避けることができます。
ary = Array.new(3) { "foo" } p ary # => ["foo", "foo", "foo"] ary.each {|v| p v.id} # => 537770556 537770436 537770424
self * times
Array.new と同様です。
ary = ["foo"] * 3 ary[0].replace "bar" p ary # => ["bar", "bar", "bar"]
Array#fill(val)
Array.new と同様です。
ary = Array.new(3).fill("foo") ary[0].replace "bar" p ary # => ["bar", "bar", "bar"]
ruby 1.7 feature: Array.new と同様、ブロックでこれを避けること ができます。
ary = Array.new(3).fill { "foo" } ary[0].replace "bar" p ary # => ["bar", "foo", "foo"]
Array#<=>
Arrayは<=>
メソッドを持っていますが、Comparableではありません。
(ruby-list:18470,ruby-dev:8261,ruby-dev:2173)
パス名を扱うメソッド(FileTestなど)はパス名の中に"\0"が含まれると その部分までをパスと見なしてしまいます。
path = "/etc\0garbage" p File.exists? path #=> true
これはおそらくそのようなチェックをRubyのソースに 埋め込むのが面倒だから(?)だと思います(邪推。 普通、こんなことしないしね。UNIXのパス名で"\0" はパス名の中に 含めることのできない数少ない文字の1つです 文責-あらい)
Hash.new([])は同じ[]を参照するので…。
Hash.new(val) は、ハッシュの default 属性に val を設定します。値が設 定されていないハッシュの参照はこの default 属性を返しているだけです。
h = Hash.new([]) h[0] << 0 h[1] << 1 p h #=> {} p h.default #=> [0, 1]
上記で、<< は default を破壊的に変更するだけで、h[0] などに影響を与 えません。+= などの破壊的でないメソッドで再代入する必要が有ります。
h = Hash.new([]) h[0] += [0] h[1] += [1] p h #=> {0=>[0], 1=>[1]} p h.default #=> []
また、このようなミスを防ぐためにも初期値は freeze しておくのが無難です。
h = Hash.new([].freeze) h[0] += [0] h[1] << 1 => -:3:in `<<': can't modify frozen array (TypeError)
File を open してほったらかしにするようなコーディングをしていると、たとえば SunOS 4.X みたいな変なシステムでびっくりできます。
stdio でファイルディスクリプタを char でもってる。だもんで、どんどんファイル開いていくと、そのうちファイルディスクリプタが負になってEBADF。
while str = File.open(name).read : end
で close を GC 任せにしたりせず、
while begin f = File.open(name) str = f.read ensure f.close end : end
とか
str = nil while File.open(name) { |f| str = f.read } : end
とか、close が保証されるようにしといた方が、無難。 *152
IO からの読み出しは毎回新たなオブジェクトを生成します。ふつうは平気ですが、意識していないとはた迷惑なプログラムが出来上がる場合があります。
400byte ほどのブロック二つを連結したものが別のバイナリファイルに入 ているかを調べるプログラムを作った時のこと。総ブロック数 400 個ほどを調べるのにスクリプトの中でループしてたら、たまにシステム全体が一分程固まったりして。メモリ足りないとはいえ、これは良くない。
必要に応じてruby-list:23467みたいなものを作る方が良いでしょう。もっと良いのはこんなことに ruby を使わないことかもしれないけど。
\wに日本語文字も含まれるが、$KCODEを適切に設定するか、 個別に指定する必要がある。 (\bは\wと\Wを表す幅0の正規表現。)
# euc-jpの環境の場合 /a\b/ === 'あaあ' #=> 2 /\ba/ === 'あaあ' #=> nil /\ba/e === 'あaあ' #=> nil /\ba/e === 'あaあ' #=> nil # Shift_JISの環境の場合 /a\b/ === 'あaあ' #=> 3 /\ba/ === 'あaあ' #=> nil /\ba/s === 'あaあ' #=> nil /\ba/s === 'あaあ' #=> nil
Regexp#eql?とRegexp#hashは定義されていない (Object#eql?とObject#hashが使われる)ので、 Hashのキーには向いていません。
//.eql? // #=> false
ある文字列を含む正規表現を作る場合には Regexp#quoteする必要があります。 *153
a = 'a.c' /^#{a}$/ === 'abc' #=> 0 (マッチした) /^#{Regexp.quote a}$/ === 'abc' #=> nil (マッチしない)
String.splitは最後の空文字列を削除するので…。
string = "" p string.split(//) #=> []
つねにStringが返るとは限りません。
最後の空文字列を取り除きたくない場合は、第2引数を指定します。
string = "" p string.split(//, -1) #=> [""]
ただし、この場合以下のようになることに注意。
string = "abc" p string.split(//, -1) #=> ["a", "b", "c", ""]
finalizer で Mutex は注意ruby-list:24697
finalizer で登録したブロックの中で、Mutex などで待ちに入るとデッドロックします。 理由はまだ自分で整理しきれてないのですが、おそらく、同じ Mutex を他でもロックしていると、そのロック中の GC で finalizerが 呼ばれてデッドロックするのかな、と思います。 weakref.rb みたいに Thread.critical を使う方が安全です。
以下の TCPServer の使用例では s2がThreadのブロック内で評価される前に、 whileのループでs2を更新してしまうことがあるため、期待した動作になら ない。正しい使い方に関してはTCPServerのスレッド版の例を参照。
s = TCPServer.new(11111) while(true) s2 = s.accept Thread.new do sleep 0.1 p s2 end end
rubyが出力するタイムゾーン文字列はOSの実装に依存しています。以下のよう な文字列を返すOSさえあります。 *154
$ ruby -e 'p Time.now' Mon Sep 04 17:32:11 東京 (標準時) 2000
また、カレントのタイムゾーンを返す実装も多く、Time.gmtime などの 効力が及ばない場合があります。
puts Time.now.gmtime.strftime("%H:%M %Z") #-> 06:09 GMT+9:00
OSによらずruby自身が"UTC"を出力する場合もあるのでさらに複雑です。 *155
$ ruby -e 'p Time.now.gmtime.zone' "GMT" $ ruby -e 'p Time.now.gmtime' Tue Jan 16 17:09:22 UTC 2001
これらの問題の影響を受けるメソッドには以下のものがあります。
gethostbyname で timeout できない
timeout は Thread で実現されているため、C レベルで停止してしまう (Threadの切替えが発生しない)処理に対しては効果がありません。
以下の例では、gethostbyname(およそ0.6秒処理に時間がかかっている) が終了し た直後((A)の箇所)で TimeoutError 例外があがっています。
require 'timeout' require 'socket' start = Time.now begin timeout(0.1) { p TCPSocket.gethostbyname("www.ruby-lang.org") # (A) } ensure p Time.now - start end => ["helium.ruby-lang.org", [], 2, "210.251.121.214"] 0.689331 /usr/local/lib/ruby/1.6/timeout.rb:37: execution expired (TimeoutError) from -:6:in `timeout' from -:6
Rubyでかかれたリゾルバを利用するという回避策があります。
require "resolve-replace"
すると、resolve.rb
で定義された、
リゾルバが利用されるようになります。
cygwin や mingw では以下もダメという報告があります。同じ理由かも知れ ません(本来、入力待ちの状態では入力を監視しつつThread切替えを行うので 大丈夫なはずなのですが)
require 'timeout' begin timeout(5) do $stdin.gets end rescue TimeoutError print "timeout\n" end
Ruby/Tk は、強力なオブジェクト指向スクリプト言語である Ruby と、 手軽に GUI プログラムを作成できる Tcl/Tk を組み合わせることで、 楽しく、プログラムをすることを目指したものです。
同じスクリプト言語といっても Ruby は Tcl よりかなり強力です。 Tk は使いたいけど、Tcl は使いたくない人にとって Ruby/Tk を使う意味は 大いにあるでしょう。
Ruby/Tk には以下のような利点があります。
Ruby/Tk には以下のような欠点があります。
Ruby/Tk には以下のような利点があります。
Ruby/Tk には以下のような欠点があります。
Tkの項目が参考になります。
菊谷さんのページ
近藤さんのページ
五十嵐さんのページ
江田さんのページ
高橋さんのページ
greenteaさんのページ。『入門 tcl/tk』のサンプルコードを Ruby/Tk のコードに変換しています。
Tcl/Tk の資料が利用できます。Tcl/Tk の文献は…
Perl/Tk の資料が利用できます。Perl/Tk の文献は…
まず、Tcl/Tk をシステムにインストールしてください。このとき、 コンパイルに必要なヘッダやライブラリもインストールするように してください(使用するバイナリパッケージによってはヘッダ等は 開発パッケージとして別にインストールする必要があるかも知れま せん)
注意として、現在の Ruby/Tk では、もはや Tcl/Tk のバージョン 8.0 より以前のものはメンテの対象になっていないことに注意して ください(動くかもしれませんけど)
ruby を build するときの configure のオプションに以下を含め てください(これらの指定はある程度自動検出されますが、Tcl/Tk のバージョンやインストール形態は様々なので、すべてに対応でき ていません)
./configure --with-tcllib=tcl8.3 \ --with-tklib=tk8.3 \ --with-tcl-include=/usr/include/tcl8.3 --with-X11-include=/usr/X11R6/include
--with-tcllib=XXX にはシステムに存在する libtclXXX.so や libtclXXX.a の tclXXX の部分を、
--with-tklib=XXX にはシステムに存在する libtkXXX.so や libtkXXX.a の tkXXX の部分を指定します。XXX の部分にはよく Tcl/Tk のバージョンを示す番号が付加されています。
--with-tcl-include=XXX には、tcl のヘッダファイルのあるパス を指定します。標準の /usr/include 等に置かれている場合には必 要ありません。もし、tk のヘッダファイルがこれとは別の場所に あるなら --with-tk-include=XXX も合わせて指定する必要があり ます。
tk のヘッダは X Window System のヘッダファイルを(たとえ、MS Windows 環境であっても)読もうとします。このヘッダが見つから ない場合は、--with-X11-include=XXX の XXX 部分に X のヘッダ ファイルのあるディレクトリを指定します。 (このため、Cygwin 環境で Ruby/Tk を使うには、XFree86 もイン ストールする必要があります。ただ、後述する bitWalk の Tcl/Tk パッケージには X のヘッダファイルが含まれているのでこの必要 はありません)
Tcl/Tk が Stub 機能を持つ場合(Tcl/Tk 8.1 以降)上記の代わりに 以下のように指定することを推奨します。
./configure --enable-tcltk_stubs \ --with-tcl-include=/usr/include/tcl8.3 \ --with-tcllib=tclstub83 \ --with-tklib=tkstub83 \ --with-X11-include=/usr/X11R6/include
--enable-tcltk_stubs により、Stub を使うことを明示します。
--with-tcllib=XXX にはシステムに存在する libtclstubXXX.so や libtcstublXXX.a の tclstubXXX の部分を、
--with-tklib=XXX にはシステムに存在する libtkstubXXX.so や libtkstubXXX.a の tkstubXXX の部分を指定します。
後は、いつものように
make make test make install
してください。
cygwin のデフォルトで入っているかもしれない tcl8.0 では Stub が使えず、 また日本語化がなされていません。
これを動作させるには、TCL_LIBRARY 環境変数を適切に設定する必要がありま す。この環境変数は Windows 形式のパスを指定する必要があります
$ export TCL_LIBRARY=`cygpath -w /usr/share/tcl8.0` $ ruby -Ks -rtk -e 'TkButton.new(nil, "text"=>"てすと") { command { puts "てすと" } }.pack' -e Tk.mainloop
以上のことから、Tcl/Tk 8.1 以降(国際化対応されています)のバイナリパッケージを別途 インストールすることを推奨します。
bitWalkの Tcl/Tkを使用する ruby を cygwin 環境で作成するには 以下のようにします。(上で説明してる「Ruby/Tk をソースからインストールするには...」 も参照してください)
(bitWalk の Tcl/Tk パッケージを d:\Tcl にインストールしたとする) $ cd ruby/ext/tcltklib $ ruby extconf.rb --with-{tcl,tk}-dir=/cygdrive/d/tcl \ --enable-tcltk_stubs \ --with-tcllib=tclstub83 \ --with-tklib=tkstub83 (configure 時に上記オプションを追加で指定しても良い) $ PATH=/cygdrive/d/Tcl/bin:$PATH (または) $ export RUBY_TCL_DLL=`cygpath -w /cygdrive/d/Tcl/bin/tcl83.dll` $ export RUBY_TK_DLL=`cygpath -w /cygdrive/d/Tcl/bin/tk83.dll` $ ruby -Ks -rtk -e 'TkButton.new(nil, "text"=>"てすと") { command { puts "てすと" } }.pack' -e Tk.mainloop
Ruby インストールガイドを参考にして下さい。
例えば、以下の組合せの場合
以下のようにすれば動作します
Cygwin 環境の ruby からのみ Tcl を使用する場合(必要なライブラリ、DLLをコピー)
普通に Tcl/Tk も使いたい場合
あるいは、
環境変数 RUBY_TCL_DLL, RUBY_TK_DLL を tcl83.dll, tk83.dll のあるパス に設定する(Windows 形式のパスで設定すること)
Windows から(autoexec.bat に設定するなど)
set RUBY_TCL_DLL=c:\Program Files\Tcl\bin\tcl83.dll set RUBY_TK_DLL=c:\Program Files\Tcl\bin\tk83.dll
Cygwin から(~/.bashrc に設定するなど)
export RUBY_TCL_DLL=`cygpath -w /cygdrive/c/Program\ Files/Tcl/bin/tcl83.dll` export RUBY_TK_DLL=`cygpath -w /cygdrive/c/Program\ Files/Tcl/bin/tk83.dll`
他の ruby スクリプトと同じように書き始めます。 例えば、
#!/usr/local/bin/ruby
とか。一番簡単な "こんにちは" を表示するスクリプトはこう書けます。
#!/usr/local/bin/ruby require "tk" TkLabel.new { text 'こんにちは' }.pack TkButton.new { text '終了' command 'exit' }.pack Tk.mainloop
別の書き方をすると、
#!/usr/local/bin/ruby require "tk" TkLabel.new { text 'こんにちは' pack } TkButton.new { text '終了' command 'exit' pack } Tk.mainloop
こんな風にも書けます。
#!/usr/local/bin/ruby require "tk" TkLabel.new (Tk.root, 'text' => 'こんにちは').pack TkButton.new (Tk.root, 'text' => '終了', 'command' => 'exit').pack Tk.mainloop
method= はほとんどない
setValue 形式もない?
ScrollBar と ListBox, Text, Canvas
what Tcl/Tk Ruby/Tk variable set a 123 a = 123 or a = '123' initialization re-assignment set b $a b = a.dup lists/arrays set a {1 2 fred 7.8} a = [1, 2, 'fred', 7.8] re-assignment list set b $a b = a.dup associative set a(Jan) 456.02 a = {'Jan' => 456.02, 'Feb' => 534.96} arrays set a(Feb) 534.96 re-assignment foreach i \ b = a.dup [array names a] { set b($i) = $a($i) } expressions set a [expr $b+$c] a = b + c increment incr i i += 1 declare proc plus {a b} { def plus(a, b) subroutines expr $a + $b } return a + b end variable scope local default local default override w/ "global" call plus 1 2 plus(1,2) subroutines statement sep newline or at ";" newline or at ";" statement "\" - newline none required continuation verbatim strings {} '' e.g. {a \ lot@ of $stuff} 'a \ lot@ of $stuff' escaped strings "" "" e.g. "Who\nWhat\nIdunno" "Who\nWhat\nIdunno" STDOUT puts "Hello World!" print "Hello!\n" puts stdout "Hello!" STDOUT.print "Hello World!\n"
what Perl/Tk Ruby/Tk variable $a = 123; or $a = '123'; a = 123 or a = '123' initialization re-assignment $b = $a; b = a.dup lists/arrays @a = (1,2,'fred',7.8); a = [1, 2, 'fred', 7.8] re-assignment @b = @a; b = a.dup associative %a = ('Jan',456.02, a = {'Jan' => 456.02, 'Feb' => 534.96} arrays 'Feb',534.96); re-assignment %b = %a; b = a.dup expressions $a = $b+$c; a = b + c increment $i++; or ++$i; i += 1 declare sub plus { my($a,$b) = @_; def plus(a, b) subroutines $a+$b; } return a + b end variable scope global default local default override w/ "my" (or "local") call &plus(1,2); #or plus(1,2) subroutines plus(1,2); #OK after sub plus statement sep ";" required newline or at ";" statement none required none required continuation verbatim strings '' '' e.g. 'a \ lot@ of $stuff' 'a \ lot@ of $stuff' escaped strings "" "" e.g. "Who\nWhat\nIdunno" "Who\nWhat\nIdunno" STDOUT print "Hello World!\n" print "Hello World!\n" STDOUT "Hello!\n" STDOUT.print "Hello World!\n"
EZWGL を扱うモジュールが 前田さんによって作られています。 現在ネットワーク上では手に入らないかも?
FLTK を扱うモジュールが立石さんによって作られています。 立石さんWebから手にいれることができます。
gtk を扱うモジュールが まつもと さんによって作られています。 現在は、五十嵐さんがメンテしています。Ruby/Gtkにあります。
XForms を扱うモジュールが立石さんによって作られています。 立石さんWebから手にいれることができます。
Athena widget や Motif を扱うモジュールが 前田さんによって作られています。 contrib/ にあります。
XView を扱うモジュールが 立石さんによって作られています。 立石さんWebから手にいれることができます。
Xlib を扱うモジュールが もりきゅうさんによって作られています。 Moriq Rubyから手にいれることができます。
現在発売されているRubyについての本は以下の通りです。(発売順)
本ドキュメントはフリーです。以下に示す条件で本ドキュメントを 再配布できます。
なお,本ドキュメントのオリジナル(2001年12月25日現在 <URL:http://www.ruby-lang.org/ja/doc.html> にあります)に対して加筆、 修正を行った場合、下記条件で再配布されることに同意したものと 見なされます。
以下の条件のいずれかを満たす時に本ドキュメントの内容を 変更したものを再配布できます。
*1あらい 2002-01-13: 本当は違う ruby-bugs-ja:PR#178
*2version 1.6 では、0.equal?(0.clone) が成立してしまいます
*3あらい 2002-01-13: 素数じゃなくていいのかな?
*4あらい 2002-01-13: 本当はこれを
更に内部のテーブルサイズで割った余りが使用されます。
あらい 2002-02-24: これは素数になりましたrubyist:1020
*5to_ary, to_hash, to_int, to_str は、説明の便宜上このページに書
いてますが、デフォルトでは Object
のメソッドとしては定義され
ていません
*6あらい 2002-02-20: 現在 1.6、1.7 共にこの制限
はありませんが、まだ流動的なようです ruby-bugs-ja:PR#98
*7status はどんな値になる?
*8あらい 2002-02-23: 終了する方法次第です。ここでは終了時の内部処理について触れてるのであしからず
*9ならば値に触れているページへのリンクがあると良いと思います
*10あらい 2002-02-23: ありますよ。exit とか abort とか書いてるで
しょー(^^)。例外については書いてないかもしれないですね。ちょっと
ソースを見てました。SystemExit による例外以外は終了ステータス 1
で終了します。SystemExit を明示的に raise したときは 0 です。こ
れ、意図されてるのかな?ソースからじゃなんとも判断つかないや
*11あらい 2002-02-23: 上記「終了処理」の対象ではありませんが、
オプション解析時には終了ステータス 2 で終
了(exit(3))することがあります(不正なオプション
指定)。スクリプトの parse error は、エラーの個数(だけど普通は 1。
1 以外を返すことはないかな?)で終了(exit(3))。
コマンドを実行できなかった子プロセスは 127 で終了
(_exit(2)) します(シェルと同じだ)。etc...
*12あらい 2001-10-14:
p (Thread.new { Thread.exit }.value)
は、false を表示します。Thread.exit や Thread#kill ではス
レッドの終了結果を設定していないためです
ruby-dev:14904
*13exit と同様 Thread の終了結果を設定しません
*14ruby 1.6 feature: version 1.6.5 までは self
を返し
ていました
*15ruby 1.6 feature: version 1.6.5 までは、終了処理中
(aborting)のスレッドに対しては "run" を返していました
*16exitとは少し違いがあります。ruby-dev:12785
*17小宮 : このレベルの特徴は?
*18 dellin: 2001/12/10追記 - Thu May 31 18:34:57 2001のCVS更新分より
*19小宮 : eval.c:5306近辺のつもり。あってます?。
*20より良い例があれば、書き換えてください。役に立つ。わかりやすい
が原則
*21 文字クラスの中では . や * はバックスラッシュでエスケープする
必要はありません。(しても構いません。)
*22あらい 2002-02-18: 調べてもいません。詳細を知りたい方は grep 等のマ
ニュアルを参照してください
*23ruby-list:28084 以下のスレッドも参照してください。
*24あらい 2002-01-24: 覚書: $KCODE の影響はほとんどの場合 String よりも
Regexp に対して。String に影響を与える部分として何がある
かを書くこと。「Shift_JIS の 2 バイト目に \ が含まれても正しく扱う」(←これは
Stringというより字句解析器)、
upcase, downcase, swapcase, capitalize, inspect, split, gsub, scan は、
$KCODE を設定すれば、日本語を意識して正しく処理する。(どのように影響
するか書くこと)
*25あらい 2002-01-24: inspect は、漢字をバックスラッシュ記法の8進で表
示するか、漢字で表示するかの違い。gsub, scan は、実装の都合で漢字を意
識しているのであくまでも Regexp が漢字を認識しているのだという理解で良
いと思う。split は、split('') の処理がバイト単位か文字単位かの違い。
もうちょい調べること
*26jcode はもう obsolete にしようよ……あおき
*27あらい 2002-01-13: 代替物がないからそれはないよね
*28あらい 2001-11-04 実際には引数に渡したオブジェクトをその
まま返してます(例を参照)。ただし、この挙動は将来代わる可能性
がありますruby-bugs-ja:PR#124
*29あらい 2002-01-14: 複製の方がいいよねえ
*30他にもruby-list:29297 などがあります
*31あらい 2002-01-14: 8 進だけは符号を許すのか。
p "-010".oct # => -8;
p "-0x10".oct # => 0;
p "-0b10".oct # => 0
*32あらい 2002-01-14: ここまで書く必要あり?どうしても混乱した記述
になるなあ。必殺の例示で逃げ
*33あらい 2002-01-14: String#to_f の現在の実装は
strtod(3) の呼び出しです。すべてのシステムで、ま
た将来にわたって例のとおりの動作になるかどうかは確認してません
*34あらい 2002-01-14: といっても、このメソッドを再定義しても、
Range#each の挙動は変わらない。あくまでも重要なのは
succの方
*35あらい 2002-01-14: "c" > "ba" であることに注意
*36ruby 1.6 feature: 将来(1.6.7 から)、0x などの prefix の直後な
どに指定することはできなくなります。また、_
を連続して書いてもエ
ラーになります。他、細かい部分でこのあたりの規則は見直され統一されまし
た。たぶん
*371=>2, 3=>4, 5=>6, 7=>8 は {1=>2, 3=>4, 5=>6, 7=>8} であるか {1=>2, 3=>4}, {5=>6, 7=>8} であるか曖昧だと思う
*38あらい 2002-02-03: その指摘はさすがに勘弁して欲しいのですが(そんな
こと言ったら brace 省略は到底無理ということになる)まあ、本文の定義が曖
昧なのは確かですね。
p (1,1=>2) # => ok
p (1=>2,3,4,5) # => error
p (1=>2,3,4=>5) # => error
p [1,1=>2] # => error
brace 省略したハッシュリテラルが許せる箇所が引数列の最後以外にもあった
気がしたのですが忘れました
*39処理の高速化のために内部で Hash を使用しているためです
*40 あらい 2002-01-06: このあたりの仕様はまだ流動的だと思い
ます。String#reverse! は、1文字の文字列に対しても self を返してい
ます
*41このマニュアルの分類では コマンド出力 `...`
は演算子ではありませんが説明の都合上再定義できる演算子の一覧にあげて
います
*42厳密にはruby-list:30574に
あるような違いがあります
*43 foo = 1, 2, 3
という書き方は 1.6.2 あたりから可能なようです。
おそらくブロックパラメータの受渡しとの対象性からかと思います
proc {|a| p a}.call(1,2,3) #=> [1,2,3]
*44ruby 1.7 feature: version 1.7 では 例外
ArgumentError が発生します
*45という説明は instance_eval と同じなのに、「つまり」
以降の内容が異なるのはなぜ?
*46あらい 2002-02-03: 実際にその部分が異なるからです。
クラスが self である位置はクラス定義文中ですが、その他のオブジェクトが
self である位置は普通はメソッド定義文中です。しかしメソッド定義文中では
メソッドを定義できませんから、厳密な記述ではありませんね。instance_eval
の「特異クラス定義文中に」というのはその点が考慮されてるのだと思います。
(というか、ソースからそこが違いだからというのが正解だろう^^)
あっ、でも特異クラス定義ではインスタンス変数が見えない(selfが特異クラス)
から instance_evalの記述はやっぱ間違いかな?
class Foo; def initialize; @foo = 1 end end
p Foo.new.instance_eval { @foo } # => 1
class <<Foo.new; p @foo end # => nil
考えるに instance_eval の記述から「つまり〜」以降ははずして、
「instance_eval でメソッドを定義すると self の特異メソッドが定義されます」
とか書けばよいかなあ? 2002-02-04 というように変更しました
rubyist:1074
*47あらい 2002-03-03: ruby 1.7 feature では、include を実行する
順序が変わったので each の代わりに reverse_each を使う
*48あらい 2002-02-14: この文いらないんじゃない?
特に「デフォルトの実装では」ってまるで再定義されることを意図した
メソッドの説明みたい
*49あらい 2002-01-12: self じゃないんだ
*50あらい 2002-01-13: 正確には、each できるためには繰り返される要素は
終端と <=
あるいは、<
メソッドで比較できる必要がある(なぜ
か <=>
ではない)。さらに、Numeric のサブクラスであれば
to_i
メソッドによりInteger のサブクラスにならなくてはなら
ず。これは、+ 1
(なぜか succ
ではない)を受け付けなくてはな
らない。また、===
で Range
オブジェクトの範囲内かどうかを
調べられるためには両端のオブジェクトが <=
, >
, >=
を
持たなくてはならない(なぜか <=>
ではない)。このマニュアルの記述
内容に反して <=>
メソッドを持つかどうかは Range
オブジェク
トを生成する際にチェックされるが直接は利用されない(Comparable 想
定しているのだろうか?)。この記述は、version 1.6.6 2002-01-11 のソース
を元に書いている。勘違いがあれば突っ込んで欲しい
*51あらい 2002-01-13: あっ、これもだ。この式が実行できなければ
size は動作しない
*52あらい 2002-01-13: もちろん Numeric のサブクラスであれば
item + s が動作しなければならない。それ以外では succ
を s 回実行する。つまり s は、整数でなければならない
*53にもかかわらずその値の説明が無い
*54あらい 2002-01-15: version 1.6 の場合、return, break, next, redo,
retry, while, until, class, module, def は値を返しません。BEGIN, END
もかな?値を返さない式を代入式の右辺に置くと parse error になります。
また、メソッド定義文の最後が値を返さない式である場合(return で抜けない
場合)、そのメソッドの戻り値は nil
です。このページに載っているも
ので値を返すものは if, if修飾式, unless, unless 修飾式, case, begin,
rescue 修飾式 です。これらは書いておきました。また、break, next による
戻り値の影響も書いておきました。version 1.7 ではまた違います。
ruby 1.7 feature参照
*55あるいは、突然エラーになってインタプリタが終了します。
retry #=> -:1: retry outside of rescue clause
*56あらい 2002-01-13: ensure は大域脱出を捕まえるので retry が (d)
に飛んでいるあまり良い例じゃないか
*57ruby 1.7 feature: 1.7 での例外の一致判定は
Module#=== を用いて行われます
*58あらい 2001-10-06 本当?
あらい 2002-01-15: どうやら、(1) eval() による評価で (2) def の中で END す
るとparse error のようです。よくわからない条件です
*59あらい:2001-04-02 version 1.6.0 から 1.6.2 までは
この結合強度の違いがなくなっていましたが、これはバグです。version 1.6.3 で修正
されました
*60 実際の応用例が
ruby-talk:10006,ruby-dev:12829にあります
*61あらい 2001-11-04: 実際には特定の組込み変数だけが
ここに書いた通りの挙動になる。version 1.7 ではこの制
限は取り除かれている
*62あらい 2002-02-22: 渡せる引数について詳細に触れること
*63あらい 2002-02-22: 渡せる引数について詳細に触れること
*64例えば、ファイルオープン中にファイルのサイズが小さ
くなってもその末尾に出力されます。このことはログ出力な
どでプログラムを実行したままそのログを小さくしたい場合
に利用されます
*65version 1.7
では第 2 引数によらず指定されれば有効になります
*66第一引数に IO を渡すインタフェースは obsolete と明言
されています(あらい 2002-01-07 どこで言ってたっけ?確か「デスクトッ
プリファレンスにはこのことは載ってなかったという話だったはず)
*67あらい 2002-01-07: IO#printfとは違う
*68Math.sqrt(-1)
はrequire 'complex'していたら発生しません。
*69というわけでもないのかな?
*70あらい 2002-01-07: 今のところ "unknown" を返すことはないはず。
もしそのようなことがあれば、バグ報告をした方が良いと思われる
*71stat
は、実際にはIOのメソッドです
*72あらい 2002-01-07 self の方がよくない?
*73あらい 2001-10-02: 「システム変数」と書いている場合もある、特殊性を
強調したい場合?記述の統一をする必要あり。ちなみにあらいは「特殊変数」と
いう用語を使っており、このマニュアルのいくつかにも書いてしまっている
*74この変数の利用は推奨されない obsolete を
参照
*75mswin32, mingw32 では、ruby.dll の置き場所から相対的に決まりま
す
*76デフォルトの順序は 1.6.5 から変更されました
*77執筆者募集: もっ
と詳細に。ruby-list:28178とか(一応、ドラフトはこれ
ruby-dev:14601)。現在の仕様は変更される可能性があります
*78あらい 2002-01-14: getpgid() は例外を発生させていません
p Process.getpgid(1000000) # => -1
*79あらい 2002-01-14: そして成功時の戻りは不定です(^^;
*80version 1.6 では nil
固定です
*81あらい 2002-01-06: 今のところ "unknown" を返すことはないはず。
もしそのようなことがあれば、バグ報告をした方が良いと思われる
*82あらい: 2001-02-19 aliasを使った方がよいのだろうな。。。
*83あらい 2002-01-14: self じゃないのか
*84あらい 2002-01-14: 他にないか調べること
*85ruby 1.6 以前は、これを
Module#append_feature を再定義すること
で実現していました
*86NaN は、p 0.0/0 #=> NaN
で得られます。Float参照
*87るびきち:未完成の部分あり
*88あらい 2001-09-25:いまいち^^;
*89るびきち:未完成の部分あり
*90るびきち:いい表現ない?
*91募集中
*92CozoH: このあたり、もっと正確で分かりやすい説明が欲しいです。私自身、よく分かっていないので。
*93[2001/03/09]るびきち:おっかしいなぁ
*94ruby-list:31275
*95参考:ruby-list:1174
*96後に解析
*97matrix.rbから英語のままとってきたので誰か訳してください。
*98matrix.rbから英語のままとってきたので誰か訳してください。
*99parsedate[23]とparsedateは同じ?違う?
*100あらい 2001-09-17: 接続を拒否され
ても true を返しているのでこの辺はうまく実装されてるのかもしれませ
ん。よくわかりません執筆者募集
*101るびきち:[2001/12/12]ここの部分ではまったので。
*102執筆者募集:一応書いただけなので適当に書き直してください。
*103具体的に動作に影響が出るメソッドの一覧を
*104より高レベルなものとしてRAA:Sockoptがあります
*105接続先の情報はaddrではなくpeeraddrです。注意。trap::Socket
*106あらい: recvfrom は、IPSocketに移動しました
*107あらい: recvfrom はIPSocketに移動しました
*1084つの
場合の3番目の引数ってなんだか変なインタフェースですね。4番目の引数
が nil の場合は要素3つと同じ扱いになるんですね。どういうわけでこう
なってるのかがよくわかりません。ホスト指定は常に3番目の要素にして
[アドレスファミリー, サービス, ホスト, フラグ] として4番目の要素で
名前解決うんぬんを指定するんじゃダメだったんでしょうかね?-あらい
2002-01-01
*109あらい: 2001-02-11
$DEBUGが真の場合、rubyインタプリタの方で abort_on_exception を true にした
ときと同じ動作にするので、この機能は必要ないのではないか?
*110あらい 2001-10-07: まだ理解できない、理解できないから書けない。
ruby-list:6735
*111あらい 2002-01-03: 全体的に記述が怪しいのですが間違ってて
も表に出さないと突っ込まれもしないのでコメントをはずしました。
このページ全文信じないように
*112ruby-list:14445 に例があります
*113waitの後に、mutexの解放を行っていませんでした。修正しておきます
*114執筆者募集
*115そのような
ものは実用レベルでは少ないのですが、例をあげると Socket などは
DNSの名前解決に時間がかかった場合割り込めません。
resolv-replace.rb を使用する必要があります
*116注: あらい 2002-01-13: ruby-list:33352 のパッチが必要です。
このパッチは 1.7 に取り込まれましたruby-list:33391
*117あらい: 2001-03-23 本当?
*118あらい: 2001-03-23 まだ試してない。あってるかな?
*119あらい: 2001-03-23 何か標準的な Win32API の例を書く
*120p (1, 2) とすると空白があっても引数を括る括弧になる
*121なんか、うまい書き方ないですかねえ?rubyist:0894
*122以下は 1.6 へ
*123あらい 2002-01-15: Enumerable#select との混同からあまり状況は変わ
らんなあといったとこですが。主観
*124拡張ライブラリによる別実装として、
RAAに
RAA:DOSishがあります
*125このBNFはまだ完全に1.6対応していません。執筆者募集
*126あおき: 簡単なとこだけ 1.6 対応しました
*127MLHS の規則が間違っている: MLHS_ITEM `,' `,' `*' というのが導出可能
*128あおき 2001-08-31: ワザとじゃないかって気もするけどなおしました。ついでに 1.6 の後置カンマ(a,)にも対応
*129 `_' は、Perl の真似だったようですが、Perl が途中で '!' に変えたため
Ruby ではこれら2つが残ったんだそうです
*130あらい: 2001-04-22 もっとちゃんと調べてから書こう。上記は信用
しないように:p 誰か代わりにしっかりしたのを書いてくれても良いです
ちなみに ISO 8825 です
*131C 言語とは異なり引数が 0 の場合にもプレフィックスが付加されます
*132`f', `e', `E', `g', `G' に関しては sprintf(3) の結果を利用しています。従って出力結果は実際にはシステムに依存することになります
*133動きます?
*134るびきち:追加。やっぱり最初につまづくのはインストールなんだろうね、たぶん。
*135ドキュメントも絶えず加筆、修正が行われています
*136カタツムリ(?)
*137version 1.4 以前はシンボルは整数(Fixnum)で実装されていました。現在はSymbolクラスのインスタンスです
*138あらい: 2001-05-19 というか、インタプリタからシンボルが
渡されます
*139この項目がこのページにあるのはおかしい気がする
*140この項がFAQなのは引数の意味が昔リファレンスに載っていなかったためです
*141あらい 2001-10-07: 例が悪かった(^^;
*142適当に誰かまとめてちょうだい執筆者募集
*143 NETRuby には触れるべきですか?
*144ruby 1.7 feature: version 1.7 では、メソッド名と
括弧の間に空白があると(おそらく)期待通りの動作をするよう
に変更されています
*145version 1.6以降では改善されました
*146version 1.6 以降、前者でもparse errorにならないよう改善されました
*147$_ に foobar が含まれていた場合は?
*148あらい 2001-10-07: 下でどう解釈されているか説明されてるから
わかりますよね?ダメ?あんまりくどいのも嫌でしょう?
*149実際の挙動はその解釈とは異なる
*150あらい 2001-10-07: ?ごめんもっとわかりやすく
*151あらい 2001-09-06: 1.6 では、\ に特別な意味はないのです。上記ではだめです。ruby-list:30949
*152あらい: 2001-01-21 version 1.7 以降なら str = File.read(name) とかでもok
*153セキュリティホールになる可能性もあるので十分注意してください。
*154Windowsで環境変数TZを設定していないときにこのようになることがあるようです。
*155 version 1.7では Time#zone は"UTC"
を返します
*156変