Title: オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル

version 1.6.7 対応
原著:まつもとゆきひろ

1 執筆者募集中

このリファレンスをよりよいものにするために 随時執筆者募集中です。あなたの参加を待ってます。

2 目次

Title: 執筆者募集

下の「Link」で参照されるページにRubyリファレンスマニュアルの記述が不完 全な部分が含まれています。

あなたの記述をみんな待ってます。よろしく。

RDというフォーマットで書きます。 RDとは何ぞやという人はWhat is RDを見てみましょう。

1 執筆の心得

  1. できるだけリンクを張る。(ただし同じ言葉に対してのリンクはうるさくなら ないように)
  2. 記述を追加したいが内容に関していまいち自信がなかったりする場合、以下の いずれかの方法で問い合わせる

その他雑多なことに関しては Manuals styleも参照してください。

作業中のページ

ToDo

Title: やること(やるかもしれないこと)

これらの課題や方針については rubyist ML で議論されています。

Title: (どなたかが)やったこと

Title: はじめに

Rubyは手軽なオブジェクト指向プログラミングのためのインタプリタ言語です。 Rubyは(Perlのような)テキスト処理やシステム管理のための豊富な機能を持っています。 また、Rubyは単純で、分かりやすく、簡単に拡張できます。

もし、簡単なオブジェクト指向のための言語を求めていたり、 Perlは見にくいと感じていたり、 Lispの考え方は好きだがあの括弧の多さには困ると感じているなら、 Rubyはまさにぴったりです。

Rubyの特長は次の通りです。

インタプリタ

Rubyはインタプリタ言語ですので プログラムを実行するためにコンパイルする必要はありません。

変数に型が無い (動的型付け)

Rubyの変数はどのような型のデータも格納する事ができますので、 変数の型について心配する必要はありません。 半面、コンパイル時のチェックは弱くなります。

変数宣言が不要

Rubyでは変数を宣言無しで使う事ができます。 変数の種類(ローカル変数、グローバル変数、インスタンス変数など)は 変数名から知る事ができます。

単純な文法

Rubyの文法はEiffelからわずかに影響を受けた単純なものです。

ユーザによるメモリ管理が不要

Rubyはメモリ管理を自動的に行います。 どこからもアクセスされなくなったオブジェクトは インタプリタに組込みのガーベージコレクタによって回収されます。

全てがオブジェクト

Rubyははじめから純粋なオブジェクト指向言語として設計されています。 整数のような基本的なデータ型をはじめとして、 全てのデータをオブジェクトとして統一的に取り扱えます。

クラス、継承、メソッド

Rubyは クラス、継承、メソッドのようなオブジェクト指向言語として基本的な機能は 当然持っています。

特異メソッド

ある特定のオブジェクトにメソッドを付加することができます。 たとえば、GUIのあるボタンを押された時の動作を メソッドとして記述するような使い方ができますし、 これを応用してプロトタイプベースの オブジェクト指向プログラミングも可能です(やりたければね)。

モジュールによるMix-in

Rubyは多重継承は複雑さの源であるという見地から、 意図的に多重継承を持っていませんが、 モジュールを使ってクラス階層を横断して実装を共有できます。 この機能を"Mix-in"と呼びます。

イテレータ

ループの抽象化を行うイテレータという機能があります。

クロージャ

手続きをオブジェクトとして扱う機能があります。 このオブジェクト化された手続きのことをクロージャと呼びます。

強力な文字列操作/正規表現

Perlをお手本とした強力な文字列操作や正規表現検索の機能があります。

多倍長整数

組込みの多倍長整数機能がありますので、 メモリが許す限り、非常に大きな整数の演算もできます。 たとえば、400の階乗なども簡単に計算できます。

例外処理機能

例外処理機能は例外的な状況への対処が簡単に書けます。

OSへの直接アクセス

Rubyは(UNIXの)ほとんどのシステムコールの呼び出し機能を持っています。 Rubyだけでシステムプログラミングも可能です。

ダイナミックローディング

OSが許せば、オブジェクトファイルを実行時に読み込む機能が提供されます。

Title: コマンドラインオプション

Rubyインタプリタは以下のコマンドラインオプションを受け付けま す。基本的にPerlのものと良く似ています。

ruby [ option ] ... [ -- ] [ programfile ] [ argument ] ...

Title: 環境変数

Rubyインタプリタは以下の環境変数を参照します。

RUBYOPT

Rubyインタプリタにデフォルトで渡すオプションを指定します。

RUBYPATH

-Sオプション指定時に、環境変数 PATHによるRubyスクリプトの探索に加えて、この環境変数で指 定したディレクトリも探索対象になります。(PATHの値よりも優 先します)。

RUBYLIB

Rubyライブラリの探索パス$:のデフォル ト値の前にこの環境変数の値を付け足します。

RUBYLIB_PREFIX

この環境変数は DJGPP版、Cygwin版、mswin32版、mingw32版のrubyでのみ有効 です。

この環境変数の値は、path1;path2 あるいは path1 path2 という形式で、 Rubyライブラリの探索パス$:の先頭部分 がpath1にマッチした場合に、これをpath2に置き換えます。

RUBYSHELL

この環境変数は OS2版、mswin32版、mingw32版のrubyでのみ有効 です。

system でコマンドを実行するときに使用するシェル を指定します。この環境変数が省略されていればCOMSPECの値を 使用します。

PATH

systemなどでコマンドを実行するときに検索するパスです。 設定されていないとき(nilのとき)は "/usr/local/bin:/usr/ucb:/usr/bin:/bin:." で検索されます。

Title: Object

全てのクラスのスーパークラス。 オブジェクトの一般的な振舞いを定義します。

1 インクルードしているモジュール:

2 メソッド:

self == other

selfother が等しいかどうか判定します。 デフォルトでは equal? と同じ効果です。

このメソッドは各クラスの性質に合わせて再定義するべきです。

self =~ other

古いタイプの正規表現比較 obj =~ /RE/ をサポートす るためのメソッドです。デフォルトは Object#== と同じ働きをします。 *1

self === other

このメソッドは case 文での比較に用いられます。デフォルトは Object#== と同じ働きをしますが、 この挙動はサブクラスで所属性のチェックを実現するため 適宜再定義されます。

class
type

レシーバのクラスを返します。

clone
dup

オブジェクトの複製を作ります。 clonefreezetaint、特異メソッドなどの情報も 含めた完全な複製を、dup はオブジェクトの内容のみの複製を 作ります。

clonedup は「浅い(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)

otherself 自身の時、真を返します。 このメソッドを再定義してはいけません。

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 を評価してその結果を返 します。 fnamelineno が与えられた場合は、ファイル 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 オブジェクトを返します。nameSymbol または文字列で指定します。

Module#instance_method も参照してください。

method_missing(name, args, ... )

呼びだされたメソッドが定義されていなかった時、Ruby がこのメソッド を呼び出します。呼び出しに失敗したメソッドの名前 (Symbol) とそ の時の引数が namearg ... に渡されます。

デフォルトではこのメソッドは例外 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 を持つとき真。 nameSymbol または文字列です。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

オブジェクトの文字列表現を返します。

printsprintf は文字列以外の オブジェクトが引数に渡された場合このメソッドを使って文字列に変換し ます。

to_str

オブジェクトの文字列への暗黙の変換が必要なときに呼ばれます。

untaint

オブジェクトの「汚染マーク」を取り除きます。汚染マークを取り 除くことによる危険性はプログラマが責任を負う必要があります。

セキュリティレベルが3以上の場合は例外 SecurityError を 発生します。

オブジェクトの汚染に関してはセキュリティモデルを参照してください。

3 プライベートメソッド:

initialize

ユーザ定義クラスのオブジェクト初期化メソッド。このメソッドは Class#new から新しく生成されたオブジェクトの初期化 のために呼び出されます。デフォルトの動作ではなにもしません。サブク ラスではこのメソッドを必要に応じて再定義されることが期待されていま す。initialize には Class#new に与えられた引 数がそのまま渡されます。

また initialize という名前を持つメソッドは自動的に private に 設定されます。

remove_instance_variable(name)

オブジェクトからインスタンス変数 name を取り除きます。 nameSymbol か文字列です。

オブジェクトがインスタンス変数 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)

ruby 1.7 feature

特異メソッドが 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)

ruby 1.7 feature

特異メソッドが 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 を使います。

Title: NameError

未定義のローカル変数や定数を使用したときに発生します。

1 スーパークラス:

Title: Proc

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 オブジェクトがイテレータブロックとして振舞う際の制 限です。

1 スーパークラス:

2 クラスメソッド:

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 と同じです。

3 メソッド:

self[arg ...]
call(arg ... )

手続きオブジェクトを実行してその結果を返します。引数はブロックの引 数にそのまま(多重代入のルールに従い)代入されます。

arity

Procオブジェクトの引数の数を返します。self が引数の数 を可変長で受け取れる場合

-(最低限必要な数+1)

を返します。

yield(arg ... )

ruby 1.7 feature

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]}

Title: Binding

ローカル変数のテーブルと self、モジュールのネストなどの情報を保 持するオブジェクトのクラス。組み込み関数 binding によっ てのみ生成され、eval の第 2 引数に使用します。

またトップレベルの Binding オブジェクトとして組み込み定数 TOPLEVEL_BINDING が用意されています。

1 スーパークラス:

Title: LocalJumpError

スコープを出てしまった Proc からの return, break, next, redo, retry で発生します。

Proc の例を参照してください。

1 スーパークラス:

2 メソッド

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

Title: NilClass

nil のクラス。偽変数(の値) nilNilClass クラスの 唯一のインスタンスです。nilfalse オブジェクトとともに 偽を表し、その他の全てのオブジェクトは真です。

1 スーパークラス:

2 メソッド:

self & other

常に false を返します。

self | other
self ^ other

other が真なら true を偽なら false を返します。

nil?

常に true を返します。

to_a

空の配列[]を返します。

to_i

0 を返します。

to_s

空文字列""を返します。

Title: TrueClass

true のクラス。trueTrueClass クラスの唯一のイン スタンスです。true は真を表す代表のオブジェクトです。

1 スーパークラス:

2 メソッド:

self & other

other が真なら true を偽なら false を返します。

self | other

常に true を返します。

self ^ other

other が真なら false を偽なら true を返します。

Title: FalseClass

false のクラス。falseFalseClass クラスの唯一のイ ンスタンスです。falsenil オブジェクトとともに偽を表し、 その他の全てのオブジェクトは真です。

1 スーパークラス:

2 メソッド:

self & other

常に false を返します。

self | other
self ^ other

other が真なら true を偽なら false を返します。

Title: Rubyの終了処理

Ruby はスクリプトの終端に達した場合や捕捉していない例外が発生した場 合に終了します(関数 exitabort 、メインスレッドに対する Thread.kill などは SystemExit 例外を発生させます)。終了時には以下 の処理が順に実行されます。

  1. すべてのスレッドを Thread.kill する
  2. Ruby の疑似シグナル SIGEXIT のハンドラが登録されていればそれを実 行する(trap を参照)。
  3. END ブロック(END { ... } または関数 at_exit で指定したブロック)が登録されていれば、 そのブロックを登録とは逆順に実行する。このブロックの実行中に発生 した大域脱出はそのブロックの処理を中断するが。スクリプトはまだ終 了しない。
  4. ObjectSpace.define_finalizer により、ファイナ ライザが登録されていればそれらを実行する(実行順序は不定)

    ファイナライザ実行中に発生した大域脱出はそのファイナライザの処理 を中断するが、スクリプトはまだ終了しない。

  5. exit(3) により終了する*7*8*9 *10 *11

ただし、関数 exit! による終了は、_exit(2) を実行するだけで、上記の処理はいずれも行われません。

Title: Thread

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#inspectThread#status によって見ることができます。

p Thread.new {sleep 1} # => #<Thread:0xa039de0 sleep>
run (実行or実行可能状態)

生成されたばかりのスレッドや runwakeup で起こされたスレッドはこの状態です。 join でスレッドの終了を待っているスレッドもスレッドの 終了によりこの状態になります。

この状態のスレッドは「生きて」います。

sleep (停止状態)

Thread.stopjoin により停止されたスレッ ドはこの状態になります。

この状態のスレッドは「生きて」います。

aborting (終了処理中)

kill 等で終了されるスレッドは一時的にこの状態になりま す。この状態から停止状態(stop)になることもあります。

この状態のスレッドはまだ「生きて」います。

dead (終了状態)

kill 等で終了したスレッドはこの状態になります。この状 態のスレッドはどこからも参照されていなければ GC によりメモリ上から なくなります。

この状態のスレッドは「死んで」います。

1 スーパークラス:

2 クラスメソッド:

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、拡張ライブラリがからむとこのフラグは無視さ れることもあります。排他制御を行うにはこのメソッドに頼らず MutexMonitor を使うべきです。

Thread.current

現在実行中のスレッド(カレントスレッド)を返します。

Thread.exit

カレントスレッドの実行を終了します。

カレントスレッドを返します。

*12

カレントスレッドが唯一のスレッドであるなら、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 を返します。

3 メソッド:

self[name]

name に対応したスレッドに固有のデータを取り出しま す。name は文字列か Symbol で指定します。

name に対応するスレッド固有データがなければ nil を返し ます。

self[name] = val

valname に対応するスレッド固有のデータとして格納し ます。name は文字列か Symbol で指定します。 valnil を指定するとそのスレッド固有データは削除さ れます。

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 を返します。

Title: Monitor

執筆者募集

Title: SystemExit

ruby を終了させます。*16

1 スーパークラス:

Title: メソッド:

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

Title: ObjectSpace

全てのオブジェクトを操作するためのモジュール。

1 モジュール関数:

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

これは、渡された procselfobj を参照しつ づけるため。そのオブジェクトが 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_modulekind_of? の関係にある全ての オブジェクトに対して繰り返します。引数が省略された時には全てのオブ ジェクトに対して繰り返します。

class_or_moduleFixnumSymbol を指定しても 何も繰り返しません。

繰り返した数を返します。

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 を使用してくださ い。

Title: manual page

foo(1)という記述はマニュアルページの参照を示します(Unixでの話)。

$ man 1 foo

などとして参照します。

数字はセクション番号を示します。例えば

などと分類わけされています。各セクションの意味は intro(1) などに 説明がありますのでそちらも参照してください。

環境によってはシステムコールがライブラリ関数として実装されている 場合もあるので socket(2)

$ man 2 socket

でなく

$ man 3 socket

の場合もあります。大抵セクションは省略して

$ man socket

として参照すれば良いでしょう。

詳細は man(1) を参照してください。

UNIX 環境を触れない人は

などを参照してください(この他にも情報があれば教えてください)。

Title: セキュリティモデル

RubyにはCGI等のプログラミングを安全に行うことを助ける為に、セキュリティ 機構が備わっています。

Rubyのセキュリティモデルは「オブジェクトの汚染」と「セーフレベル」という 仕組みによってなりたっています。

1 オブジェクトの汚染

Rubyではオブジェクトは「汚染されている」とみなされることがあります。この しくみは大きく分けて二つの使われ方をします。

ひとつ目は、信用できない入力をもとに作られたオブジェクトを「汚染されてい る」とみなし、「危険な操作」の引数として使えないようにすることです。悪意 あるデータによって、プログラムが意図しない動作をする事を防ぐことを目的と しています。

もうひとつは、信用しているオブジェクト(汚染されていないオブジェクト)を 信用できないプログラムから守るという使い方です。セーフレベル4で汚染されて いないオブジェクトへの操作が大幅に制限されるのはこの事を意図しています。

オブジェクトの汚染に関連するメソッド

Object#taint

オブジェクトを汚染する

Object#tainted?

オブジェクトが汚染されている場合に真を返す

Object#untaint

オブジェクトの汚染を取り除く

2 セーフレベル

各スレッドは固有の「セーフレベル」を持っています。セーフレベルが高くなるほ ど、行える操作は制限されます。セーフレベルはスレッドローカル変数$SAFEで 設定します。

$SAFEに関するルール

原則として、各セキュリティレベルにはそれ以下のセキュリティレベルの制限も 適用されます。たとえばレベル1で許されない操作はレベル2でも行えません。

2.1 レベル 0

デフォルトのセーフレベルです。

2.1.1 汚染されるオブジェクト

環境変数PATHだけは例外で、値に危険なパスを含む場合のみ汚染されます。

ここでは危険なパスとは誰でも変更/書き込みが可能なパスをいいます。
ルートディレクトリから階層が順番にチェックされ、一箇所でも誰でも
変更可能な個所があればそのパスは危険とみなされます。

2.1.2 禁止される操作

2.2 レベル 1

*17

2.2.1 汚染されるオブジェクト

2.2.2 禁止される操作

2.3 レベル 2

信用しているプログラムで信用できないデータを処理する為のレベルです。 CGI等でユーザからの入力を処理するのに適しています。

2.3.1 汚染されるオブジェクト

2.3.2 禁止される操作

レベル1の制限に加え、以下の操作が禁止されます。

2.4 レベル 3

生成される全てのオブジェクトが汚染されます。レベル4でプログラムを実行す る環境を作り上げるのに適しています。

2.4.1 汚染されるオブジェクト

2.4.2 禁止される操作

レベル2の制限に加え、以下の操作が禁止されます。

2.5 レベル 4

信用することのできないプログラムを実行するためのレベルです。

このレベルではレベル3では禁止されている「汚染された文字列のeval」が許可 されています。(evalで実行すると危険な操作は全て禁止されているからです。)

2.5.1 汚染されるオブジェクト

2.5.2 禁止される操作

レベル3の制限(上記のとおりevalは除く)に加え、以下の操作が禁止されます。

3 セーフレベルに関するその他の詳細

4 使用例

一端高くした$SAFEレベルを低く変更する事はできませんが、以下のようにスレッ ドを使うことで、プログラムの一部だけを高いセーフレベルで実行することが可 能です。

例:

def safe(level)
  result = nil
  Thread.start {
  $SAFE = level
  result = yield
  }.join
  result
end

safe(4) { puts "hello" }    # $SAFEなので例外
puts "world"                # 外側は影響を受けない

Title: SecurityError

セキュリティ上の問題が起きたときに発生します。 セキュリティモデル も参照してください。

1 スーパークラス:

Title: fatal

致命的なエラー(内部的なエラー)のときに発生します。 例えば:

などです。fatal というオブジェクトは通常の方法では見えません。

1 スーパークラス:

Title: 正規表現

以下は、ruby がサポートする正規表現記号の一覧です。

という規則があります。

以下の説明の中で「多バイト文字に対応した正規表現」とは、 $KCODE が設定されているか、あるいは明示的に漢字オプショ ン(正規表現リテラルを参照)を指定するなどで多バイト文字 にマッチする正規表現を指します。

1 後方参照

正規表現 \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

2 文字クラス

正規表現 [ ] は、文字クラス指定です。[] 内に列挙したいずれかの一 文字にマッチします。

例えば、/[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

3 バックトラック

*23

(?> ) という特殊な括弧で正規表現をかこむと、その括弧の中の表現に マッチした部分ではバックトラックが起こりません。その意味を例を挙げて 見てみます。

例えば通常の正規表現では

p /(a*)ab/ === 'aaab'

はマッチします。その過程は以下のようになります。

  1. 正規表現 a* がインデックス 0 で a みっつにマッチする
  2. 正規表現 a がマッチに失敗
  3. 正規表現 a* がマッチした分を少し「あきらめさせて」、 a ふたつにマッチさせる (バックトラックする)
  4. 正規表現 aa にマッチする
  5. 正規表現 bb にマッチする

しかしこの正規表現の括弧を (?> ) に変えるとマッチしなくなります。 その過程は以下のようになります。

  1. 正規表現 a* がインデックス 0 で a みっつにマッチする
  2. 正規表現 a がマッチに失敗
  3. a* がマッチした分をすこし減らして試したいが、 抑止指定されているのですぐに失敗する
  4. 正規表現 a* がインデックス 1 で a ふたつにマッチする

以下同じように失敗して、最終的にマッチ全体が失敗します。

ひらたく言うと、通常の正規表現の基本が「欲張りマッチ」なのに対して、 (?> ) は一回取ったものは絶対に離さない「超欲張りマッチ」を行います。

Title: String

文字列クラス。任意の長さのバイト列を扱うことができます。

このクラスのメソッドのうち名前が ! で終るものは文字列の中身を 直接変更します。このような場合は ! のついていない同じ名前の メソッドを使うほうが概して安全です。たとえば以下のような場合に問題に なることがあります。

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

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

String.new(string)

string と同じ内容の新しい文字列を作成して返します。

ruby 1.7 feature: 引数を省略した場合は空文字列を 生成して返します。

4 メソッド:

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]

selfsubstr を含む場合、一致した文字列を生成して 返します。 *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 を返します。 ただし firstlast のどちらかまたは両方が負の数 であるときは一度だけ文字列の長さを足して再試行します。

例:

'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 を指定した場合は、正規表現 regexpnth 番目の括弧にマッチする最初の部分文字列を文字列 val で置き換えます。nth が 0 の場合は、マッチした部分文字列全体 を val で置き換えます。

正規表現がマッチしない場合や nth に対応する括弧が なければ例外 IndexError が発生します。

self[first..last]=val
self[first...last]=val

first から last までの部分文字列を文字列 val で 置き換えます。

val を返します。

self <=> other

selfother を ASCII コード順で比較して、self が大きい時に正、等しい時に 0、小さい時に負の整数を返します。

変数 $= の値が真である時、比較は常にアルファベッ トの大文字小文字を無視して行われます。 ($=変数はいずれ廃止されることになっています obsolete を参照)

capitalize
capitalize!

先頭の文字を(アルファベットであれば)大文字に、残りを小文字に変更します。

capitalize は変更後の文字列を生成して返します。 capitalize!self を変更して返しますが、変更が起こら なかった場合は nil を返します。

p "foobar".capitalize   # => "Foobar"

$KCODE が適切に設定されていなければ、漢字コードの一部も変換 してしまいます(これは、ShiftJIS コードで起こり得ます)。 逆に、$KCODE を設定してもマルチバイト文字のアルファベット は処理しません。

# -*- Coding: shift_jis -*-
$KCODE ='n'
puts "帰".capitalize # => 蟻

upcase, downcase, swapcase も参照してください。

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のデフォルト値は変数$/の値です。

rsnil を指定した場合、このメソッドは何もしません。 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)

selfsalt から暗号化された文字列を生成して返します。 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 には区切りの文字列も含みます。

rsnil を指定すると行区切りなしとみなします。 空文字列 "" を指定すると連続する改行を行の区切りとみなします (パラグラフモード)。

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#upcasetr で書くと、

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

Title: Rubyの文法

Title: 字句構造

Rubyの現在の実装はASCIIキャラクタセットを用いています。アル ファベットの大文字と小文字は区別されます。識別子と一部のリテ ラルの途中を除いては任意の場所に空白文字やコメントを置くこと ができます。空白文字とはスペース、タブ、垂直タブ、バックスペー ス、キャリッジリターン、改ページです。改行は行が明らかに次の 行に継続する時だけ、空白文字として、それ以外では文の区切りと して解釈されます。

1 識別子

例:

foobar
ruby_is_simple

Rubyの識別子は英文字またはアンダースコア('_')か ら始まり、英文字、アンダースコア('_')または数字 からなります。識別子の長さに制限はありません。

2 コメント

例:

# this is a comment line

スクリプト言語の習慣にならい、文字列中や数値リテラル (?#)以外の#から行末までをコメント と見なします。

3 埋め込みドキュメント

例:

=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形式でドキュメントを埋め込むことを 期待しています。

4 予約語

予約語は以下のものです。

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 のあとやメソッド呼び出しの ピリオドのあとなどメソッド名であるとはっきり分かる場所では メソッド名として用いることができます。

Title: プログラム

プログラムはを並べたものです。式と式の間はセミコロ ン(;)または改行で区切ります。ただし、バックスラッシュに続く改行は文 の区切りにならず、次の行へ継続します。

例:

print "hello world!\n"

1

例:

true
(1+2)*3
foo()
if test then ok else ng end

式は括弧によってグルーピングすることができます。

2 プログラムの終り

Rubyインタプリタはプログラムを読みこんでいる際に以下のものに出あうとそこ で読みこみを終了します。

Title: 変数と定数

Ruby の変数と定数の種別は変数名の最初の一文字によって、 ローカル変数、 インスタンス変数、 クラス変数、 グローバル変数、 定数 のいずれかに区別されます。 通常の変数の二文字目以降は英数字または _ですが、システム変数の一部には 「`$'+1文字の記号」という変数があります(組込み変数を参照)。変数名 の長さにはメモリのサイズ以外の制限はありません。

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オプショ ンを指定すれば日本語文字の識別子も使用でき、それはローカル変数とみなさ れます。

2 インスタンス変数

例:

@foobar

`@'で始まる変数はインスタンス変数であり、特定の オブジェクトに所属しています。インスタンス変数はそのクラスま たはサブクラスのメソッドから参照できます。初期化されていない インスタンス変数を参照した時の値はnilです。

3 クラス変数

例:

class Foo
  @@foo = 1
  def bar
    puts @@foo
  end
end

@@で始まる変数はクラス変数です。クラス変数はクラス定義 の中で定義され、クラスの特異メソッド、インスタンスメソッドなどから参照/ 代入ができます。

クラス変数と定数の違いは以下の通りです。

クラス変数はクラス自身のインスタンス変数とは以下の点で異なります。

クラス変数は、そのクラスやサブクラス、それらのインスタンスで共有される グローバル変数であるとみなすことができます。

4 グローバル変数

例:

$foobar
$/

`$'で始まる変数はグローバル変数で、プログラムの どこからでも参照できます(その分、利用には注意が必要です)。 グローバル変数には宣言は必要ありません。 初期化されていないグローバル変数を参照した時の値は nilです。

5 疑似変数

通常の変数以外に疑似変数と呼ばれる特殊な変数があります。

self

現在のメソッドの実行主体

nil

NilClassクラスの唯一のインスタンス

true

TrueClassクラスの唯一のインスタンス。真の代表値

false

FalseClassクラスの唯一のインスタンス。nilとfalseは偽を表します。

__FILE__

現在のソースファイル名

__LINE__

現在のソースファイル中の行番号

疑似変数の値を変更することはできません。 擬似変数へ代入すると文法エラーになります。

6 定数

例:

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

6.1 定数参照の優先順位

親クラスとネストの外側のクラスで同名の定数が定義されているとネストの外 側の定数の方を先に参照します。つまり、定数参照時の定数の探索順序は、最 初にネスト関係を外側に向かって探索し、次に継承関係を上位に向かって探索 します。

例:

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

Title: リテラル

数字の1や文字列"hello world"のようにRubyのプログラムの中に直接 記述できる値の事をリテラルといいます。

1 数値リテラル

? 表現では全てのバックスラッシュ記法が有効です。

文字コード以外の数値リテラルには、`_' を含めることができます。 ruby インタプリタは `_' を単に無視し、特別な解釈は何もしません。 これは、大きな数値の桁数がひと目でわかるように記述するのに便利です。 リテラルの最初と、最後には _ を書くことはできません。(リテラルの 前(符号(+,-)の直後を含む)に _を置くとローカル変数やメソッド呼び 出しと解釈されます) *36

1_000_000_000  => 1000000000
0xffff_ffff  => 0xffffffff

2 文字列リテラル

例:

"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"

%記法 による別形式の文字列表現もあります。

2.1 バックスラッシュ記法

文字列式は評価されるたびに毎回新しい文字列オブジェクトを生成 します。

2.2 式展開

例:

($ruby = "RUBY"の場合)

   "my name is #{$ruby}" #=> "my name is RUBY"
   'my name is #{$ruby}' #=> "my name is #{$ruby}"

ダブルクォート(")で囲まれた文字列式、コマンド文 字列および正規表現、の中では#{式}という形式で式 の内容(を文字列化したもの)を埋め込むことができます。式が変数 記号($,@)で始まる変数の場合には {}を省略して、#変数名という形式で も展開できます。文字#に続く文字が {,$,@でなければ、その まま文字#として解釈されます。明示的に式展開を止 めるには#の前にバックスラッシュを置きます。

3 コマンド出力

例:

`date`
%x{ date }

バッククォート(`)で囲まれた文字列は、ダブルクォー トで囲まれた文字列と同様にバックスラッシュ記法 の解釈と式展開 が行なわれた後、コマンドとして実行され、その標準出力が文字列 として与えられます。コマンドは評価されるたびに実行されます。 コマンドの終了ステータスを得るには、$? を 参照します。

%記法 による別形式のコマンド出力もあります。

4 ヒアドキュメント (行指向文字列リテラル)

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

5 正規表現リテラル

例:

/^Ruby the OOPL/
/Ruby/i
/my name is #{myname}/o
%r|Ruby|

/で囲まれた文字列は正規表現です。正規表現として解釈される メタ文字については正規表現を参照してください。

終りの/の直後の文字は正規表現に対するオプションになります。 オプションの機能は以下の通りです。

Ruby は日本語化されているので、$KCODE の値に従って正 規表現中の日本語文字を正しく扱います。$KCODE = "n" の場合、日本 語文字を一切認識せずにバイト列として扱います。これはデフォルトの動作で す。

オプションとして n, e, s, u のいずれかを指定す ることで正規表現の文字コードを $KCODE の値に関係なく 個々の正規表現リテラルに指定することもできます。

%記法 による別形式の正規表現も指定できます。

正規表現の中では文字列と同じバックスラッシュ記法式展開も有効です。

6 配列式

例:

[1, 2, 3]
%w(a b c)

文法:

`[' 式`,' ... `]'

それぞれの式を評価した結果を含む配列を返します。 配列はArrayクラスのインスタンスです。

要素が文字列リテラルの場合に限り、%記法 による別形式の 配列表現も指定できます。

7 ハッシュ式

例:

{1=>2, 2=>4, 3=>6}

文法:

`{' 式 `=>' 式 `,' ... `}'
`{' 式 `,' 式 `,' ... `}'

それぞれの式を評価した結果をキーと値とするハッシュオブジェク トを返します。ハッシュとは任意のオブジェクトをキー(添字)として持 つ配列で、Hashクラスのインスタンスです。

ハッシュ式の要素が1つ以上あり、曖昧でなければ {, }は 省略しても構いません。この形式はメソッド呼び出しの引数でよく使われます。 *37 *38

例:

do_something('task'=>'resolve', 'timeout'=>10)

8 範囲オブジェクト

範囲式を参照

9 シンボル

例:

(シンボルの例)

      :class
      :lvar
      :method!
      :andthisis?
      :$gvar
      :@ivar
      :@@cvar
      :+

文法:

`:' 識別子
`:' 変数名
`:' 演算子

Symbolクラスのインスタンス。 ある文字列とSymbolオブジェクトは一対一に対応します。

Symbol リテラルに指定できる演算子はメソッドとして再定義できる演算子だ けです。演算子式 を参照して下さい。

10 %記法

文字列リテラルコマンド出力正規表現リテラル配列式 では、%で始まる形式の記法を用いることができます。 文字列や正規表現では、`"', `/' など(通常のリテラルの区切り文字)を要素 に含めたい場合にバックスラッシュの数をコードから減らす効果があります。 また配列式では文字列の配列を簡単に表現できます。それぞれ以下のように対 応します。

!の部分には改行を含めた任意の非英数字を使うことができます。始ま りの区切り文字が括弧(`(',`[',`{',`<')である時には、終りの区切り文字は 対応する括弧になります。括弧を区切り文字にした場合、対応が取れていれば 区切り文字と同じ括弧を要素に含めることができます。

%(()) => "()"

配列式の%記法はシングルクォートで囲んだ文字列を空白文字で分割したのと 同じです。たとえば、

%w(foo bar baz)

['foo', 'bar', 'baz']と等価です。

バックスラッシュを使って空白を要素に含むこともできます。

%w(foo\ bar baz)

=> ["foo bar", "baz"]

Title: Numeric

リテラルの符号は、単項演算子 `-', `+' のメソッド呼び出しでは ありません。

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

Title: Array

配列クラス。配列の要素は任意の Ruby オブジェクトです。 一般的には配列は配列式を使って

[1, 2, 3]

のように生成します。

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

4 メソッド:

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 番目)。lengthstart 番目からの配列の 長さより長い時には、越えた分の長さは無視されます。length が 負の時には nil を返します。

self[nth]=val

nth 番目の要素を val に設定します。nth が配列の 範囲を越える時には配列の長さを自動的に拡張し、拡張した領域を nil で初期化します。

val を返します。

self[start..end]=val

start 番目の要素から end 番目の要素までを配列 val の内容に置換します。val の値が配列でないときには val で置換します。val の要素の数の方が多い時には、後ろ の要素がずれます。

valnil か 空の配列 [] なら 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

selfother の内容を繋げた新しい配列を返します。 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

selfother の各要素をそれぞれ順に <=> で比較 して、self が大きい時に正、等しい時に 0、小さい時に負の整数 を返します。各要素が等しいまま、一方だけ配列の末尾に達した時は、よ り短い配列の方が小さいとみなします。

self == other

selfother の各要素をそれぞれ順に == で比較し て、全要素が等しければ真を返します。

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!

compactself から 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)

配列 otherself の末尾に(破壊的に)連結します。 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)

selfother の各要素をそれぞれ順に 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)。

ruby 1.7 feature:

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 ...])

ruby 1.7 feature

インデックス 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| ... }

ruby 1.7 feature

最初の形式では、引数で指定されたインデックスに対応する要素を配列で 返します。インデックスに対応する値がなければ 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 を返します。

push, pop, unshift も参照して ください。

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

self.join($,) と同じです。

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 を返します。

push, pop, shift も参照してく ださい。

例:

arr = [1,2,3]
arr.unshift 0
p arr             #=> [0, 1, 2, 3]
arr.unshift [0]
p arr             #=> [[0], 0, 1, 2, 3]

Title: Hash

ハッシュテーブル(連想配列とも呼ぶ)のクラス。ハッシュは任意の種類のオブ ジェクトから任意の種類のオブジェクトへの関連づけを行うことができます。 ハッシュ生成は以下のようなハッシュ式で行われます。

{a=>b, ... }

ハッシュの格納に用いられるハッシュ値の計算には、 Object#hash メソッドが使われ、キーの同一性判定には、 Object#eql? メソッドが使われます。

キーとして与えたオブジェクトの内容が変化し、メソッド hash の返す 値が変わるとハッシュから値が取り出せなくなりますから、ArrayHash などのインスタンスはキーに向きません。文字列をキーとして与 えると、文字列をコピーし、コピーを更新不可に設定(freeze)してキーとして 使用します。キーとして使われている文字列を更新しようとすると例外 TypeError が発生します。

1 スーパークラス:

2 インクルードされているモジュール:

3 クラスメソッド:

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)

4 メソッド:

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| ... }

keyvalue を引数としてブロックを評価した値が真であ る時、その要素を self から削除します。self を返します。

reject! は、要素を削除しなければ nil を返します。

each {|key, value| ... }
each_pair {|key, value| ... }

keyvalue を引数としてブロックを評価します。 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 の戻り値が使用 されます。 indexesindices と同じです。

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

ハッシュの全値の配列を返します。

Title: Symbol

シンボルを表すクラス。シンボルは任意の文字列と一対一に対応するオブジェ クトです。Ruby スクリプトからは

のようにして得られます。リテラルでシンボルを表す場合、`:' の後に は識別子、メソッド名(`!',`?' などの接尾辞を含む)、変数名 (`$'などの接頭辞を含む)、再定義できる演算子のいずれかに適合する ものしか書くことはできません(そうでなければ文法エラーになります)。

1 スーパークラス:

2 クラスメソッド:

Symbol.all_symbols

ruby 1.7 feature

定義済みの全てのシンボルオブジェクトの配列を返します。

p Symbol.all_symbols  # => [:RUBY_PLATFORM, :RUBY_VERSION, ...]

シンボルの生成はコンパイル時に行われるので以下のようにしても結果に 差はありません。

a = Symbol.all_symbols
:foo
b = Symbol.all_symbols
p b - a
# => []

3 メソッド:

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 に対応する整数は別のものです。

Title: 演算子式

例:

1+2*3/4

プログラミングの利便のために一部のメソッド呼び出しと制御構造は演算子形 式をとります。Rubyには以下にあげる演算子があります。

高い   ::
       []
       **
       -(単項)  +(単項)  !  ~
       *  /  %
       +  -
       << >>
       &
       |  ^
       > >=  < <=
       <=> ==  === !=  =~  !~
       &&
       ||
       ..  ...
       ?:(条件演算子)
       =(+=, -= ... )
       not
低い   and or

左の「高い」「低い」は演算子の優先順位です。 例えば「&&」は「||」より優先順位が高いので、以下のように 解釈されます。

a && b || c   #=> (a && b) || c
a || b && c   #=>  a || (b && c)

ほとんどの演算子は特別な形式のメソッド呼び出しですが、一部の ものは言語に組み込みで、再定義できません。

1 代入

例:

foo = bar
foo[0] = bar
foo.bar = baz

文法:

変数 '=' 式
定数 '=' 式
式`['expr..`]' '=' 式
式`.'識別子 '=' 式

代入式は変数などに値を設定するために用いられます。代入はロー カル変数や定数の宣言としても用いられます。代入式の左辺は以 下のいずれかでなければなりません。

1.1 自己代入

例:

foo += 12       # foo = foo + 12
a ||= 1         # a が偽か未定義ならば1を代入。初期化時のイディオムの一種。

文法:

式1 op= 式2     # 式1は通常の代入の左辺のいずれか

op は以下のいずれかです。演算子と=の間にスペースを 空けてはいけません。

+, -, *, /, %, **, &, |, ^, <<, >>, &&, ||

この形式の代入は 式1 = 式1 op 式2 と同様に評価されます。 ただし、式1は一度しか評価されません。*42

1.2 多重代入

例:

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]

*43

多重代入は括弧により、ネストした配列の要素を代入することもできます。

(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)

多重代入の値は配列に変換された右辺です。

2 範囲式

例:

1 .. 20
/first/  ...  /second/

文法:

式1 `..' 式2
式1 ` ... ' 式2

条件式以外の場所では式1から式2までの範囲オブジェクトを返しま す。範囲オブジェクトはRangeクラス のインスタンスです。 ... で生成された範囲オブジェクトは 終端を含みません。

条件式として範囲指定式が用いられた場合には、式1が真になるま では偽を返し、その後は式2が真を返すまでは真を返します。式2が 真になれば状態は偽に戻ります。..は式1が真になっ た時にすぐに式2を評価し(awkのように)、 ... は次の 評価まで式2を評価しません(sedのように)。

3 and

例:

test && set
test and set

文法:

式 `&&' 式
式 `and' 式

まず、左辺を評価して、結果が真であった場合には右辺も評価しま す。and は同じ働きをする優先順位の低い演算子です。

4 or

例:

demo || die
demo or die

文法:

式 `||' 式
式 or 式

まず左辺を評価して、結果が偽であった場合には右辺も評価します。 or は同じ働きをする優先順位の低い演算子です。

5 not

例:

! me
not me
i != you

文法:

`!' 式
not 式

式の値が真である時偽を、偽である時真を返します。

式 `!=' 式

!(式 == 式)と同じ。

式 `!~' 式

!(式 =~ 式)と同じ。

6 条件演算子

例:

obj == 1 ? foo : bar

文法:

式1 ? 式2 : 式3

式1の結果によって式2または式3を返します。

if 式1 then 式2 else 式3 end

とまったく同じです。

Title: Module

モジュールのクラス。

1 スーパークラス:

2 クラスメソッド:

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 が行います。

3 メソッド:

self <=> other

selfother を比較して、 selfother の子孫であるとき -1、 同一のクラス/モジュールのとき 0、 selfother の先祖であるとき 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

比較演算子。selfother の子孫である時、 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 文での比較に用いられます。 objselfObject#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 で指定される名前の定数が定義されている時真 を返します。nameSymbol か文字列で指定します。

autoload で指定された定数に対しては、selfObject である場合に限り、真を返します。

const_get(name)

モジュールに定義されている name で指定される名前の定数の値を 取り出します。定数が定義されていない時には例外 NameError が 発生します。 nameSymbol か文字列で指定します。

const_set(name, value)

モジュールに name で指定された名前の定数を value とい う値として定義します。そのモジュールにおいてすでにその名前の定数が 定義されている場合、警告メッセージが出力されます。 nameSymbol か文字列で指定します。

constants

そのモジュール(またはクラス)で定義されている定数名の配列を返 します。 スーパークラスやインクルードしているモジュールの定数も含みます。

Module.constantslocal_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 を返します。nameSymbol か文字 列です。

Object#method も参照してください。

method_defined?(name)

モジュールにインスタンスメソッド name が定義されているとき真 を返します。nameSymbol か文字列です。

module_eval(expr, [fname, [lineno=1]])
module_eval {|mod| .... }

モジュールのコンテキストで文字列 expr を評価してその結果を返 します。 fnamelineno が与えられた場合は、ファイル 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 を返します。

4 プライベートメソッド:

alias_method(new, old)

メソッドの別名を定義します。 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 を定義します。 nameSymbol か文字列で指定します。返り値は常に nil です。

このメソッドで定義されるアクセスメソッドの定義は次の通りです。

def name
  @name
end

省略可能な第 2 引数 assignable が指定されその値が真である 場合には、属性の書きこみ用メソッド name= も同時に定義されます。 その定義は次の通りです。

def name=(val)
  @name = val
end
attr_accessor(name, ... )

属性 name に対する読み込みメソッドと書きこみメソッドの両方を 定義します。nameSymbol か文字列で指定します。返り値 は常に nil です。

このメソッドで定義されるメソッドの定義は以下の通りです。

def name
  @name
end
def name=(val)
  @name = val
end
attr_reader(name, ... )

属性 name の読み出しメソッドを定義します。 nameSymbol か文字列で指定します。 返り値は常に nil です。

このメソッドで定義されるメソッドの定義は以下の通りです。

def name
  @name
end
attr_writer(name, ... )

属性 name への書き込みメソッド (name=) を定義します。 nameSymbol か文字列で指定します。返り値は常に nil です。

このメソッドで定義されるメソッドの定義は以下の通りです。

def name=(val)
  @name = val
end
define_method(name, method)
define_method(name) { ... }

インスタンスメソッド name を定義します。 method には ProcMethod あるいは 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>))

selfinclude されたときに対象のクラスまたはモジュー ルを引数にインタプリタから呼び出されます。

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 を返します。

Title: Range

範囲オブジェクトのクラス。範囲オブジェクトは範囲演算子 .. または ... によって生成されます。.. 演算子によって生成された範囲 オブジェクトは終端を含み、... 演算子によって生成された範囲オブジェ クトは終端を含みません。

例:

for i in 1..5
   ...
end

これは 1 から 5 までの範囲オブジェクトを生成して、それぞれの値に対して 繰り返すと言う意味です。

範囲演算子のオペランドは互いに <=> で比較できる必要があります。 さらに Range#each を実行するためには succ メソッ ドを実行できるものでなければいけません。 *50

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

Range.new(first,last[, exclude_end])

first から last までの範囲オブジェクトを生成して返しま す。exclude_end は終端を含むかどうかを指定します。省略時には 終端を含みます。

生成時に、引数の正当性チェックとして

first <=> last

を実行する。これが例外を返す場合、例外 ArgumentError を発生 させる。(ruby 1.7 feature: version 1.7 ではさらに first.succ を実行して例外が発生しないか確認する)

4 メソッド:

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| ... }

ruby 1.7 feature

範囲内の要素を s おきに繰り返します。 *52

("a" .. "f").step(2) {|v| p v}
# => "a"
     "c"
     "e"
to_ary

ruby 1.7 feature

to_a と同じです。範囲内の個々の値を要素とする配列 を返します。多重代入などで暗黙の型変換(配列化)が起こります。

a,b,c = (1..3)
p [a,b,c]    #=> [1, 2, 3]

Title: 制御構造

Rubyでは(Cなどとは異なり)制御構造は式であって、何らかの値を 持ちます。 *53 *54 RubyはC言語やPerlから引き継いだ制御構造を持ちますが、 その他にイテレータというループ抽象化の機 能があります。イテレータは繰り返しを始めとする制御構造をユー ザが定義する事が出来るものです.

1 条件分岐

1.1 if

例:

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 の条件式が正規表現のリテラルである時には

$_ =~ リテラル

であるかのように評価されます。

1.2 if 修飾子

例:

print "debug\n" if $DEBUG

文法:

式 if 式

右辺の条件が成立する時に、左辺の式を評価してその結果を返します。 条件が成立しなければ nil を返します。

1.3 unless

例:

unless baby?
  feed_meat
else
  feed_milk
end

文法:

unless 式 [then]
  式 ...
[else
  式 ... ]
end

unless は条件実行を行いますが、条件が if と反対で、条件が偽の時に実行を行います。unless 式に elsif を指定することはできません。

1.4 unless 修飾子

例:

print "stop\n" unless valid(passwd)

文法:

式 unless 式

右辺の条件が成立しない時に、左辺の式を評価してその結果を返します。 条件が成立しなければ nil を返します。

1.5 case

例:

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 を返します。

2 繰り返し

2.1 while

例:

while sunshine
  work()
end

文法:

while 式 [do]
   ...
end

式を評価した値が真の間、本体を繰り返して実行します。 while は、値を返しません。

2.2 while 修飾子

例:

sleep while idle

文法:

式 while 式

右辺の式を評価した値が真の間、左辺を繰り返して実行します。

左辺の式が begin である場合には、それを最低一度は 評価します。

例:

begin
  sleep
end while idle

while 修飾した式は値を返しません。

2.3 until

例:

until sunrise
  sleep
end

文法:

until 式 [do]
   ...
end

式を評価した値が真になるまで、本体を繰り返して実行します。 until は、値を返しません。

2.4 until修飾子

例:

work until tired

文法:

式 until 式

右辺の式を評価した値が真になるまで、左辺を繰り返して実行しま す。

左辺の式が begin である場合には、左辺を最低一度は 評価します。

例:

begin
  sleep
end until sunrise

until 修飾した式は値を返しません。

2.5 for

例:

for i in [1, 2, 3]
  print i*2, "\n"
end

文法:

for lhs ...  in 式 [do]
  式..
end

式を評価した結果のオブジェクトの各要素に対して本体を繰り返し て実行します。これは以下の式とほぼ等価です。

(式).each `{' `|' lhs..`|' 式.. `}'

「ほぼ」というのは、do ... endまたは{ }による ブロックは新しいローカル変数の有効範囲を導入するのに対し、 for文はローカル変数のスコープに影響を及ぼさない点が 異なるからです。

for は、in に指定したオブジェクトの each メソッドの戻り値を返します。

2.6 break

例:

i=0
while i<3
  print i, "\n"
  break
end

文法:

break

break はもっとも内側のループを脱出します。ルー プとは

のいずれかを指します。Cと違い、breakはループを 脱出する作用だけを持ち、case を抜ける作用は持ち ません。

break によりループを抜けた、for やイテレータは、nil を返します。

2.7 next

例:

next

文法:

next

nextはもっとも内側のループの次の繰り返しにジャンプします。 イテレータでは、yield 呼出し の脱出になります。

next により抜けた yield 式は nil を返します。

2.8 redo

例:

redo

文法:

redo

ループ条件のチェックを行なわず、現在の繰り返しをやり直します。

2.9 retry

例:

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)

*56

3 例外処理

3.1 raise

例:

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 モジュールで 定義されている関数的メソッドです。

3.2 begin

例:

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の組み込み例外は(SystemExitInterrupt のような脱出を目的としたものを除いて) StandardError のサブクラスです。

例外クラスのクラス階層については 例外クラス を参照してください。

rescue では error_type は通常の引数と同じように評価され、 そのいずれかが一致すれば本体が実行されます。error_type を評価し た値がクラスやモジュールでない場合には例外 TypeError が発生しま す。

省略可能な else 節は、本体の実行によって例外が発生しなかった場合 に評価されます。

ensure 節が存在する時は begin 式を終了する直前に必ず ensure 節の本体を評価します。

begin式が返す値は ensure が実行される直前に評価された式で す。

3.3 rescue修飾子

例:

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

4 その他

4.1 return

例:

return
return 12
return 1,2,3

文法:

return [式[`,' 式 ... ]]

式の値を戻り値としてメソッドの実行を終了します。式が2つ以上 与えられた時には、それらを要素とする配列をメソッドの戻り値と します。式が一つもない場合には nil が戻り値とな ります。

4.2 BEGIN

例:

BEGIN {
   ... 
}

文法:

BEGIN '{' 文.. '}'

初期化ルーチンを登録します。BEGIN直後の { }内部(BEGINブロック)で指定した文 は当該ファイルのどの文が実行されるより前に実行されます。複数 のBEGINが指定された場合には指定された順に実行さ れます。

BEGINブロックは独立したローカル変数のスコープを 導入するため、ローカル変数を外部と共有する事はありません。情 報の伝達にはグローバル変数を使う必要があります。

BEGINはトップレベルにしか置く事はできません。

4.3 END

例:

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"

Title: RuntimeError

実行時例外です。例外を指定しない raise の呼び出しはこ の例外を発生させます。

1 スーパークラス:

Title: Kernel

全てのクラスから参照できるメソッドを定義しているモジュール。 Object クラスはこのモジュールをインクルードしています。 組込み関数の項で解説されているメソッドはこのモジュールで定義され ています。

Object クラスのメソッドは実際にはこのモジュールで定義されていま す。これはトップレベルでのメソッドの再定義に対応するためです。

Title: StandardError

この例外クラスとそのサブクラスは、rescue節でクラ スを省略したときにも捕捉できます。

1 スーパークラス:

Title: Interrupt

trap されていない SIGINT を受け取ると発生します。 SIGINT 以外のシグナル受信による例外は SignalException を参 照してください。

1 スーパークラス:

Title: TypeError

不正な型を使用したときに発生します。

1 スーパークラス:

Title: メソッド呼出し

例:

foo.bar()
foo.bar
bar()
print "hello world\n"
print
Class::new

文法:

[式  `.'] 識別子 [`(' 式 ... [`*' [式]],[`&' 式] `)']
[式 `::'] 識別子 [`(' 式 ... [`*' [式]],[`&' 式] `)']

メソッド呼出し式はレシーバ(`.'の左側の式の値)の メソッドを呼び出します。レシーバが指定されない時はself のメソッドを呼び出します。

メソッド名には通常の識別子の他、識別子に?または !の続いたものが許されます。慣習として、述語(真 偽値を返すメソッド)には?を、同名の (!の無い)メソッドに比べてより破壊的な作用をもつ メソッド(例:trtr!)には !をつけるようになっています。

最後の引数の直前に*がついている場合、その引数の 値が展開されて渡されます。つまり:

foo(*[1,2,3])

foo(1,2,3)

と同じです。

最後の引数の直前に&がついている場合、その引 数で指定した手続きオブジェクトがブロックとしてメソッドに渡さ れます。

メソッド呼び出しの際、privateなメソッドは関数形式 (レシーバを省略した形式)でしか呼び出すことができません。 またprotectedなメソッドはselfがそのメソッド が定義されたのと同じクラス、またはそのサブクラスでなければ 呼び出せません。(呼び出し制限を参照)

1 super

例:

super
super(1,2,3)

文法:

super
super(式, ... )

superは現在のメソッドがオーバーライドしているメ ソッドを呼び出します。括弧と引数が省略された場合には現在のメソッド の引数がそのまま引き渡されます。

例:

def foo( arg )
  arg = 1
  super arg      # 1 を引数にして呼び出す
  super          # 5 を引数にして呼び出す
  super()        # 引数なしで呼び出す
end
foo 5

2 イテレータ

例:

[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

3 yield

例:

yield data

文法:

yield `(' [式 [`,' 式 ... ]] `)'
yield [式 [`,' 式 ... ]]

引数をブロックの引数として渡してブロックを評価します。 ブロック引数の代入は多重代入と同じルールで行われます。 またyieldを実行したメソッドにブロックが渡されていない (イテレータではない) 時は例外 LocalJumpError が発生します。 yield の値はブロックを評価した値です。

Title: クラス/メソッドの定義

1 クラス定義

例:

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") という形式が使われる

クラス定義式は値を返しません。

2 特異クラス定義

例:

class << obj
  def test
     :
  end
     :
end

文法:

class `<<' expr
  式..
end

クラス定義と同じ構文で特定のオブジェクトの機能を定義します。 この構文の内部で定義したメソッドや定数は指定したオブジェクト に対してだけ有効になります。

特異クラス定義式は、最後に評価した式の結果を返します。 最後に評価した式が値を返さない場合は nil を返します。

3 モジュール定義

例:

module Foo
  def test
     :
  end
     :
end

文法:

module 識別子
  式..
end

モジュールを定義します。モジュール名はアルファベットの大文字 で始まる識別子です。

モジュール定義は、識別子で指定した定数へのモジュールの代入に なります(Ruby では、モジュールもオブジェクトの一つで Moduleクラスのインスタンスです)。

モジュールが既に定義されいるとき、さらに同じモジュール名でモ ジュール定義を書くとモジュールの定義の追加になります。

モジュール定義式は値を返しません。

4 メソッド定義

例:

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節を 指定できます。

4.1 メソッドの評価

メソッドが呼び出されると、まず(必要ならば)引数のデフォルト式が 評価され、本体が評価され、メソッドレベルの rescue 節または else 節が評価され、最後に ensure 節が評価されます。 メソッド全体の戻り値は return に渡した値です。 return が呼び出されなかった場合は、本体/rescue/else の中で最後に評価した式の値です。その三つともすべてがカラだった 場合は nil になります。

またメソッドは定義する前に呼び出すことはできません。例えば

foo
def foo
  print "foo\n"
end

は未定義メソッドの呼び出しで例外 NameError を発生させます。

メソッド定義式自体は値を返しません。

5 特異メソッド定義

例:

def foo.test
  print "this is foo\n"
end

文法:

def 式 `.' 識別子 [`(' [引数 [`=' default]] ... [`,' `*' 引数 ]`)']
  式..
[rescue [error_type,..] [=> evar] [then]
  式..]..
[else
  式..]
[ensure
  式..]
end

特異メソッドとはクラスではなくある特定のオブジェクトに固有の メソッドです。特異メソッドの定義はネストできます。

クラスの特異メソッドはそのサブクラスにも継承されます。言い替 えればクラスの特異メソッドは他のオブジェクト指向システムにお けるクラスメソッドの働きをすることになります。

特異メソッド定義式は値を返しません。

6 クラスメソッドの定義

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 を参照して ください。

7 呼び出し制限

メソッドは publicprivateprotected の三通りの 呼び出し制限を持ちます。

public に設定されたメソッドは制限なしに呼び出せます。 private に設定されたメソッドは関数形式でしか呼び出せません。 protected に設定されたメソッドは、そのメソッドが定義された クラスおよびその下位クラスのインスタンスからしか呼び出せません。

デフォルトでは def 式がクラス定義の外にあれば private、 クラス定義の中にあれば public に定義します。これは Module#publicModule#privateModule#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

8 定義に関する操作

8.1 alias

例:

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 を返します。

8.2 undef

例:

undef bar

文法:

undef メソッド名[, メソッド名[, ...]]

メソッドの定義を取り消します。メソッド名には識別子そのもの か Symbol を指定します(obj.method のような式を書くことはできません)。 undef の引数はメソッド呼び出し等の一切の評価は行われません。

メソッドの定義内で定義を取り消すにはModuleクラスのメソッ ド Module#undef_method を利用して下 さい。

undef のより正確な動作は、メソッド名とメソッド定義との 関係を取り除き、そのメソッド名を特殊な定義と関連づけます。この状態の メソッドの呼び出しは例えスーパークラスに同名のメソッドがあっても例外 NameError を発生させます。 (一方、メソッド Module#remove_method は、関係を取 り除くだけです。この違いは重要です)。

aliasによる別名定義と undefによる定義取り消しによってクラスのインタフェー スをスーパークラスと独立に変更することができます。ただし、メ ソッドがselfにメッセージを送っている場合もあるので、よく注意 しないと既存のメソッドが動作しなくなる可能性があります。

undef 式は nil を返します。

8.3 defined?

例:

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? が返す値の一覧です。

Title: Class

クラスのクラス。より正確に言えば、個々のクラスはそれぞれメタクラスと呼 ばれる名前のないクラスをクラスとして持っていて、Class はそのメタ クラスのクラスです。この関係は少し複雑ですが、Ruby を利用するにあたっ ては特に重要ではありません。

クラスは、モジュールとは

という違いがありますが、それ以外のほとんどの機能は Module から継 承されています。Module のメソッドのうち

Class では未定義にされています。

1 スーパークラス:

2 クラスメソッド:

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 が行います。

3 メソッド:

new( ... )

クラスのインスタンスを作ります。このメソッドの引数はブロック引数も 含め initialize に渡されます。

superclass

クラスのスーパークラスを返します。

4 プライベートメソッド:

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"

Title: importenv.rb

require 'importenv'を加えるだけで環境変数をグローバル変数としてアクセスすることができるようになる。

1 使用例

require 'importenv'
p $USER              # => "rubikitch" (自分のユーザ名)
$USER = "matz"
p ENV["USER"]        # => "matz"
p $USER              # => "matz" (*)

1.1 注意

Ruby 1.6.2までは(*)の出力が自分のユーザ名になってしまうバグがあったが、それは1.6.3で修正されている。

Title: 組込み関数

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 を最初に参照した時に featurerequire するように設定します。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 では以下の点で違いがあります。

chomp([rs])
chomp!([rs])

システム変数 $_rs で指定される末尾 の文字列を取り除いたものにします。 chomp! は文字列そのものを変更しその結果を返しますが、 取り除く文字列がなければ nil を返します。 rs のデフォルト値は $/ です。

詳細は String#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

fnamelineno が与えられた場合には、ファイル 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 の デフォルト値はシステム変数 $/ の値です。読み込 んだ文字列はシステム変数 $_ にもセットされます。

rsnil を指定すると行区切りなしとみなしてファイルの内容を すべて読み込みます。 空文字列 "" を指定すると連続する改行を行の区切りとみなします (パラグラフモード)。

readlinegets と同じ働きをしますが、 ファイルの最後まで読むと例外 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 では以下の点で違いがあります。

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 引数 permopen(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 を呼び出します。

maxnil または 0 を指定すると 0 以上 1 未 満の実数値 Float で乱数を与えます。

readlines([rs])

コマンドライン引数として与えられたファイル(なければ標準入力) をつ なげた仮想的なファイル(ARGFを全て読み込んで、その 各行を要素としてもつ配列を返します。

行の区切りは引数 rs で指定した文字列になります。rs の デフォルト値はシステム変数 $/ の値です。

rsnil を指定すると行区切りなしとみなします。 空文字列 "" を指定すると連続する改行を行の区切りとみなします (パラグラフモード)。

require(feature)

Ruby ライブラリ feature をロードパス $: 上 から探し、同じライブラリがまだロードされていなかった時だけロードし ます。

Ruby ライブラリとは Ruby スクリプト (*.rb) か拡張ライブラリ (*.so) であり、feature の拡張子が省略された場合はその 両方から探します(検索順序に関しては $: を参照して ください)。省略されなかった場合は指定された種別のみを探します。ま た拡張ライブラリの拡張子にはアーキテクチャで実際に使われる拡張子に 関らず常に .so を用います。

実際にライブラリをロードした時には true、既にロードされてい る時には false を返します。ロードに失敗した場合は、例外 LoadError が発生します。ロードした feature の名前を(拡 張子も含めて)、変数 $" に追加します。

scan(re)
scan(re) {|matched| ... }

$_.scan と同じです。

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

実行のタイプを表す、以下のいずれかの文字列。

  • "line" ... 式の評価。
  • "call" ... メソッドの呼び出し。
  • "return" ... メソッド呼び出しからのリターン。
  • "c-call" ... Cで記述されたメソッドの呼び出し。
  • "c-return" ... Cで記述されたメソッド呼び出しからのリターン。
  • "class" ... クラス定義、特異クラス定義、モジュール定義への突入。
  • "end" ... クラス定義、特異クラス定義、モジュール定義の終了。
  • "raise" ... 例外の発生。
file

実行中のプログラムのソースファイル名 (文字列)。

line

実行中のプログラムのソースファイル上の行番号 (整数)。

id

event に応じ、以下のものが渡されます。 第六ブロック引数の klass と対応しています。

line

最後に呼び出されたメソッドを表す Symbol オブジェクト。 トップレベルでは nil

call/return/c-call/c-return

呼び出された/リターンするメソッドを表す Symbol オブジェクト。

class/end

nil

raise

最後に呼び出されたメソッドを表す Symbol オブジェクト。 トップレベルでは nil

binding

実行中のプログラムのコンテキストを表す Binding オブジェクト。

klass

event に応じ、以下のものが渡されます。 第四ブロック引数の id と対応しています。

line

最後に呼び出されたメソッドが属するクラスを表す Class オブジェクト。トップレベルでは false

call/return/c-call/c-return

呼び出された/リターンするメソッドが属するクラス を表す Class オブジェクト。

class/end

false

raise

最後に呼び出されたメソッドが属するクラスを表す Classオブジェクト。トップレベルでは false

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 では以下の点で違いがあります。

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 を参照して ください。

`command`, open も参照してくだ さい。

test(cmd, file1 [, file2])

ファイルテストを行います。cmd は以下に示す 数値リテラルか文字列です(文字列の場合はそ の先頭の文字だけをコマンドとみなします)。

throw(tag[, value=nil])

同じ tag を指定した catch のブロックの 終わりまで(メソッドを越えて)脱出します。もし同じ tag で 待っている catch が存在しない場合は NameError で スレッドが終了します。tag は文字列またはシンボルです。 valuecatch の戻り値になります。

例:

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 オブジェクトなら ブロック引数に代入された値が渡されます。またフックは複数 登録できます。

トレースを解除するには、hooknil を 指定するか、untrace_var を用います。

例:

trace_var(:$v) {|val| puts "$v=#{val.inspect}" }
$v = "foo"   #=> $v="foo"
$v = 1       #=> $v=1

hooknil ならば、設定されていた 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 インタプリタは例外 InterruptSignalException を発生させます。このようなシグナルは例外処理によっ て捕捉することもできます。

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'        # なにも出力されない

Title: Float

浮動小数点数のクラス。

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

Float.induced_from(num)

numFloat に変換した結果を返します。

4 メソッド:

self + other
self - other
self * other
self / other
self % other
self ** other

算術演算子。それぞれ和、差、積、商、剰余、冪を計算します。

self <=> other

selfother を比較して、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

小数点以下を切り捨てて値を整数に変換します。

round, ceil, floor も参照。

Title: ArgumentError

引数の数があっていないときや、値が正しくないときに発生します。

Time.at
Math.sqrt(-1)

など*68

1 スーパークラス:

Title: Fixnum

マシンのポインタのサイズに収まる長さの固定長整数。ほとんどのマシンでは 31 ビット幅です。演算の結果が Fixnum の範囲を越えた時には自動的 に Bignum に拡張されます。

1 スーパークラス:

2 メソッド:

id2name

Symbol オブジェクトの整数値 (Symbol#to_i で得られます)に対応する文字列を返します。整数に対応するシンボルが 存在しない時には nil を返します。

Title: Bignum

多倍長整数のクラス。Bignum が扱うことのできる大きさはメモリサイ ズだけによって制限されます。演算の結果が Fixnum の範囲内である場 合には Fixnum に変換され、逆に Fixnum の範囲を越える時には Bignum に拡張されます。ビット演算については 2 の補数表現の無限長 のビットストリングとみなすことができます。特に負の数は左側に無限に 1 のビットが立っているように操作できます。Float との混合に関しては、 変換時に桁落ちが生じる可能性があります。

1 スーパークラス:

Title: Integer

整数の抽象クラス。サブクラスとして FixnumBignum があり ます。この 2 種類の整数は値の大きさに応じてお互いに自動的に変換されま す。ビット操作において整数は無限の長さのビットストリングとみなすことが できます。

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

Integer.induced_from(num)

numInteger に変換した結果を返します。

4 メソッド:

self[nth]

nth 番目のビットが立っている時 1 を、そうでなければ 0 を返し ます。

5 メソッド:

self + other
self - other
self * other
self / other
self % other
self ** other

算術演算子。それぞれ和、差、積、商、剰余、冪を計算します。

self <=> other

selfother を比較して、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 であれば何もしません。

upto, step, times も参照。

next
succ

の整数を返します。

step(limit, step) {|n| ... }

self からはじめ step を足しながら limit を越える 前までブロックを繰り返します。step は負の数も指定できます。 step に 0 を指定した場合は例外 ArgumentError が発生します。

self を返します。

upto, downto, times も参照。

times {|n| ... }

self 回だけ(0 から self-1 まで)繰り返します。 self が負であれば何もしません。

self を返します。

upto, downto, step も参照。

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 を返します。

downto, step, times も参照。

Title: Continuation

組込み関数 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 の略です。

1 スーパークラス:

2 メソッド:

call(ret[,ret2[,...]])

self が記憶した状態を継続します。引数は そのまま callcc の戻り値になります。

Title: Errno::EXXX

errno に対応する例外クラスです。実際のクラス名については Errno モジュールとシステムのマニュアル errno(3) を参照してください。

1 スーパークラス:

2 定数:

Errno

各クラスに対応する errno の値です。

Errno::EXXX::Errno 定数は、対応する値が常に設定されています が、SystemCallError#errno メソッドは実際にエ ラーが発生してなければ nil を返します。

例:

Errno::EAGAINErrno::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

Title: ARGF

スクリプトに指定した引数 (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 な どこのオブジェクトをレシーバとしたメソッドの省略形です。

1 メソッド:

IO オブジェクトのメソッドに加えて、以下のメソッドを持ちます。

ARGF.to_s
ARGF.filename

処理対象のファイル名を返します。標準入力に対しては - を返し ます。組込み変数 $FILENAME と同じです。

ARGF.file

処理対象の File オブジェクト(または IO オブジェクト)を 返します。

ARGF.lineno

全引数ファイルを一つのファイルとみなしたときの現在の行番号を返しま す。個々の引数ファイル毎の行番号を得るには ARGF.file.lineno とします。

ARGF.skip

処理対象のファイルをクローズします。次回の読み込みは次の引数が処理 対象になります。self を返します。

Title: EOFError

EOF(End Of File)に達したときに発生します。

1 スーパークラス:

Title: LoadError

requireload が失敗したときに発生します。

1 スーパークラス:

Title: File

ファイルアクセスのためのクラス。通常 open を 使ってオープンされます。このクラスには FileTest モジュールに 定義されているのと同じ特異メソッドが定義されています。

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

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 が発生します。

modechmod(2) と同様に数値で指定します。

lchmod は、シンボリックリンクに関してリンクそのものの モードを変更します。lchmod(2) を実装し ていないシステムでこのメソッドを呼び出すと NotImplementedError 例外が発生します。

File.chown(owner, group[, filename[, ...]])
File.lchown(owner, group[, filename[, ...]]) ((<ruby 1.7 feature>))

ファイルのオーナーとグループを変更します。スーパーユーザだけがファ イルのオーナーとグループを変更できます。変更を行ったファイルの数を 返します。変更に失敗した場合は例外 Errno::EXXX が発生します。

ownergroup は、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_dirnil かまたは与えられなかった時にはカ レントディレクトリが使われます。

先頭の ~ はホームディレクトリ(環境変数 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))。 pathpattern にマッチすれば真を返します。

pattern にはワイルドカードとして `*', `?', `[]' が使用 できます(Dir.globとは違って `{}' は使用できません)。

%w(foo foobar bar).each {|f|
  p File.fnmatch("foo*", f)
}
# => true
     true
     false

flags に以下の定数(File::Constants モジュールで定義さ れています)を論理和で指定することでパターンマッチの動作を変更する ことができます。flags のデフォルト値は0(フラグ指定なし)です。

FNM_NOESCAPE

エスケープ文字 `\' を普通の文字とみなします。

p File.fnmatch('\*', '\*', File::FNM_NOESCAPE)   # => true

ワイルドカードをエスケープしない `\' はこのフラグに関らず `\' に マッチします*69

p File.fnmatch('\\', '\\')   # => true
p File.fnmatch('\a', '\a')   # => false
FNM_PATHNAME

ワイルドカード `*', `?', `[]' が `/' にマッチしなくなります。 シェルのパターンマッチにはこのフラグが使用されています。

p File.fnmatch('*', '/', File::FNM_PATHNAME)   # => false
p File.fnmatch('?', '/', File::FNM_PATHNAME)   # => false
p File.fnmatch('[/]', '/', File::FNM_PATHNAME) # => false
FNM_PERIOD

ワイルドカード `*', `?', `[]' が先頭の `.' にマッチしなくなります。 シェルのパターンマッチにはこのフラグが使用されています。

p File.fnmatch('*', '.', File::FNM_PERIOD)   # => false
p File.fnmatch('?', '.', File::FNM_PERIOD)   # => false
p File.fnmatch('[/]', '.', File::FNM_PERIOD) # => false
FNM_CASEFOLD

アルファベットの大小文字を区別せずにパターンマッチを行います。

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"

*70

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)

pathnamedirnamebasename に分割して、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クラスで定義されているク ラスメソッドも持っています。

4 メソッド:

atime
ctime
mtime

それぞれ、ファイルの最終アクセス時刻/状態が最後に変更された時刻/最 終更新時刻(Time オブジェクト)を返します。

ファイルの時刻の取得に失敗した場合は例外 Errno::EXXX が発生 します。

chmod(mode)

ファイルのモードを mode に変更します。モードの変更に成功した 場合は 0 を返します。失敗した場合は例外 Errno::EXXX が発生し ます。

modechmod(2) と同様に数値で指定します。

chown(owner, group)

ファイルのオーナーとグループを変更します。スーパーユーザだけがファ イルのオーナーとグループを変更できます。所有者の変更に成功した場合 は 0 を返します。変更に失敗した場合は例外 Errno::EXXX が発生 します。

ownergroup は、chown(2) と同様に 数値で指定します。 nil または -1 を指定することでオーナーやグループを現在 のままにすることができます。

flock(operation)

ファイルをロックします。ロックに成功した場合は 0 を返します。失敗 した場合は例外 Errno::EXXX が発生します。LOCK_NB が指 定されていて、ブロックされそうな場合には false を返します。 有効な operation は以下の通りです。

以上の定数は 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 が発生します。

5 定数:

ALT_SEPARATOR

システムのファイルパスのセパレータが SEPARATOR と異なる場合 に設定されます。MS-DOS などでは "\" です。UNIX や Cygwin な どでは nil です。

PATH_SEPARATOR

PATH 環境変数の要素のセパレータです。UNIX では ":" MS-DOS な どでは ";" です。

SEPARATOR
Separator

ファイルパスのセパレータです。ファイルを扱うメソッドにパス名を渡す 場合などスクリプト内のパス名は環境によらずこのセパレータで統一され ます。値は "/" です。

6 内部クラス:

Constants

File クラスに関係する定数を格納したモジュールです。File::Constants を参照してください。

Stat

stat 構造体(stat(2)参照)を表すクラスです。 File::Stat を参照してください。

Title: File::Constants

File クラスに関る定数を集めたモジュール。

File クラスはこのモジュールをインクルードしているので、以下に挙 げる定数は File クラスの定数のように扱うことができます。

1 定数

以下の定数は、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

Title: IO

IO クラスは基本的な入出力機能を実装します。

1 スーパークラス:

2 インクルードされているモジュール:

3 クラスメソッド:

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

lengthnil であるか省略した場合には、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 と同じです。

4 メソッド:

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.soFcntl モジュールが提供しています。

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#getsgets 同様、読み込んだ文字列を変数 $_ にセットします。

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)

文字 chself に出力します。 引数の扱いは putc と同じです(詳細はこちらを参照し てください)。

ch を返します。

puts([obj[, ...]])

objself に出力した後、改行します。 引数の扱いは 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 を指定すると行区切りなしとみなします。 空文字列 "" を指定すると連続する改行を行の区切りとみなします (パラグラフモード)。

readlinegets 同様読み込んだ文字列を変数 $_ にセットします。

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 を経由しないので getsgetceof? などと混用すると思わぬ動作 をすることがあります。

データの読み込みに失敗した場合は例外 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 が発生します。

5 定数

SEEK_CUR
SEEK_END
SEEK_SET

IO#seek を参照してください。

Title: debug.rb

Ruby デバッガです。ruby スクリプトのソースデバッグに使用します。

Emacs を使用したインタフェースruby/misc/rubydb[23]x.elも ruby の アーカイブの中にあります。

rubydb2x.el は、Emacs 19.2x 以前用、 rubydb3x.el は、Emacs 19.3x 以降用です。

1 使い方:

$ ruby -rdebug foo.rb

または、Emacs から

M-x load-library rubydb3x.el
M-x rubydb

2 デバッグコマンド:

以下は、デバッガで使用できるコマンド名とその用法の一覧です。各コマンド 名には省略形があります。

ここに挙げたもの以外を入力した場合、その入力を ruby の式として評価します。

break
break [file|method:]<line|method>

ブレークポイントを設定します。引数を省略した場合設定したブレークポ イントを表示します。

設定するブレークポイントの書式は プログラムファイル名:位置 です。 位置 はファイル中の行番号もしくはメソッド名で指定します。 ファイル名: を省略した場合は現在実行中のファイルを指定した ものと見倣されます。

このコマンドの省略形は b です。

catch <an Exception>

例外が発生した時にデバッガを停止させるキャッチポイントを設定します。 引数を省略した場合設定したキャッチポイントを表示します。

発生した例外が <an Exception> のサブクラスであれば デバッガが停止します。デフォルトのキャッチポイントは StandardErrorに設定されています。

<an Exceptionとして off を指定すると 例外発生時に停止しなくなります。

このコマンドの省略形は cat です。

watch <expression>

<expression> の値が変化したときに停止するウォッ チポイントを設定します。

このコマンドの省略形は wat です。

delete [nnn]

指定したブレークポイントを取り除きます。引数を省略した場合すべての ブレークポイントを取り除きます。

このコマンドの省略形は del です。

display <expression>

処理が停止するごとに <expression> を評価するディス プレイ式を設定します。 引数を省略した場合すべてのディスプレイ式を表示します。

このコマンドの省略形は disp です。

undisplay <nnn>

指定したディスプレイ式を取り除きます。引数を省略した場合すべての ディスプレイ式を取り除きます。

このコマンドの省略形は undisp です。

cont

スクリプトが終了するまで、もしくは次のブレークポイントに到達するま で処理を続行します。

このコマンドの省略形は c です。

step [nnn]

一行ずつ処理を実行します。引数を指定した場合、指定した行数分、処理を 続行します。メソッドの中に入ります。

このコマンドの省略形は s です。

next [nnn]

一行ずつ処理を実行します。引数を指定した場合、指定した行数分、処理を 続行します。step [nnn]との違いは、メソッド呼び出しのところでそのメ ソッドの中に入らないことです。

このコマンドの省略形は n です。

where
frame

フレームのスタックと、現在のフレーム位置を表示します。

このコマンドの省略形は w または f です。

list [(-|nn-mm)]

スクリプトを表示します。引数が `-' ならば前の行を表示します。 nn-mm の形式では指定した範囲の行のスクリプトを表示します。

このコマンドの省略形は l です。

up [nn]

上位のフレームに上がります。

down [nn]

下位のフレームに下がります。

finish

外側のフレームに上がるまで処理を続行します。

このコマンドの省略形は fin です。

trace [(on|off)]

トレースモードの設定を変更します。トレースモードをonにすると、以後 の実行においてメソッドの呼び出し関係が表示されます。引数を省略した 場合現在のモードを表示します。

このコマンドの省略形は tr です。

quit

スクリプトを中断し、デバッガを終了します。

このコマンドの省略形は q です。

var g[lobal]
var l[ocal]
var i[nstance] <object>
var c[onst] <object>

それぞれ、グローバル変数、ローカル変数、オブジェクト<object>の インスタンス変数、<object>の定数を表示します。

このコマンドの省略形は v です。

method i[nstance] <object>
method <class|module>

それぞれ、オブジェクト<object>のインスタンスメソッド クラスメソッド または モジュールメソッドを表示します。

このコマンドの省略形は m です。

thread l[ist]

スレッドの一覧を表示します。

このコマンドの省略形は th です。

thread c[ur[rent]]

現在のスレッドを表示します。

thread <nnn>
thread stop <nnn>
thread c[ur[rent]] <nnn>

スレッド <nnn> を停止します。

thread resume <nnn> run thread nnn

スレッド <nnn> を再開します。

p <expression>

ruby の式 <expression> の結果を表示します。

help

デバッグコマンドの一覧を表示します。

このコマンドの省略形は h です。

Title: tracer.rb

1 目的・概要

実行トレース出力をとる機能を提供する。

使い方は大きく分けて2通り。

ruby -rtracer hoge.rb

hoge.rbの実行をすべてトレース出力する。

require 'tracer'

Tracer.on によりトレース出力を有効にする。

Tracer.off によりトレース出力を無効にする。

また、ブロック付きで Tracer.on を呼び出すと、そのブロック内のみ トレースを出力する。

2 サンプルコード

なし

3 class Tracer

3.1 クラスメソッド

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より。

event

イベントを表す文字列。

以下の種類がある。カッコ内はtracer.rbの出力での表記。

line (-)

ある行を実行

call (>)

メソッド呼び出し

return (<)

メソッドからのリターン

class (C)

クラスコンテキストに入った

end (E)

クラスコンテキストから出た

raise

例外が発生した

c-call

Cで記述されたメソッドが呼ばれた

c-return

Cで記述されたメソッドからreturn

file

現在処理しているファイルの名前

line

現在処理している行番号

id

最後に呼び出されたメソッドのメソッド名(のシンボル) そのようなメソッドがなければ0になる。

binding

現在のコンテキスト

4 SEE ALSO

Title: profile.rb

Ruby プログラムのためのプロファイラです。プロファイラとは効率改善のた めの調査に用いられるツールのことで、profile.rbは各メソッドの実行時間に 関する統計を出力します。

1 使い方:

$ ruby -r profile foo.rb

実行が終ると標準出力にプロファイルを出力します。

プロファイルは各メソッドの実行時間に関する統計からなりますが、この時間 には大きく分けて2種類あります。ひとつは、メソッドが呼び出されてから返 るまでの時間です。もうひとつは、全体の時間からそのメソッド内で行なわれ た他の呼び出しに費やしたすべての時間を引いた時間です。以下の説明では前 者を全体時間、後者を正味時間と呼ぶことにします。

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#+
… 以下略 …

おのおのの行に現れる各フィールドの意味は左から順に次の通りです。

  1. 全体時間のパーセンテージ
  2. 全体時間の総和(単位は秒)
  3. 正味時間の総和(秒)
  4. 呼び出された回数
  5. 1回の呼び出し当たりの平均正味時間(ミリ秒)
  6. 1回の呼び出し当たりの平均全体時間(ミリ秒)
  7. メソッド名

Title: SignalException

trap されていないシグナル(signal(2) 参照)を受け取ったときに発生します。

実際に発生したシグナル名は、 SignalException#message から "SIGname"という形で得られます。

デフォルトの状態では、以下のシグナルが SignalException を発生さ せます。

SIGHUP, SIGQUIT, SIGALRM, SIGUSR1, SIGUSR2

また、SIGINT は 例外 Interrupt を発生させます。

1 スーパークラス:

Title: 組込み変数

このマニュアルでは、`$'で始まる変数を「グローバル変数」と呼んでいますが *73 組み込みの変数(これらは特殊な機能と用途を持ちます)の中にはその有効なス コープがグローバルとは限らない場合があります(どこでも使えるという意味で はグローバルですが、その値はグローバルとは限りません)。ここでは、変数の 値のスコープで大別してグローバル変数の一覧を列挙します。

1 ローカルスコープ

以下の変数はスレッドローカルでもあります。

$_

最後に gets または readline で読み込んだ文字列。 EOF に達した場合には、nil。この変数はローカルスコープです。 (覚え方: Perlと同じ)

$&

現在のスコープで最後に成功した正規表現のパターンマッチでマッチした 文字列。最後のマッチが失敗していた場合には nil。 (覚え方: いくつかのエディタでの & と同じ)

Regexp.last_match[0] と同じ。

$~

現在のスコープで最後に成功したマッチに関する情報(MatchData オブジェクト)。これを設定すると $&$1 ... $9 などの 値が変化します。

このデータから n 番目のマッチ($n)を取り出すためには $~[n] で 参照できます。 (覚え方: ~ はマッチに使われる)

Regexp.last_match と同じ。

$`

現在のスコープで最後に成功した正規表現のパターンマッチでマッチした 部分より前の文字列。最後のマッチが失敗していた場合には nil。 (覚え方: `は文字列の前に置かれる)

Regexp.last_match.pre_match と同じ。

$'

現在のスコープで最後に成功した正規表現のパターンマッチでマッチした 部分より後ろの文字列。最後のマッチが失敗していた場合には nil。 (覚え方: 'は文字列の後ろに置かれる)

Regexp.last_match.post_match と同じ。

$+

現在のスコープで最後に成功した正規表現のパターンマッチでマッチした 中で最後の括弧に対応する部分文字列。 最後のマッチが失敗していた場合には nil。 いくつかある選択型のパターンのどれがマッチしたのか分からない時に便利 (覚え方: be positive and forward looking.)

$1
$2
$3 ...

最後に成功したパターンマッチでn番目の括弧にマッチした値が格 納されます。該当する括弧がなければnilが入ってい ます。(覚え方: \数字 のようなもの)

Regexp.last_match[1], Regexp.last_match[2], ... と同じ。

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

カレントスレッドのセーフレベル。セーフレベルについては セキュリティモデルを参照してください。

Thread.current.safe_level と同じ。

3 グローバルスコープ

$=

パターンマッチや文字列の比較でアルファベットの大文字小文字を 区別するかどうかのフラグ。デフォルトは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

組込み関数 printputsp などのデフォルトの出力先。初期値は 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 と同じ。

$:

loadrequire がファイルをロードする時に検索するディレクトリのリストを含む 配列。 $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 オプションでセットされます。

デバッグモードでは、通常の実行と以下の違いがあります。

$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' です。

参考

現在の実装では、$KCODE は、インタプリタの字句解析器、 Regexp の漢字フラグのデフォルト値 (正規表現リテラル, Regexp.new)、 String の以下のメソッド

upcase, downcase, swapcase, capitalize, inspect, split, gsub, scan

に影響します。

3.1 オプション変数

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 の別名。

Title: Regexp

正規表現のクラス。正規表現のリテラルはスラッシュで囲んだ形式 で生成します。

/^this is regexp/

Regexp.new(string) を使って正規表現オブジェクトを動的に生成する こともできます。

1 スーパークラス:

2 クラスメソッド:

Regexp.compile(string[, option[, code]])
Regexp.new(string[, option[, code]])

文字列をコンパイルして正規表現オブジェクトを生成して返します。第 2 引数が与えられて、その値が真であれば、生成された正規表現はアルファ ベットの大文字小文字を区別しません。第 2 引数が整数であった場合、 その値は Regexp::IGNORECASERegexp::MULTILINERegexp::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_matchnil を返すため、 last_match[1] の形式では例外 NameError が発生します。 対して、last_match(1)nil を返します。

3 メソッド:

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

その正規表現のもととなった文字列表現を生成して返します。

4 定数

EXTENDED

バックスラッシュでエスケープされていない空白と # から改行までを無 視します。正規表現リテラル の //x オプションと同じ です。(空白を入れる場合は\でエスケープして\ (<-空白)と 指定します)

IGNORECASE

文字の大小の違いを無視します。 正規表現リテラル の //i オプションと同じです。

MULTILINE

複数行モード。正規表現 "." が改行にマッチするようになります。 正規表現リテラル の //m オプションと同じです。

Title: MatchData

正規表現のマッチに関する情報を扱うためのクラス。 このクラスのインスタンスは、

などにより得られます。

1 スーパークラス:

2 メソッド:

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>))

$&, $1, $2, ... を格納した配列を返します。

/(foo)(bar)(BAZ)?/ =~ "foobarbaz"
p $~.to_a       # => ["foobar", "foo", "bar", nil]
to_s

マッチした文字列全体を返します。

/bar/ =~ "foobarbaz"
p $~            # => #<MatchData:0x401b1be4>
p $~.to_s       # => "bar"

Title: Process::Status

ruby 1.7 feature

Process.wait などで生成されるオブジェクト。プロセスの終 了ステータスを表現します。

1 メソッド

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.waitpidProcess::WUNTRACED フラグを設定した 場合にだけ真になりえます。

stopsig

stopped? が真の場合そのシグナルの番号を、そうでない場合は nil を返します。

signaled?

プロセスがハンドラを定義していないシグナルを受けて終了した場合に真 を返します。

termsig

signaled? が真の場合プロセスを終了させたシグナル番号を、 そうでない場合は nil を返します。

coredump?

終了時にコアダンプしていたら真を返します。

2 使用例

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

Title: Process

UNIX のプロセスを管理するモジュール。Process.exit!, Process.fork 以外のメソッドは全てモジュール関数 (Module#module_function)です。

Process がプロセスを表現するクラスではなく、プロセスに対する操作 をまとめたモジュールであることに注意してください。

1 モジュールメソッド:

Process.exit!([status])

関数 exit! と同じです。

Process.fork
Process.fork { ... }

関数 fork と同じです。

2 モジュール属性:

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 を返します。

3 モジュール関数:

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 オブジェクト です。

4 定数:

PRIO_PROCESS

Process.getpriority または Process.setpriority のプロセスプライオリティ指定。

PRIO_PGRP

プロセスグループプライオリティ。

PRIO_USER

ユーザプライオリティ。

WNOHANG

Process#waitpid の第二引数に指定するフラグで す。終了した子プロセスがない時に waitpid がブロックしません。

WUNTRACED

Process#waitpid の第二引数に指定するフラグで す。子プロセスの停止によりステータスを報告していない子プロセスがあ る時に waitpid がブロックしません。

5 内部クラス:

Status ((<ruby 1.7 feature>))

プロセスの終了ステータスを表現するクラスです。 Process::Status を参照してください。

Title: Config

執筆者募集

Ruby インタプリタ作成時に設定された情報を格納したモジュールです。

1 モジュール関数:

Config.expand(val)

MAKEFILE_CONFIG 参照

2 定数

DESTDIR
TOPDIR
CONFIG

設定値を格納したハッシュです。以下のキーと値を持ちます。

srcdir

Ruby をコンパイルしたソースディレクトリ

prefix

Ruby のインストール先の基準ディレクトリ

ruby_install_name
RUBY_INSTALL_NAME

ruby インタプリタのファイル名

EXEEXT

実行ファイルの拡張子

SHELL

シェルのパス名

CFLAGS

C コンパイラのオプション

CPPFLAGS

C プリプロセッサのオプション

CXXFLAGS

C++ コンパイラのオプション

FFLAGS

Fortran コンパイラのオプション

LDFLAGS

リンカオプション

LIBS

ライブラリ

exec_prefix

アーキテクチャ依存の実行ファイルのインストール先ディレクトリ

bindir

実行ファイルのインストール先ディレクトリ

sbindir

管理者用実行ファイルのインストール先ディレクトリ

libexecdir

他のプログラムから実行される実行ファイルのインストール先ディレクトリ

datadir

アーキテクチャに依存しないデータのインストール先ディレクトリ

sysconfdir
sharedstatedir
localstatedir
libdir
includedir
oldincludedir
infodir
mandir
MAJOR

Ruby の major バージョン番号(1.6.5の1)

MINOR

Ruby の minor バージョン番号(1.6.5の6)

TEENY

Ruby の teeny バージョン番号(1.6.5の5)

host
host_alias
host_cpu
host_vendor
host_os

実行するシステムの情報 (?)

例:
C:\>ruby -vrrbconfig -e "p Config::CONFIG['host']"
ruby 1.6.6 (2001-12-26) [i386-mingw32]
"i686-pc-cygwin"
target
target_alias
target_cpu
target_vendor
target_os

生成されたコードを実行するシステムの情報

例:
C:\>ruby -vrrbconfig -e "p Config::CONFIG['host']"
ruby 1.6.6 (2001-12-26) [i386-mingw32]
"i386-pc-mingw32"
build
build_alias
build_cpu
build_vendor
build_os

ビルドしたシステムの情報

C:\>ruby -vrrbconfig -e "p Config::CONFIG['host']"
ruby 1.6.6 (2001-12-26) [i386-mingw32]
"i586-pc-linux-gnu"
CC

ビルドに使われた C コンパイラ

CPP

ビルドに使われた C プリプロセッサ

YACC

ビルドに使われた コンパイラコンパイラ

RANLIB
AR
NM
DLLWRAP
AS
DLLTOOL

ビルドに使われたライブラリ操作コマンド (?)

WINDRES

Windows のリソース操作コマンド

LN_S

シンボリックリンク作成コマンド

SET_MAKE
OBJEXT

オブジェクトファイル(コンパイルだけされてリンク前のファイル)の拡張子

LIBOBJS

ruby本体にリンクされているオブジェクトファイル (?)

ALLOCA
XLDFLAGS
DLDFLAGS
STATIC
CCDLFLAGS
LDSHARED
DLEXT
DLEXT2

ダイナミックリンクライブラリの拡張子

STRIP

オブジェクトファイルからシンボルを切り捨てるコマンド

EXTSTATIC
setup
MINIRUBY

ビルド途中に作成される機能限定版rubyのcompile_dirからの相対パス

PREP
LIBRUBY_LDSHARED
LIBRUBY_DLDFLAGS
RUBY_SO_NAME

ruby共有ライブラリの名前

LIBRUBY_A
LIBRUBY_SO
LIBRUBY_ALIASES
LIBRUBY
LIBRUBYARG
SOLIBS
DLDLIBS
ENABLE_SHARED

configureで--enable-sharedだったかどうか(値は"yes"または"no") (?)

MAINLIBS
arch
sitedir
configure_args
ruby_version

rubyのバージョン(例:"1.6")

rubylibdir
archdir
sitelibdir
sitearchdir
compile_dir
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"

Title: 組込み定数

TRUE

代表的な真の値。true と同じ。Ruby では偽でない値(false でも nil でもない値)は全て真とみなされます。 (obsoleteも参照してください。)

FALSE

偽の値。false と同じ。 (obsoleteも参照してください。)

NIL

nil と同じ。 (obsoleteも参照してください。)

STDIN

標準入力。$stdin のデフォルト値。

STDOUT

標準出力。$stdout のデフォルト値。

STDERR

標準エラー出力。$stderr のデフォルト値。

ENV

環境変数を表す(疑似)連想配列(詳細は ENV を参照)。この連想配 列の値を変更すると子プロセスの環境として引き継がれます。

ARGF

引数(なければ標準入力)で構成される仮想ファイル (詳細は ARGF を参照)。つまり getsARGF.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"]}

なお、$SAFEレベルが 0 でなければ有効にはなりませ ん。また、eval によるコンパイルは対象にはなりませ ん。

Title: ENV

環境変数を表すオブジェクト。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

1 インクルードされているモジュール:

2 メソッド:

ENV[key]

key に対応する環境変数の値を返します。該当する環境変数が存在 しない時には nil を返します。

ENV[key]=value
ENV.store(key, value)

key に対応する環境変数の値を value にします。 valuenil の時、key に対応する環境変数を取り 除きます。

ENV.delete(key)

key に対応する環境変数を取り除きます。取り除かれた環境変数の 値を返 しますが、key に対応する環境変数が存在しない時には nil を返します。

ブロックが与えられた時には key にマッチするものがなかった時 に評価されます。

ENV.reject{|key, value| ... }

ブロックを評価した値が真である時、要素を削除します。 Enumerable#reject と異なり Hash を返 します。

ENV.delete_if {|key, value| ... }
ENV.reject!{|key, value| ... }

keyvalue を引数としてブロックを評価した値が真であ る時、環境変数を削除します。

reject! は要素に変化がなければ nil を返します。

ENV.each {|key, value| ... }
ENV.each_pair {|key, value| ... }

keyvalue を引数としてブロックを評価します。

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| ... }

ruby 1.7 feature

最初の形式では、引数で指定されたキー(環境変数名)に対応する値の配列 を返します。存在しないキー(環境変数)に対しては nil が対応します。 ENV.indexesENV.indices と同じです。

ブロック付きでイテレータとして呼び出した場合は Enumerable#select と同じです。つまり、ブロッ クにキーと値の組を順に渡し、ブロックが真を返した要素(キーと値の配 列) の配列を返します。

ENV.to_a

環境変数から [key,value] なる 2 要素の配列の配列を生成します。

ENV.to_hash

環境変数の名前と値のハッシュを返します。

ENV.values

環境変数の全値の配列を返します。

Title: 組込みクラス/モジュール/例外クラス

1 組込みクラス

2 組込みモジュール

3 例外クラス

Title: Data

拡張ライブラリを書く時に new が定義されているとまずい場合が あるため、Object から new だけを undef したクラス。 Ruby レベルでは気にする必要は全くありません。

1 スーパークラス:

Title: Exception

全ての例外の祖先のクラスです。

1 スーパークラス:

2 クラスメソッド:

Exception.new([error_message = ""])
Exception.exception([error_message = ""])

例外オブジェクトを生成して返します。引数としてエラーメッセージを表 す文字列を与えることができます。このメッセージはデフォルトの例外ハ ンドラで表示されます。

3 メソッド:

backtrace

バックトレース情報を返します。

という形式(デフォルトでは)の String の配列です。

message
to_s
to_str

エラーメッセージをあらわす文字列を返します。

set_backtrace(errinfo)

バックトレース情報に errinfo を設定します。errinfonilString あるいは String の配列のいずれかでな くてはなりません。

Title: Dir

ディレクトリ内の要素を順に返すディレクトリストリーム操作のためのクラス。

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

Dir[pattern]
Dir.glob(pattern)
Dir.glob(pattern) {|file| ...}

ワイルドカードの展開を行った結果を文字列の配列として返します。 ブロックが与えられたときはワイルドカードにマッチしたファイルを 引数にそのブロックを 1 つずつ評価して nil を返します

パターンを空白(スペース、タブ、改行)あるいは "\0" で区切って 1 度 に複数のパターンを指定することもできます。

p Dir.glob("f* b*")
=> ["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

4 メソッド:

close

ディレクトリストリームをクローズします。以降のディレクトリに 対する操作は例外 IOError を発生させます。

クローズに成功すれば nil を返します。失敗した場合は例外 IOError が発生します。

each {|item| ... }

ディレクトリの各要素に対してブロックを評価します。 self を返します。

pos
tell

ディレクトリストリームの現在の位置を整数で返します。

Dir.open("/tmp") {|d|
    d.each {|f|
      p d.pos
    }
}
pos=(pos)
seek(pos)

ディレクトリストリームの読み込み位置を pos に移動させます。 posDir#tell で与えられた値でなければなりま せん。

pos= は右辺を返します。seekself を返します。

read

ディレクトリストリームから次の要素を読み出して返します。最後の要素 まで読み出していれば nil を返します。

ディレクトリの読み出しに失敗した場合は例外 Errno::EXXX が発 生します。

rewind

ディレクトリストリームの読み込み位置を先頭に移動させます。 self を返します。

Title: File::Stat

ファイルの情報を格納したオブジェクトのクラス。

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

File::Stat.new(path)

path に関する File::Stat オブジェクトを生成して返します。 File.stat と同じです。

4 メソッド:

self <=> other

ファイルの最終更新時刻を比較します。selfother よりも 新しければ正の数を、等しければ 0 を古ければ負の数を返します。

ftype

ファイルのタイプを表す文字列を返します。文字列は以下のうちの いずれかです。

"file"
"directory"
"characterSpecial"
"blockSpecial"
"fifo"
"link"
"socket"

"unknown"

*81

以下の属性メソッドは、システムによってサポートされていない場合 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ビットが立っている時に真

Title: Method

obj.method(:method_name) によりオブジェクト化され たメソッドオブジェクトのクラスです。メソッドの実体(名前でなく)とレシー バの組を封入します。Proc オブジェクトと違ってコンテキストを保持 しません。

Proc との差…Method は取り出しの対象であるメソッドが なければ作れませんが、Proc は準備なしに作れます。その点から Proc は使い捨てに向き、Method は何度も繰り返し生成する 場合に向くと言えます。また内包するコードの大きさという点では Proc は小規模、Method は大規模コードに向くと言えます。

1 スーパークラス:

2 メソッド:

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

selfcall する Proc オブジェクトを生成して返 します。

unbind

self のレシーバとの関連を取り除いた UnboundMethod オブ ジェクトを生成して返します。

Title: UnboundMethod

レシーバを持たないメソッドオブジェクトのクラスです。 Module#instance_methodMethod#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

1 スーパークラス:

Method

2 メソッド:

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)

selfobj にバインドして 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

selfcall する Proc オブジェクトを生成して返します。

unbind

self を返します。

Title: Numeric

Numeric は数値の抽象クラスです。Ruby では coerce メソッドを使うことによって異なる数値クラス間で演算を行うことができます。

演算や比較を行うメソッド(+, -, *, /, <=>)などはサブクラスで定義されま す。また、効率のため Numeric のメソッドと同じメソッドがサブクラ スで再定義されている場合があります。

1 スーパークラス:

2 インクルードしているモジュール:

3 メソッド:

+ self

self 自身を返します。

- self

self の符号を反転させたものを返します。

self / other ((<ruby 1.7 feature>))

self を other で割った商を返します。

abs

self の絶対値を返します。

ceil

self と等しいかより大きい最小の整数(天井)を返します。

round, truncate, to_i, floor も参照。

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)

selfother で割った商 (q) と余り (m) を、 [q, m] という 2 要素の配列にして返します。

ここで、xy で割った商 q と余り m とい うのは、それぞれ

x = y * q + m  かつ  |m| < |y|

をみたす 整数 q と 数 m のことです。

ただし divmod では、上の条件に加えて、余りの符号を other と同じ(またはゼロ)にします。つまり

となります。

floor

self を超えない最大の整数(床)を返します。

round, truncate, to_i, ceil も参照。

integer?

self が整数の時、真を返します。

modulo(other)

self を other で割った余り m を返します(divmod 参照)。

ただし m の符号は other と同じ(またはゼロ)です。 つまり

となります。

nonzero?

ゼロの時、偽を返し、非ゼロの時 self を返します。

remainder(other)

self を other で割った余り r を返します (divmod参照)。

ただし r の符号は self と同じ(またはゼロ)です。 つまり

となります。

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, to_i, ceil, floor も参照。

truncate

小数点以下を切捨てます。

round, to_i, ceil, floor も参照。

zero?

ゼロの時、真を返します。

4 数値関連クラスの定義メソッド

ほとんどの数値関連のメソッドはサブクラスで再定義されています。これは、 効率のためであったり上位抽象クラスで実装を定義することができなかったり するためです。実際にどのメソッドがどのクラスに定義されているかは以下の 表を参照してください。

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                

Title: Struct

構造体クラス。Struct.new はこのクラスのサブクラスを新たに生成し ます。個々の構造体はサブクラスから new を使って生成します。個々 の構造体サブクラスでは構造体のメンバに対するアクセスメソッドが定義され ています。

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

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

4 構造体クラスのクラスメソッド:

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

構造体のメンバの名前の配列を返します。

5 メソッド:

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"

Title: ThreadGroup

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"

対象の ThreadThread を起こす可能性がある場合 (Thread.exclusive参照)

Thread.exclusive do
  (ThreadGroup::Default.list - [Thread.current]).each {|th| th.join}
end

1 スーパークラス:

2 クラスメソッド:

ThreadGroup.new

新たな ThreadGroup を生成して返します。

3 メソッド:

add(thread)

スレッド thread のグループを self にします。

self を返します。

list

self に属するスレッドの配列を返します。

4 定数:

Default

デフォルトで定義されている ThreadGroup です。メインスレッド は最初このグループに属します。

Title: Time

時刻オブジェクト。Time.now は現在の時刻を返します。 File#stat の返すファイルのタイムスタンプは Time オブジェクトです。

Time オブジェクトは時刻を起算時からの経過秒数で保持しています。 起算時は協定世界時(UTC、もしくはその旧称から GMT とも表記されます) の 1970年1月1日午前0時です。なお、うるう秒を勘定するかどうかはシステムに よります。

また、Time オブジェクトは協定世界時と地方時のどちらのタイムゾー ンを使用するかのフラグを内部に保持しています。ただし、この情報は Marshal.dump では保存されず、Marshal.load で読み込んだ Time オブジェクトのタイムゾーンは常に地方時になりま す。

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

Time.at(time[, usec])

time で指定した時刻の Time オブジェクトを返します。 timeTime オブジェクト、もしくは起算時からの経過秒 数を表わす整数か浮動小数点数です。

浮動小数点の精度では不十分な場合、usec を指定します。 time + (usec/1000000) の時刻を返します。この場合、 timeusec ともに整数でなければなりません。

生成された 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 オブジェクトを返します。newnow とは 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 も使えます が、警告メッセージが出力されます。

4 メソッド:

self + other

self より other だけ後の時刻を返します

self - other

otherTime オブジェクトである時、ふたつの時刻の差を Float で返します。other が数値である時には self より other だけ前の時刻を返します。

self <=> other

時刻の比較。otherTime オブジェクトか数値でなければ なりません。数値の場合は起算時からの経過秒数とみなして比較します。

asctime
ctime

時刻を asctime(3) の形式の文字列に変換します。た だし、末尾の \n は含まれません。

gmt?
utc?

self のタイムゾーンが協定世界時に設定されていれば真を返しま す。

getgm
getutc

ruby 1.7 feature

タイムゾーンを協定世界時に設定した Time オブジェクトを新しく 生成して返します。

getlocal

ruby 1.7 feature

タイムゾーンを地方時に設定した Time オブジェクトを新しく生成 して返します。

gmtime
utc

タイムゾーンを協定世界時に設定します。

このメソッドを呼び出した後は時刻変換を協定世界時として行ないます。 協定世界時を表示するためには以下のようにします。

print Time.now.gmtime, "\n"

self を返します。

localtime

タイムゾーンを地方時に設定します(デフォルト)。self を返しま す。

localtime(gmtimeも)の挙動はシステムの localtime(3)の挙動に依存します。Time クラ スでは時刻を起算時からの経過秒数として保持していますが、ある特定の 時刻までの経過秒は、システムがうるう秒を勘定するかどうかによって異 なる場合があります。システムを越えて Time オブジェクトを受け 渡す場合には注意する必要があります。

strftime(format)

時刻を format 文字列に従って文字列に変換した結果を返します。 format 文字列として指定できるものは 以下の通りです。

現在の実装では、このメソッドは、システムの 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

ruby 1.7 feature

協定世界時との時差を秒を単位とする数値として返します。

地方時が協定世界時よりも進んでいる場合(アジア、オーストラリアなど) には負の値、遅れている場合(アメリカなど)には正の値になります。

タイムゾーンが協定世界時に設定されている場合は 0 を返します。

to_a

tm 構造体の中身を配列にして返します。その順序は:

です。

to_f

起算時からの経過秒数を浮動小数点数で返します。1 秒に満たない経過も 表現されます。

to_i
tv_sec

起算時からの経過秒数を整数で返します。

to_s

時刻を date(1) のような形式の文字列に変換します。

usec
tv_usec

時刻のマイクロ秒の部分を返します。

Title: Comparable

比較演算を許すクラスのための Mix-in。このモジュールをインクルー ドするクラスは、基本的な比較演算子である <=> 演算子を定義してい る必要があります。他の比較演算子はその定義を利用して派生できます。

1 メソッド:

self == other

selfother が等しい時真を返します。

self > other

selfother より大きい時真を返します。

self >= other

selfother より大きいか等しい時真を返します。

self < other

selfother より小さい時真を返します。

self <= other

selfother より小さいか等しい時真を返します。

between?(min, max)

selfminmax の範囲内(min, max を含みます)にある時真を返します。

Title: Enumerable

繰り返しを行なうクラスのための Mix-in。このモジュールの メソッドは全て each を用いて定義されているので、インクルード するクラスには each が定義されていなければなりません。

1 メソッド:

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>))

最初に初期値 initself の最初の要素を引数にブロック を実行します。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

全ての要素を含む配列を返します。

Title: Errno

システムコールのエラーに対応する例外を集めたモジュールです。

1 内部クラス:

以下の例外クラスが定義されています(システムに定義されていれば)。個々の 例外の意味はシステム依存です。これらのクラス全般の説明については Errno::EXXX を参照してください。

なお、Ruby にとって未知の(以下の一覧にはない)システムエラーが発生した 場合は、Errno::Exxx (xxx は、エラー番号を表す 3 桁の 数字)という名の例外クラスが作成されます。

ERROR

この例外クラスは BeOS の場合に限ります。

EPERM
ENOENT
ESRCH
EINTR
EIO
ENXIO
E2BIG
ENOEXEC
EBADF
ECHILD
EAGAIN
ENOMEM
EACCES
EFAULT
ENOTBLK
EBUSY
EEXIST
EXDEV
ENODEV
ENOTDIR
EISDIR
EINVAL
ENFILE
EMFILE
ENOTTY
ETXTBSY
EFBIG
ENOSPC
ESPIPE
EROFS
EMLINK
EPIPE
EDOM
ERANGE
EDEADLK
ENAMETOOLONG
ENOLCK
ENOSYS
ENOTEMPTY
ELOOP
EWOULDBLOCK
ENOMSG
EIDRM
ECHRNG
EL2NSYNC
EL3HLT
EL3RST
ELNRNG
EUNATCH
ENOCSI
EL2HLT
EBADE
EBADR
EXFULL
ENOANO
EBADRQC
EBADSLT
EDEADLOCK
EBFONT
ENOSTR
ENODATA
ETIME
ENOSR
ENONET
ENOPKG
EREMOTE
ENOLINK
EADV
ESRMNT
ECOMM
EPROTO
EMULTIHOP
EDOTDOT
EBADMSG
EOVERFLOW
ENOTUNIQ
EBADFD
EREMCHG
ELIBACC
ELIBBAD
ELIBSCN
ELIBMAX
ELIBEXEC
EILSEQ
ERESTART
ESTRPIPE
EUSERS
ENOTSOCK
EDESTADDRREQ
EMSGSIZE
EPROTOTYPE
ENOPROTOOPT
EPROTONOSUPPORT
ESOCKTNOSUPPORT
EOPNOTSUPP
EPFNOSUPPORT
EAFNOSUPPORT
EADDRINUSE
EADDRNOTAVAIL
ENETDOWN
ENETUNREACH
ENETRESET
ECONNABORTED
ECONNRESET
ENOBUFS
EISCONN
ENOTCONN
ESHUTDOWN
ETOOMANYREFS
ETIMEDOUT
ECONNREFUSED
EHOSTDOWN
EHOSTUNREACH
EALREADY
EINPROGRESS
ESTALE
EUCLEAN
ENOTNAM
ENAVAIL
EISNAM
EREMOTEIO
EDQUOT

Title: FileTest

FileTest はファイルの検査関数を集めたモジュールです。このモジュー ルはインクルードしても使えます。

1 モジュール関数:

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)

filenamesetuid(2) されている時に真を返 します。

FileTest.setgid?(filename)

filenamesetgid(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?, も参 照してください。

Title: GC

GC は Ruby インタプリタの「ゴミ集め(Garbage Collection)」を制御 するモジュールです。

1 モジュールメソッド:

GC.disable

ガーベージコレクトを禁止します。

前回の禁止状態を返します(禁止されていたなら true, GC が有効であったなら、 false)。

GC.enable

カーベージコレクトを許可します。

前回の禁止状態を返します(禁止されていたなら true, GC が有効であったなら、 false)。

GC.start

カーベージコレクトを開始します。

nil を返します。

2 メソッド:

garbage_collect

ガーベージコレクトを開始します。以下と同じ働きをします。

GC.start

nil を返します。

Title: Marshal

Ruby オブジェクトをファイル(または文字列)に書き出したり、読み戻したり する機能を提供するモジュール。大部分のクラスのインスタンスを書き出す事 ができますが、書き出しの不可能なクラスも存在していて(例:IO)、そ のようなクラスを書き出そうとすると例外 TypeError が発生します。

1 モジュール関数:

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]

2 定数:

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]

Title: Math

浮動小数点演算をサポートするクラス。Math モジュールは同じ定義の メソッドと特異メソッドとの両方が定義されているので、特異メソッドを呼び 出して使う使い方と、クラスにインクルードして使う使い方との両方ができま す。

例:

pi = Math.atan2(1, 1)*4;
include Math
pi2 = atan2(1, 1)*4

1 モジュール関数:

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 が発生します。

2 定数:

E

自然対数の低

p "%.60f" % Math::E
# => "2.718281828459045090795598298427648842334747314453125000000000"
PI

円周率

p "%.60f" % Math::PI
# => "3.141592653589793115997963468544185161590576171875000000000000"

Title: Precision

精度をもつ具象数値クラスのための Mix-in。 ここでいう精度とは実数の近似 の良さを意味します。抽象数値クラスや複素数、行列などそれら自身が実数に 含まれないような クラスにインクルードすべきではありません。

1 モジュールメソッド:

Precision.included(module_or_class)

ruby 1.7 feature

Precision がインクルードされた時に呼ばれます。詳細は Module#included を参照してください。

このメソッドは、Precision をインクルードするクラスやモジュー ルに対してメソッド induced_from を自動的に定義するためにあり ます。*85

Precision.induced_from(number)

number を自分のクラスに変換した結果を返します。 デフォルトの 定義は、例外 TypeError を発生させるので、Mix-in したクラスで このメソッドを再定義する必要があります。再定義に、 Precision#prec を使うと、 無限ループになる可 能性があります。

2 メソッド:

prec(klass)

self を精度 klass に変換した結果を返します。デフォルト の定義では klass.induced_from(self) を呼び出し、その結 果を返します。

新しく精度クラスを作るときは組み込みクラスの Precision.induced_from を変更するのではなく、この prec の再定義で対応するべきです。

prec_i

selfInteger に変換します。prec(Integer) と等 価です。

prec_f

selfFloat に変換します。prec(Float) と等価で す。

Title: Signal

ruby 1.7 feature

UNIX のシグナル関連の操作を行うモジュールです。

1 モジュール関数:

Signal.list

シグナル名とシグナル番号を対応づけた Hash オブジェクトを返し ます。

p Signal.list   # => {"WINCH"=>28, "PROF"=>27, ...}
Signal.trap(signal, command)
Signal.trap(signal) { ... }

関数 trap と同じです

Title: NoMemoryError

大きすぎるメモリを一度に確保しようとしたときに発生します。

また、メモリ不足に対しては通常 fatal エラーが発生しますが、セー フレベル($SAFE)が 4 以上のときは代わりにこの例外が発 生します。

1 スーパークラス:

Title: ScriptError

スクリプトのエラーを表す例外です。

1 スーパークラス:

Title: NotImplementedError

実装されていない機能が呼び出されたときに発生します。

1 スーパークラス:

Title: SyntaxError

シンタックスエラーがあったときに発生します。

1 スーパークラス:

Title: IndexError

添字が範囲外のときに発生します。

1 スーパークラス:

Title: IOError

I/O でエラーが起きたときに発生します。

1 スーパークラス:

Title: NoMethodError

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)

1 スーパークラス:

Title: RangeError

範囲に関する例外。範囲外の数値変換 (Bignum から Fixnum へ の変換)などにより発生します。

1 スーパークラス:

Title: FloatDomainError

正負の無限大や NaN(Not a Number) を Bignum に変換しようと したり、NaN との比較を行ったときに発生します。 *86

1 スーパークラス:

Title: RegexpError

正規表現のコンパイルに失敗した場合に発生します。

Regexp.new("*")
=> in `initialize': invalid regular expression; there's no previous \
   pattern, to which '*' would define cardinality at 1: /*/ (RegexpError)

1 スーパークラス:

Title: SystemCallError

システムコールが失敗した時に発生する例外です。実際には SystemCallError そのものではなく、サブクラスである Errno モジュールの内部クラス(各errnoと同じ名前)です。

1 スーパークラス:

2 クラスメソッド:

SystemCallError === other ((<ruby 1.7 feature>))

otherSystemCallError のサブクラスであれば真です。 (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>

3 メソッド:

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 定数を使用してください。

Title: SystemStackError

スタックレベルが深くなりすぎたときに発生します。

1 スーパークラス:

Title: ThreadError

Thread 関連のエラーが起きたときに発生します。

1 スーパークラス:

Title: ZeroDivisionError

0 で除算を行ったときに発生します。

1 スーパークラス:

Title: 添付ライブラリ

Ruby は、ライブラリによるクラスやモジュール、メソッドの追加などの拡張 を行うことができます。以下は、標準で添付/配布されているライブラリの一 覧です。ライブラリの読み込みには requireload を使用します。

1 添付ライブラリ一覧

テキスト /ファイル /ネットワーク /入出力 /日本語 /数学 /データベース /画面制御/CUI /GUI /日付・時間 /マルチスレッド・同期 /Unix /MS Windows /正規表現 /GC /デザインパターン /開発ツール /コマンドライン /その他

2 カテゴリ別

*88

2.1 テキスト

2.2 ファイル

2.3 ネットワーク

2.4 入出力

2.5 日本語

2.6 数学

2.7 データベース

2.8 画面制御/CUI

2.9 GUI

2.10 日付・時間

2.11 マルチスレッド・同期

2.12 Unix

2.13 MS Windows

2.14 正規表現

2.15 GC

2.16 デザインパターン

2.17 開発ツール

2.18 コマンドライン

2.19 その他

Title: cgi/session.rb

--> CGI::Session

Title: CGI::Session

[2001/08/26] by るびきち

1 概要

CGIのセッション管理を行うライブラリ。 セッションとは、複数回のHTTPリクエストで一連の動作をさせるものである。*90 セッション管理には従来通り、cgi.rbが提供するクッキーを使用してもいいが、このcgi/session.rbを使用した方がよりわかりやすい。 セッション情報はHashライクなインターフェースである。

このcgi/session.rbを使うと、セッション情報はサーバ側で管理し、クライアントにはそのセッション情報に対応するセッションIDをクッキーで渡すことになる。 そのクッキーはexpiresが指定されていないために、ブラウザを終了した時点で消滅する。

2 使い方

2.1 生成

cgi = CGI::new
session = CGI::Session::new( cgi [, aHash] )

CGI::Session::newにCGIオブジェクトを渡す。 オプション引数 aHash で使えるキーとその意味は次の通り。

"session_path"

クッキーのpathとして使われる. (default: File::dirname(ENV["SCRIPT_NAME"]), スクリプトのURIのpath部の最後のスラッシュまで)

"session_key"

クッキーと<FORM type=hidden>のnameとして使われる. (default: "_session_id")

"session_id"

セッションIDとして使われる. デフォルトのデータベースであるFileStoreを用いる場合, 値は英数字だけからなる文字列で無ければならない. このオプションが指定するとリクエストにセッションIDが含まれても無視される. (default: ランダムに生成される)

"new_session"

値がtrueのとき強制的に新しいセッションを始める. このオプションが指定するとリクエストにセッションIDが含まれても無視される. (default: false)

"database_manager"

データベースクラス. (defalut: CGI::Session::FileStore)

"tmpdir"

CGI::Session::FileStore がセッションデータを作成するディレクトリの名前. (default: ENV["TMP"] || "/tmp")

"prefix"

CGI::Session::FileStore がセッションデータのファイル名に与えるプレフィックス. (default: "")

2.2 セッション情報を記録する

session['name'] = "rubikitch"

CGI::SessionオブジェクトはHashのようなものであり、キーに対応する値を記録する。

2.3 セッション情報を得る。

name = session['name']

別なCGIでこのセッション情報を取り出すときは、このようにする。

2.4 ヘッダ出力

ヘッダ出力はCGI#out、CGI#headerを使っている限り、通常通りで構わない。 cgi/session.rbは内部的にクッキーを使用しているが、これらのメソッドが面倒を見てくれるので、意識をする必要はない。

2.5 umask値

umask値が0022ならばセッション情報ファイルのパーミッションが644になるので、任意のユーザがそのセッション情報ファイルを見ることができる。 それが嫌な場合はCGI::Sessionオブジェクト生成前にumask値を設定しておこう。

3 使用例

ただ、名前を入力するとあいさつをするだけのつまらないCGI。

デモ会場はこちら

3.1 ソースコード

#!/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

4 参考URL

Title: cgi-lib.rb

このライブラリはobsoleteです。 cgi.rbを使ってください。

Title: CGI

[2001/03/17] by るびきち

CGIサポートライブラリ

Version 2.1.0

1 使用例

1.1 フォームの値を取得

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')

1.2 フォームの値をHashで取得

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                          # 全パラメータを消去

1.3 フォームの値をファイルに保存

require "pstore"
db = PStore.new("query.db")
db.transaction do
  db["params"] = cgi.params
end

PStoreを参照。

1.4 ファイルからfield nameを読み込む

require "pstore"
db = PStore.new("query.db")
db.transaction do
  cgi.params = db["params"]
end

1.5 マルチパートなfield nameを取得

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クラスのメソッドを持つ。)

1.6 フォームの値が入っているものとしてローカルで実験

CGI::CGI_PARAMSCGI::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"

1.7 クッキーの値を取得

require "cgi"
cgi = CGI.new
values = cgi.cookies['name']  # <== 'name' の配列
  # 'name'が与えられてない場合は[]を返す。
names = cgi.cookies.keys      # <== クッキーの名前の配列

また、cgi.cookiesはHashである。

1.8 クッキーオブジェクトを取得

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"}

あと、クッキーオブジェクトを作るを見ること。

1.9 環境変数を取得

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_lengthserver_portIntegerを返し、その他はStringを返す。

HTTP_COOKIEHTTP_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

1.10 $DEFAULT_OUTPUT ($>)へHTTPヘッダとHTML文字列を出力

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

2 メソッド

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>&lt;A HREF="url"&gt;&lt;/A&gt"

print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
  # => "<BR>&lt;A HREF="url"&gt;&lt;/A&gt"
CGI.unescapeElement(string, *element)

特定の要素だけをHTMLエスケープから戻す。

例:          
print CGI::unescapeElement(
        CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
  # => "&lt;BR&gt;<A HREF="url"></A>"

print CGI::unescapeElement(
        CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
  # => "&lt;BR&gt;<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

2.1 CGI::Cookie

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>

3 さまざまな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

3.1 A要素

CGI::HtmlExtension#a(href = "")

例:
a("url")
  # = a({ "HREF" => "url" })

3.2 BASE要素

CGI::HtmlExtension#base(href = "")

例:
base("url")
  # = base({ "HREF" => "url" })

3.3 BLOCKQUOTE要素

CGI::HtmlExtension#blockquote(cite = nil)

例:
blockquote("url"){ "string" }
  # = blockquote({ "CITE" => "url" }){ "string" }

3.4 CAPTION要素

CGI::HtmlExtension#caption(align = nil)

例:
caption("align"){ "string" }
  # = caption({ "ALIGN" => "align" }){ "string" }

3.5 CHECKBOX

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 })

3.6 CHECKBOXグループ

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"] })

3.7 ファイルフィールド

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">

3.8 FORM要素

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>

3.9 hiddenフィールド

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">

3.10 HTML要素

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" }

3.11 IMAGEボタン

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">

3.12 IMG要素

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">

3.13 マルチパートフォーム

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>

3.14 パスワードフィールド

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">

3.15 ポップアップメニュー

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>

3.16 ラジオボタン

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">

3.17 ラジオグループ

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"] })

3.18 リセットボタン

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">

3.19 スクロールリスト

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>

3.20 SUBMITボタン

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">

3.21 テキストフィールド

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">

3.22 TEXTAREA要素

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 })

4 HISTORY

Title: complex.rb

--> Complex

1 関数:

Complex(x, y)

2 Numeric

2.1 メソッド:

im
real

実部。

image

虚部。

arg
polar
conjugate

Title: Complex

執筆者募集

1 スーパークラス:

2 クラスメソッド:

Complex::polar

3 メソッド:

self + other
self - other
self * other
self / other
self % other
self ** other
divmod -- obsolete
abs
abs2
arg
polar
conjugate
self <=> other
self == other
to_i
to_f
to_r
to_s

4 定数

I

虚数単位。

Title: curses.so

端末ライブラリ curses のインターフェイス。

(?) がついているのはわからないもの。

(!) がついているものは(青木が)仕様を変えるべきだと 思ったところです。

1 Curses モジュール

1.1 モジュール関数

init_screen

スクリーンを curses のために初期化します。 Curses モジュールのすべてのメソッドはこのメソッドを 呼び出してからでないと使えません。

close_screen

curses スクリーンを閉じます。これ以後 Curses モジュール のメソッドを呼び出すとすべて例外になります。

stdscr

画面全体を表す Curses::Window オブジェクトを返します。

refresh

stdscr の表示を更新します。

doupdate

(?) wnoutrefresh と組み合わせないと意味ない?

clear

stdscr の文字を消去します。 この消去は refresh を待たずにすぐ実行されます。

echo

入力のエコーを有効にします。

noecho

入力のエコーをやめます。

cbreak
crmode

キーボード入力のバッファリングをやめます。

nocbreak
nocrmode

キーボード入力のバッファリングを有効にします。

nl

cooked モードのとき、return キーの入力に対して LF (Ctrl-j) を返すようにします。

nonl

cooked モードのとき、return キーの入力に対して CR (Ctrl-m) を返すようにします。

raw

キーボード入力のバッファリングと Ctrl-C など 特殊キーの処理をやめます (raw モード)。

noraw

キーボード入力のバッファリングと Ctrl-C など 特殊キーの処理を行うようにします (cooked モード)。

beep

音を出します。 この機能がないところでは単に無視されます。

flash

画面を一瞬点滅させます。 この機能がないところでは単に無視されます。

getch

標準入力から 1 バイト読み込みます。 返り値は ASCII コードを示す整数です。

getstr

標準入力から一行読み込みます。 返り値は文字列です。

このメソッドは getnstr() が実装されていない プラットホームではバッファオーバーフローをおこす恐れが あります。

ungetch(ch)

文字 ch (ASCII コードを示す整数)を押し戻します。

setpos(y, x)

stdscr のカーソルを座標 (x,y) に移動します。 座標はともに 0 が始点です。

文字がない場所に setpos して文字をなにも書かずに refresh するといきなりプロセスが終了してしまうライブラリが あるようだ(?) 例:linux のノーマル curses

standout

以降書き込む文字を強調します。 「強調」は反転であることが多いようですが、 そう決められているわけではありません。

standend

強調する文字の書き込みを終えます。

addch(ch)

stdscr のカーソルの位置に ch (1 バイト)を上書きします。

insch(ch)

stdscr のカーソルの位置に ch (1 バイト)を挿入します。

addstr(str)

stdscr のカーソルの位置に文字列 str を挿入します。

delch

stdscr のカーソルの位置から 1 バイト削除します。

deleteln

stdscr のカーソルがある行を削除し、後の行を上に詰めます。

lines

画面に表示可能な行数を返します。

cols

画面に表示可能な桁数(バイト)を返します。 ただし実際にはもう 1 バイト少なくしか表示できないライブラリが あるようです。

inch

stdscr のカーソル位置から 1 バイト読みとって返します。

2 Curses::Window クラス

2.1 クラスメソッド

new(height, width, y, x)

画面の座標 (x,y) を左上端とし、幅 width 高さ height とする curses のトップレベルウィンドウを 作成し、それを表現する Curses::Window オブジェクトを 返します。

2.2 メソッド

subwin(height, width, y, x)

画面の座標 (x,y) を左上端とし、幅 width 高さ height とするサブウィンドウを作成し、 それを表現する Curses::Window オブジェクトを返します。

close

ウィンドウを閉じます。以降のこのウィンドウオブジェクトに 対する操作は例外を発生します。

clear

ウィンドウの表示を消去します。 この操作は即座に実行されます。

refresh

ウィンドウの表示を更新します。

box(ver_char, hor_char)

縦の線に ver_char、横の線に hor_char を使い ウィンドウに沿って箱を書きます。線は普通にウィンドウ内に 書かれるだけなので上書きしないよう注意してください。

move(y, x)

ウィンドウを (x,y) に移動します。

(!) 親ウィンドウからはみだす位置を指定すると無視されます。

setpos(y, x)

ウィンドウ内の (x,y) にカーソルを移動します。

cury

ウィンドウ内におけるカーソルの行番号を返します。 一行目が 0 です。

curx

ウィンドウ内におけるカーソルの桁番号を返します。 一桁目が 0 です。

maxy

移動可能な最大の y 座標を返します。 表示可能な行 + 1 です。

maxx

移動可能な最大の x 座標を返します。 表示可能なバイト数 + 1 です。

begy

親ウィンドウの中でウィンドウの左上がある y 座標を返します。 始点は 0 です。

begx

親ウィンドウの中でウィンドウの左上がある x 座標を返します。 始点は 0 です。

standout

以後書き込む文字を強調表示します。

standend

強調書き込みを終了します。

inch

ウィンドウのカーソル位置から 1 バイト読みとって返します。

addch(ch)

ウィンドウのカーソル位置に ch (1 バイト)を上書きします。

insch(ch)

ウィンドウのカーソル位置に ch (1 バイト)を挿入します。

addstr(str)
self << str

ウィンドウのカーソル位置に文字列 str を上書きします。

getch

ウィンドウへの入力から 1 バイト読みこみます。

getstr

ウィンドウへの入力から一行読みこみます。

delch

ウィンドウのカーソル位置から 1 バイト消去します。

deleteln

ウィンドウの、カーソルがある行を消去します。

Title: date.rb

--> Date

1 Date

1.1 スーパークラス

Object

1.2 インクルードしているモジュール

Comparable

1.3 クラスメソッド

exist2?(year, day-of-year[, start=ITALY])

正しい年日付であれば、相当するユリウス日を返します。 そうでないなら、偽を返します。

new1、および new2 も参照してください。
exist3?(year, month, day-of-month[, start=ITALY])
exist? (year, month, day-of-month[, start=ITALY])

正しい暦日付であれば、相当するユリウス日を返します。 そうでないなら、偽を返します。

new1、および new3 も参照してください。

existw?(year, week, day-of-week[, start=ITALY])

正しい暦週であれば、相当するユリウス日を返します。 そうでないなら、偽を返します。

new1、および neww も参照してください。

new1([jd=0[, start=ITALY]])

ユリウス日に相当する日付オブジェクトを生成します。

ユリウス日は 紀元前4713年1月1日 (ユリウス暦) 正午 (グリニッジ平均時) を 暦元とした通日 (経過日数) です。

このクラスで、ユリウス日は、 ただ日付の通し番号として使われます; 故に、 普通は端数はありません (それは正午であることを示します)。

このクラスのいくつかの重要なメソッドで、 負のユリウス日は保証されません。

new3 も参照してください。

new2([year=-4712[, day-of-year=1[, start=ITALY]]])

年日付に相当する日付オブジェクトを生成します。

年日付は、暦年 (年)、 および暦年の中の序数 (年の日) によって指定される特定の日の日付です。

月の日は負、 または正の数でなければなりません (負のときは最後からの序数)。 零であってはなりません。

new1、および new3 も参照してください。

new3([year=-4712[, month=1[, day-of-month=1[, start=ITALY]]]])
new ([year=-4712[, month=1[, day-of-month=1[, start=ITALY]]]])

暦日付に相当する日付オブジェクトを生成します。

暦日付は、暦年 (年)、暦月 (月)、 および暦月の中の序数 (月の日) によって指定される特定の日の日付です。

このクラスでは、紀元前の年を天文学の流儀で勘定します。 1年の前は零年、零年の前は-1年、のようにします。

月、および月の日は負、 または正の数でなければなりません (負のときは最後からの序数)。 零であってはなりません。

省略できる最後の引数は、 グレゴリオ暦をつかい始めた日をあらわすユリウス日でなければなりません。 ビッグバンの代わりに真 (グレゴリオ暦の指定)、 ビッグクランチの代わりに偽 (ユリウス暦の指定) を与えることもできます。

new1 も参照してください。

neww([year=1582[, week=41[, day-of-week=5[, start=ITALY]]]])

暦週に相当する日付オブジェクトを生成します。

暦週は、暦年中の序数によって指定される特定の7日の期間であり、 月曜から始まります。 その年の第1暦週は、最初の木曜日を含む週とします。 これは、1月4日を含む週と同じです。

週、および週の日 (曜日) は負、 または正の数でなければなりません (負のときは最後からの序数)。 零であってはなりません。

このメソッドに改暦前の日付を与えることはできません。

new1、および new3 も参照してください。

today([start=ITALY])

現在の日付に相当する日付オブジェクトを生成します。

1.4 メソッド

self + n

self から n 日後の日付オブジェクトを返します。 n は数値でなければなりません。

self - x

x が日付オブジェクトなら、ふたつの差を返します。 あるいは x が数値ならば、self より x 日前の日付を返します。

self << n

self より n ヶ月前の日付オブジェクトを返します。 n は数値でなければなりません。

self <=> other

ふたつを比較し、-1、零、あるいは 1 を返します。 other は日付オブジェクトか、ユリウス日をあらわす数値でなければなりません。

self === other

同じ日なら真を返します。

self >> n

self から n ヶ月後の日付オブジェクトを返します。 n は数値でなければなりません。

cwday

暦週の日 (曜日) を返します (1-7、月曜は1)。

cweek

暦週を返します (1-53)。

cwyear

暦週における年を返します。

downto(min){|date| ...}

このメソッドは、step(min, -1){|date| ...} と等価です。

england

このメソッドは、newsg(Date::ENGLAND) と等価です。

gregorian

このメソッドは、newsg(Date::GREGORIAN) と等価です。

italy

このメソッドは、newsg(Date::ITALY) と等価です。

jd

ユリウス日を返します。

julian

このメソッドは、newsg(Date::JULIAN) と等価です。

ld

リリウス日を返します。

リリウス日は、西暦1582年10月15日 (グレゴリオ暦) を暦元とした通日です。

leap?

閏年なら真を返します。

mday
day

月の日を返します (1-31)。

mjd

修正ユリウス日を返します (正午として)。

修正ユリウス日は 西暦1858年11月17日 (グレゴリオ暦) 零時 (協定世界時) を 暦元とした通日 (経過日数) です。

mon
month

月を返します (1-12)。

newsg([start=Date::ITALY])

self を複製して、その改暦日を設定しなおします。

new3 も参照してください。

sg

改暦日をあらわすユリウス日を返します。

new3 も参照してください。

step(limit, step){|date| ...}

ブロックの評価を繰り返します。ブロックは日付オブジェクトをとります。 limit は日付オブジェクトでなければなりません、 また step は非零でなければなりません。

succ
next

翌日の日付オブジェクトを返します。

tjd

切詰ユリウス日を返します (正午として)。

このクラスで、切詰ユリウス日は 西暦1968年5月24日 (グレゴリオ暦) 零時 (協定世界時) を 暦元とした通日 (経過日数) です。

TJD の使用はまったく勧められません

tjd2

"FLOOR(tjd/10000)" と "tjd MOD 10000" の対を返します。 ふたつ目の要素は、もうひとつの TJD です。 それは、本当の TJD かもしれません。 CCSDS 301.0-B-2 を参照してください。

TJD の使用はまったく勧められません

to_s

ISO 8601:1988 書式 (CCYY-MM-DD) の文字列を返します。

upto(max){|date| ...}

このメソッドは、step(max, 1){|date| ...} と等価です。

wday

曜日を返します (0-6、日曜日は零)。

yday

年の日を返します (1-366)。

year

年を返します。

Title: date2.rb

このライブラリは date.rb に置き換えられました

Title: dbm.so

--> DBM

Title: DBM

NDBMファイルをアクセスするクラス。キー、データともに文字列でなければな らないという制限と、データがファイルに保存されるという点を除いては Hashクラスと全く同様に扱うことがでます。

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

open(dbname[, mode])

dbnameで指定したデータベースをモードを modeに設定してオープンします。modeの省 略値は0666です。modeとしてnilを指定 するとデータベースが存在しない時には新たなデータベースを作らず nilを返します。

4 メソッド:

self[key]

keyをキーとする値を返します。

self[key]=value

keyをキーとして、valueを格納します。 valueとしてnilを指定すると、keyに対 する項目を削除します。

clear

DBMファイルを空にします。

close

DBMファイルをクローズします。以後の操作は例外を発生させます。

delete(key)

keyをキーとする項目を削除します。

delete_if { |key, value| ... }

ブロックを評価した値が真であれば該当する項目を削除します。

each {|key, value| ... }
each_pair {|key, value| ... }

各要素に対するイテレータ。

each_key {|key| ... }

全てのkeyに対して繰り返すイテレータ。

each_value {|value| ... }

全てのvalueに対して繰り返すイテレータ。

empty?()

データベースが空の時、真を返します。

has_key?(key)
key?(key)
include?(key)

keyがデータベース中に存在する時、真を返します。

has_value?(key)
value?(value)

valueを値とする組がデータベース中に存在する時、真を返します。

indexes(key_1, ... )
indices(key_1, ... )

各引数の値をキーとする要素を含む配列を返します。

keys

データベース中に存在するキー全てを含む配列を返します。

length
size

データベース中の要素の数を返します。(注意:現在の実現では要素数を数 えるためにデータベースを全部検索します)

shift

データベース中の要素を一つ取り出し、データベースから削除します。

values

データベース中に存在する値全てを含む配列を返します。

Title: delegate.rb

1 目的・概要

メソッドの委譲(delegation)を行う。

Delegatorクラスは指定したオブジェクトにメソッドの実行を委譲する。 Delegatorクラスを利用する場合はこれを継承して__getobj__メソッドを 再定義して委譲先のオブジェクトを指定する。

SimpleDelegatorはDelegatorの利用例の一つであり、コンストラクタに 渡されたオブジェクトにメソッドの実行を委譲する。

関数DelegateClass(supperclass)はsuperclassクラスの オブジェクトをひとつとり、そのオブジェクトにインスタンスメソッドを委譲す るクラスを定義して返す。

2 クラス

3 サンプルコード

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]

4 Delegator

与えられたオブジェクトの持つメソッドに関して委譲用のメソッド定義を 提供するクラス。

コンストラクタで指定されたオブジェクトのもつインスタンスメソッドのうち、 自分の持たないメソッドについて、 __getobj__が返すオブジェクトに実行を委譲するようメソッドを定義する。

4.1 インスタンスメソッド

Delegator#initialize(obj)

objのもつインスタンスメソッドのうち、 自分の持たないメソッドについて、 __getobj__が返すオブジェクトに実行を委譲する ようインスタンスメソッドを定義する。

Delegator#__getobj__

委譲先のオブジェクトを返す。 デフォルトではNotImplementErrorを発生するので、サブクラスで 再定義する必要がある。

5 SimpleDelegator

Delegatorクラスをそのまま利用した、 指定したオブジェクトにメソッドを委譲するクラス。

上位クラス

Delegator

5.1 クラスメソッド

SimpleDelegator.new(obj)

objがもつメソッドについて、実行をobjに委譲する

オブジェクトを生成する。

5.2 インスタンスメソッド

SimpleDelegator#__getobj__

委譲先のオブジェクトを返す。

SimpleDelegator#__setobj__(obj)

委譲先のオブジェクトをobjに変更する。

委譲するメソッドの定義は生成時にのみ行われるため、 以前の委譲先オブジェクトとobjの間でインスタンスメソッドに 違いがあっても、 委譲するインスタンスメソッドの再設定は行われないことに注意。

6 関数

DelegateClass(superclass)

クラスsuperclassのインスタンスへメソッドを委譲するクラスを 定義し、そのクラスを返す。

7 SEE ALSO

Object#method_missing(method_symbol, ...)

メソッドがオブジェクトに定義されていなかったときにこのメソッドが 呼ばれる。これを使って自分の知らないメソッドをほかのオブジェクト に委譲することができる。

例:

def hoge.method_missing(message, *arg)
    @to_obj.send(message, *arg)
end

Title: digest.so

メッセージダイジェストライブラリ ext/digest/digest.txt を参照

Title: e2mmap.rb -- Exception2MessageMapper

例外クラスに特定のエラーメッセージ用フォーマットを関連づけます。

1 Usage

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...

2 Methods

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 の別名です。

Title: Exception2MessageMapper

--> e2mmap.rb

Title: eregex.rb

1 目的・概要

2つの正規表現によるAND/ORを提供する。

Regexpクラスに&と|のメソッドを定義し、それぞれ 2つの正規表現の両方にマッチすれば真となるもの(RegAnd)と いずれかにマッチすれば真となるもの(RegOr)を返す。 RegAnd、RegOrは=~のみサポートしている。

2 サンプルコード

require 'eregex'
p "abc" =~ /b/|/c/
p "abc" =~ /b/&/c/

3 class Regexp

組み込みクラスRegexpを拡張して次のメソッドを定義している。

3.1 インスタンスメソッド

Regexp#&(other)

RegAnd(self,other)を返す

Regexp#|(other)

RegOr(self,other)を返す

4 class RegAnd

4.1 インスタンスメソッド

RegAnd#initialize(reg1,reg2)

コンストラクタ

RegAnd#=~(str)

strreg1reg2の両方にマッチすれば真を返す

5 class RegOr

5.1 インスタンスメソッド

RegOr#initialize(reg1,reg2)

コンストラクタ

RegOr#=~(str)

strreg1reg2のいずれかにマッチすれば真を返す

Title: etc.so

--> Etc

Title: Etc

/etcディレクトリ以下の情報を得るためのモジュール。クラスにインクルード して使うこともできる。

1 使い方:

require "etc.so"

p Etc.getlogin

2 モジュール関数:

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エントリを順にアクセスするためのイテレータ。

Title: expect.rb

IO#expect(pat, [timeout])

--> ruby-src:ruby/ext/pty/README.expect.ja

Title: fcntl.so

--> Fcntl

Title: Fcntl

Unix のシステムコール fcntl(2) (つまり IO#fcntl)で使用できる定数 を集めたモジュールです。定義される 定数は以下の通りです

1 定数:

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

Title: final.rb

このライブラリで定義されていたメソッドは ruby 本体に組み込まれたため このライブラリ自体は obsolete になりました。

Title: finalize.rb

--> Finalizer

Title: Finalizer

執筆者募集

Title: find.rb

--> Find

Title: Find

ディレクトリ配下のファイルを探索するためのモジュールです。

1 使い方:

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

2 モジュール関数:

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メソッドのブロックにディレクトリが渡されたときにこ のメソッドを実行すると、そのディレクトリ配下の探索を無視します。

3 履歴:

version 1.4 (ruby version 1.6.1)

ディレクトリのシンボリックリンクを辿らなくなりました。

Title: forwardable.rb

クラスに対してメソッドの委譲機能を定義します。 以下のモジュールが定義されます。

詳細は ruby-src:ruby/doc/forwardable.rd.ja を参照

Title: Forwardable

詳細は ruby-src:ruby/doc/forwardable.rd.ja を参照

Title: SingleForwardable

詳細は ruby-src:ruby/doc/forwardable.rd.ja を参照

Title: ftools.rb

1 概要

require 'ftools' とすると、ファイルのコピーや削除などのメソッドが追加される。 to は新たなファイル名かディレクトリ名。 verbose が真のとき、標準エラー出力に処理の経過が出る。

2 メソッド

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.chmodverbose の指定が 追加されるだけ。

File.install(from, to[, mode = nil[, verbose = false]])

ファイルをコピーし、モードを設定する。 コピー先が存在する場合は一旦削除されるので、コピー先のファイルが 他のファイルにハードリンクされていれば、そのリンクは切れる。 install (install(1))コマンドに相当。

Title: gdbm.so

--> GDBM

Title: GDBM

GDBMファイルをアクセスするクラス。キー、データともに文字列でなければな らないという制限と、データがファイルに保存されるという点を除いては Hashクラスと全く同様に扱うことがでます。

1 スーパークラス:

2 インクルードしているモジュール:

3 クラスメソッド:

new(dbname[, mode[, flags]])
open(dbname[, mode[, flags]])
open(dbname[, mode[, flags]]) {|db| ...}

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

4 メソッド:

self[key]

keyをキーとする値を返します。

self[key]=value

keyをキーとして、valueを格納します。

cachesize = size
clear

DBMファイルを空にします。

close

DBMファイルをクローズします。以後の操作は例外を発生させます。

delete(key)
delete(key) {|key| ... }

keyをキーとする項目を削除します。

指定したキーが存在しなければnilを返します、このとき ブロックを指定していれば、ブロックを評価します。

delete_if { |key, value| ... }
reject! { |key, value| ... }

ブロックを評価した値が真であれば該当する項目を削除します。

each {|key, value| ... }
each_pair {|key, value| ... }

各要素に対するイテレータ。

each_key {|key| ... }

全てのkeyに対して繰り返すイテレータ。

each_value {|value| ... }

全てのvalueに対して繰り返すイテレータ。

empty?

データベースが空の時、真を返します。

fastmode = bool
syncmode = bool

オープンしているGDBMオブジェクトのモードを変更します。下記の定数 GDBM::FAST、GDBM::SYNC を参照してください。

fetch(key[,ifnone])
fetch(key) {|key| ... }

ハッシュと同じ

has_key?(key)
key?(key)
include?(key)
member?(key)

keyがデータベース中に存在する時、真を返します。

has_value?(key)
value?(value)

valueを値とする組がデータベース中に存在する時、真を返します。

index(val)

ハッシュと同じ

indexes(key_1, ... )
indices(key_1, ... )

各引数の値をキーとする要素を含む配列を返します。

invert

値からキーへのハッシュを返します。

keys

データベース中に存在するキー全てを含む配列を返します。

length
size

データベース中の要素の数を返します。(注意:現在の実現では要素数を数 えるためにデータベースを全部検索します)

reject {|key, value| ... }

self.to_hash.reject と同じです。ハッシュを返します。

reorganize

GDBMでは、要素の削除を行ってもDBファイルのサイズは減少しません(削 除によって空いた領域は次の格納のために取っておかれます、)。このメ ソッドを呼び出すことでDBMファイルを新規に作り直し無駄な領域をなく すことができます。

大量の削除を行ったときに、ディスクスペースの節約のために使用します。

replace(other)

DBMの内容を other の内容で置き換えます。 other は each_pair メソッドを持つオブジェクトで なければなりません。

shift

データベース中の要素を一つ取り出し、データベースから削除します。

store(key, val)

self[key]=val と同じです。keyに対してvalを格納します。

sync

要素の変更をファイルに反映します。FASTモード (GDBM#open() の第3引数にGDBM::FAST を指定)のときだけ意味があります。

注) GNU gdbm version 1.8 以降よりFASTモードがデフォルトになりました。

to_a

DBMの各要素を格納した配列を返します。返される配列の1つの要素は [key, val] です。(つまり配列の配列を返します)。

to_hash

DBMの各要素を格納したハッシュを返します。

update(other)

DBMとotherの内容をマージします。重複するキーに対応する値は otherの内容で上書きされます。

otherは each_pair メソッドを持つオブジェクトでなければなりま せん。

values

データベース中に存在する値全てを含む配列を返します。

5 定数

GDBM::VERSION

libgdbm のバージョン情報の文字列です。

以下の定数は open の第3引数に指定します。

GDBM::FAST

書き込みの結果が、ディスク上のファイルにすぐに反映しなくなります。 このモードのときに結果を明示的にファイルに反映させるには GDBM#sync メソッドを呼びます。libgdbm version 1.8.0 以降ではこのモードがデフォルト です。

GDBM::SYNC

書き込みの結果が、ディスク上のファイルにすぐに反映されます。 libgdbm version 1.8.0 以前のデフォルトモードです。

この定数は libgdbm version 1.8.0 以降より有効です

GDBM::NOLOCK

通常、他のプロセスがDBをオープンしている最中にオープンを行うと Errno::EWOULDBLOCK(またはErrno::EAGAIN)例外が発生します。このフラグを 指定していれば、他のプロセスがオープンしている最中でも同時オープンする ことができます。

この定数は libgdbm version 1.8.0 以降より有効です。

Title: getoptlong.rb

詳細は <URL:http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/> を参照

Title: getopts.rb

Author: <jammy@shljapan.co.jp>

オプションを解析し、$OPT_xxx に値を設定します。

1 書式:

getopts(SINGLE_OPTS、*OPTS)
第一引数:

`-f'や`-x(=-fx)'の様な一文字のオプションの指定をします。オプショ ンが`-f'と`-x'の2つの場合は`"fx"'の様に指定します。ここでオプシ ョンがないときは必ず`nil'を指定して下さい。

第二引数:

ロングネームのオプションや、引数を伴うオプションの指定をします。 `--version'や`--geometry 300x400'、`-d host:0.0'等がこれに該当し ます。引数を伴う指定は ":" を必ず付ける様にします。この例の場合、 "version"、"geometry:"、"d:" の様になります。 また、オプションを 指定しなかった場合のデフォルトの値を持たせたい場合は、":"の直後に そのデフォルト値を指定します。例えば、"geometry:80x25" の様になり ます。

2 オプション解析:

解析結果は全て "$OPT_指定した引数名" という形で処理されます。

3 戻り値:

実際にセットされたオプションの数を返します。また、間違ったオプショ ンを指定した場合は、`nil'を返します。

Title: irb.rb

--> ruby-src:ruby/doc/irb/irb.rd.ja

Title: jcode.rb

[2001/02/27] by CozoH [2001/03/08] by るびきち

1 概要

Stringクラスのメソッドを追加、再定義し、 日本語を意識した文字列処理を提供します。

2 使用例

*91[2001/03/08]るびきち:$KCODEを指定しないと結果がおかしいので注意。

require 'jcode'
$KCODE='e' # 漢字コードをEUCに。Windowsでは 's' 
print 'abcdef'.tr( 'a-z', 'A-Z' ), "\n"

3 追加メソッド

each_char
each_char {|char| ... }

文字列中の各文字に対して繰り返します。 ブロックを指定せずに呼び出された時には、各文字の配列を返します。

例:

#!/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+
end_regexp

最後の文字が多バイト文字である文字列にマッチする正規表現を返します。 再定義されたString#succで内部的に使われます。

jcount(str)

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
jlength
jsize

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
mbchar?

selfに多バイト文字が最初に現れる位置を返します。 多バイト文字が含まれていなければnilを返します。

例:

#!/usr/bin/env ruby
$KCODE='e'
zstr='ABCDEF'
hoge='hogehoge'

require 'jcode'

p zstr.mbchar? # => 0
p hoge.mbchar? # => nil

4 再定義メソッド

それぞれのメソッドに!がついているものは破壊的メソッドです。

chop
chop!

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
delete(str)
delete!(str)

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
squeeze([str])
squeeze!([str])

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
succ
succ!

String#succの日本語対応版です。

以下のようなの文字列を返します。

"あaあ".succ => "あaぃ"
"rb".succ => "rc"
"_紅玉".succ => "_紅桐"

従来のString#succは、 多バイト文字と半角文字が混在している文字列を 意図通りに処理することができません。 例えば上記のコードは、それぞれ "あbあ""sb""_紘玉"を返します。

なお、"99"の次は"100"になるのに対し、 "99"の次は"100"にはならないことに注意。 "Az""zz"も同様です。 *92

tr(search, replace)
tr!(search, replace)

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
tr_s(search, replace)
tr_s!(search, replace)

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"

ありゃ?*93 *94

Title: kconv.rb

文字コードエンコーディングを変換するためのモジュール。

1 使用例

 

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

2 モジュール関数

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 の定数です。

3 String に追加されるメソッド

String#kconv(out_code, in_code = Kconv::AUTO)

self のエンコーディングを out_code に変換したのを 返します。out_code in_codeKconv の定数で 指定します。

String#tojis

self のエンコーディングを iso-2022-jp に変換した文字列を 返します。

String#toeuc

self のエンコーディングを euc-jp に変換した文字列を 返します。

String#tosjis

self のエンコーディングを shift_jis に変換した文字列を 返します。

4 定数

AUTO

エンコーディングを自動検出する。 入力の指定でのみ有効。

JIS

iso-2022-jp を表す。

EUC

euc-jp を表す。

SJIS

shift_jis (シフト JIS / MS 漢字コードとも言う) を表す。

BINARY

JIS EUC SJIS 以外

UNKNOWN

出力においては「エンコーディングを判定できなかった」 入力においては AUTO と同様に「自動検出」を表す。

Title: mailread.rb

--> Mail

Title: Mail

[2001/02/05] るびきち

シンプルなメールクラス。

1 mailread.rb 使い方

require 'mailread'

m = Mail.new('/var/mail/foo')
puts 'From: ' + m['From'],
     'Subject: ' + m['Subject'],
     '--',
     m.body[0,5]

2 クラスメソッド:

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

3 メソッド:

Mail#header

ヘッダを Hash で返す。 キーは 'From'、'Subject' などのフィールド名で、すべてのキーは String#capitalize されている。

値の末尾の改行は削除される。複数行に分かれている場合、間に改行を はさむ(継続行を表す空白は削除される)。MIME デコードなどを行いた い場合は NKF などを使用すること。

Mail#body

本文を行単位の Array で返す。

Mail#[field]

ヘッダの field の値を返す。 m.header[field.capitalize] と同じなので値取得の際は、フィー ルド名のアルファベットの大小を気にする必要はない。

Title: mathn.rb

[2001/02/20] るびきち *95

rational.rbcomplex.rbを補助する関数群。

本来 Floatととは異なり, Ratinalは誤差がないので,

1/2 -> 1/2 (Rational)
2 * Rational(1,2) -> 1 (Fixnum)

となってほしいこともあるかと思います. つまり, rubyのBignumとFixnumの様 な関係ですね. rubyではこれらの型変換は勝手に行なっています.

mathn.rbをインクルードするとこの様な動作を行ないます. つまり, Ratinal とComplexをBignumとFixnumと同等な関係にします.

1 Integer

1.1 クラスメソッド:

Integer.from_prime_division(pd)

素因数分解の配列pdから数を求める。 pd[素因数, 指数]組の配列である。

例:
Integer.from_prime_division [[2,3],[3,2]]
-> 72 # == 2**3 * 3**2

1.2 メソッド:

Integer#gcd2(int)

selfintの最大公約数を求める。

例:
12.gcd2 8
-> 4
Integer#prime_division

selfの素因数分解(の配列)を求める。

例:
72.prime_division
-> [[2, 3], [3, 2]]

2 Prime

2.1 インクルードしているモジュール:

2.2 クラスメソッド:

Prime.new

素数を生成するクラスを作る。

2.3 メソッド:

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

3 Fixnum

4 Bignum

5 Rational

Rational#**

べき乗。 RationalになるようであればRationalで返す。

Rational#power2

作りかけ(^^;;

6 Math

Math.sqrt(a)
Math.rsqrt(a)

*96

Title: matrix.rb

執筆者募集

Title: Matrix

執筆者募集 *97

1 クラスメソッド:

Matrix.[](*rows)

creates a matrix where `rows' indicates rows. `rows' is an array of arrays, e.g, Matrix[[11, 12], [21, 22]]

Matrix.rows(rows, copy = true)

creates a matrix where `rows' indicates rows. if optional argument `copy' is false, use the array as internal structure of the metrix without copying.

Matrix.columns(columns)

creates a new matrix using `columns` as set of colums vectors.

Matrix.diagonal(*values)

creates a matrix where `columns' indicates columns.

Matrix.scalar(n, value)

creates a diagonal matrix such that the diagal compornents is given by `values'.

Matrix.scalar(n, value)

creates an n-by-n scalar matrix such that the diagal compornent is given by `value'.

Matrix.identity(n)
Matrix.unit(n)
Matrix.I(n)

creates an n-by-n unit matrix.

Matrix.zero(n)

creates an n-by-n zero matrix.

Matrix.row_vector(row)

creates a 1-by-n matrix such the row vector is `row'. `row' is specifed as a Vector or an Array.

Matrix.column_vector(column)

creates a 1-by-n matrix such that column vector is `column'. `column' is specifed as a Vector or an Array.

2 accessing:

[](i, j)

returns (i,j) compornent

row_size

returns the number of rows

column_size

returns the number of columns

row(i)

returns the i-th row vector. when the block is supplied for the method, the block is iterated over all row vectors.

column(j)

returns the jth column vector. when the block is supplied for the method, the block is iterated over all column vectors.

collect
map

creates a matrix which is the result of iteration of given block over all compornents.

minor(*param)

returns sub matrix. parameter is specified as the following:

  1. from_row, row_size, from_col, size_col
  2. from_row..to_row, from_col..to_col

3 TESTING:

regular?

Is regular?

singular?

Is singular? i.e. Is non-regular?

square?

Is square?

4 ARITHMETIC:

*(m)

times

+(m)

plus

-(m)

minus

/(m)

self * m.inv

inverse
inv

inverse

**

power

5 Matrix functions:

determinant
det

returns the determinant

rank

returns the rank

trace
tr

returns the trace

transpose
t

returns the transposed

6 CONVERTING:

coerce(other)
row_vectors

array of row vectors

column_vectors

array of column vectors

to_a

converts each element to Array

to_f

converts each element to Float

to_i

converts each element to Integer

to_r

converts each element to Rational

7 PRINTING:

to_s

returns string representation

inspect

Title: Vector

執筆者募集 *98

1 INSTANCE CREATION:

Vector.[](*array)
Vector.elements(array, copy = true)

2 ACCSESSING:

[](i)
size

3 ENUMRATIONS:

each2(v)
collect2(v)

4 ARITHMETIC:

*(x) "is matrix or number"
+(v)
-(v)

5 VECTOR FUNCTIONS:

inner_product(v)
collect
map
map2(v)
r

6 CONVERTING:

covector
to_a
to_f
to_i
to_r
coerce(other)

7 PRINTING:

to_s
inspect

Title: md5.rb

digest/md5.so をロードして MD5 を Digest::MD5 に置き換えます

古い MD5 のマニュアルは以下

--> MD5

Title: MD5

RFC:1321に記述されているRSA Data Security, Inc. の MD5 Message-Digest Algorithmを実装するクラス。

1 スーパークラス:

2 クラスメソッド:

new([str])
md5([str])

新しいMD5オブジェクトを生成する。文字列引数が与えられるとそれ を追加する(see update)。

3 メソッド:

clone

MD5オブジェクトの複製を作る

digest

今までに追加した文字列に対するハッシュ値を16バイト長の文字列で返す。

hexdigest

今までに追加した文字列に対するハッシュ値を、ASCIIコードを使って 16進数の列を示す 'fe5c2235f48d2bcc911afabea23cd5aa' の ような32文字の文字列にエンコードして返す。Rubyで書くと以下と同じ。

def hexdigest
  ret = ''
  digest.each_byte {|i| ret << sprintf('%02x', i) }
  ret
end
update(str)

MD5オブジェクトに文字列を追加する。複数回updateを呼ぶことは文 字列を連結してupdateを呼ぶことと等しい。

Title: mkmf.rb

Ruby の拡張ライブラリのための Makefile を作成するライブラリです。通常 extconf.rb という名の ruby スクリプトの中で require され、このスクリプ トを実行することで Makefile を作成するのが慣習となっています。

拡張ライブラリの作り方(extconf.rbの書き方)に関しては ruby のアーカイブ に含まれる ruby-src:ruby/README.EXT (日本語版は ruby-src:ruby/README.EXT.ja)も参照してください。

1 使い方

架空の拡張ライブラリ 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 を参照してください。

2 configure オプション

ここでの configure オプションとは ruby インタプリタ作成時に指定された configure スクリプトのオプション、または extconf.rb 実行時のオプショ ンのことです。extconf.rb の作成者は任意のオプションを定義できます。 (arg_config を参照)。

また、以下のオプションがデフォルトで利用可能です。

--with-opt-include=directory

ヘッダファイルを探索するディレクトリ directory を追加します。

--with-opt-lib=directory

ライブラリファイルを探索するディレクトリ directory を追加します。

--with-opt-dir=directory

ヘッダファイル、ライブラリファイルを探索するディレクトリ directory/include、directory/lib をそれぞれ追加します。

--with-target-include=directory

extconf.rb の中で dir_config(target) を実行していればこ のオプションを指定できます。

ヘッダファイルを探索するディレクトリ directory を追加します。

--with-target-lib=directory

extconf.rb の中で dir_config(target) を実行していればこ のオプションを指定できます。

ライブラリを探索するディレクトリ directory を追加します。

--with-target-dir=directory

extconf.rb の中で dir_config(target) を実行していればこ のオプションを指定できます。

ヘッダファイル、ライブラリファイルを探索するディレクトリ directory/include、directory/lib をそれぞれ追加します。

3 depend ファイル

カレントディレクトリに 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 に出力する際に多少の加工を行う場合があります。

4 make ターゲット

extconf.rb が生成した Makefile には以下のターゲットが定義されています。

all

拡張ライブラリを作成します。

clean

作成した拡張ライブラリ、オブジェクトファイルなどを削除します。

distclean
realclean

clean に加えて Makefile extconf.h(create_header参照) core ruby などを削除します。

install

作成した拡張ライブラリを $archdir にインストールします。カレン トディレクトリにディレクトリ lib があればその配下の ruby スクリプト (.rb ファイル)をディレクトリ階層ごと $libdir にインストールし ます。

site-install

install と同様ですが、拡張ライブラリは $sitearchdir に、 ruby スクリプトは $sitelibdir にインストールされます。

5 関数

以下は、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の正 規表現を文字列で指定します。

CPP $CFLAGS opt | egrep pat

を実行し、その結果が正常かどうかを 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 に出力します。mfileIO クラスの インスタンスです。

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 が定義され ているかどうかを検査します。検査に成功すれば $libslib を追加し 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 オプションがいずれも指定されていなければ、省略可能な引数 deafultidefaultldefault が使用されます。最初 の形式では、"-Idefault/include""-Ldefault/lib" をそれぞれ追加し、二番目の形式では "-Iidefault""-Lldefault" をそれぞれ追加 します。

create_makefile(target[, srcdir])

have_libraryなどの各種検査の結果を元に 拡張ライブラリ target.so を作成する Makefile を生成します。

srcdir は make 変数 srcdir の値になり、これにはソー スがあるディレクトリ名を指定します。省略した場合は、 extconf.rb があるディレクトリです。

extconf.rb は普通このメソッドの呼び出しで終ります。

6 定数

CONFIG

Config::MAKEFILE_CONFIG と同じです。

CFLAGS

この値は、Makefileにも反映されます。

LINK

リンクを検査するときのコマンドラインのフォーマットです。 try_linkなどが使用します。

CPP

プリプロセスを検査するときのコマンドラインのフォーマットです。 try_cppなどが使用します。

7 グローバル変数

$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_funchave_header の検査結果はこの配列の要素になり

["-DHAVE_FUNC", "-DHAVE_HEADER_H"]

といった値になります。

create_header は、この変数の値を参照してヘッダファイルを生成 します。

$libs

拡張ライブラリをリンクするときに一緒にリンクされるライブラリを指定 する文字列です。

have_libraryfind_library の検査結果はこの文字列に

"-lfoo -lbar"

のように間に空白を置いて連結されます。

$CFLAGS

拡張ライブラリをコンパイルするときの C コンパイラのオプション、ヘッ ダファイルのディレクトリを指定する文字列です。

dir_config はこの変数に値 "-Idir" を追加します。

$LDFLAGS

拡張ライブラリをリンクするときのリンカのオプション、ライブラリファ イルのディレクトリを指定する文字列です。

find_librarydir_config はこの変数に値 "-Ldir" を追加 します。

Title: monitor.rb

執筆者募集

Title: MonitorMixin

執筆者募集

Title: mutex_m.rb

執筆者募集

Title: net/ftp

1 Net::FTP

1.1 スーパークラス

Object

1.2 クラスメソッド

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と同じです。

1.3 メソッド

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?

接続が切れている時に真を返します。

Title: net/http.rb version 1.2.1

1 このライブラリについて

汎用データ転送プロトコル HTTP を扱うライブラリです。 実装は [RFC2616] <URL:http://www.ietf.org/rfc/rfc2616.txt> に 基いています。

2 使用例

2.1 ウェブサーバからドキュメントを得る (GET)

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'

2.2 フォームの情報を送信する (POST)

require 'net/http'
Net::HTTP.start( 'some.www.server', 80 ) {|http|
  response , = http.post( '/cgi-bin/any.rhtml',
                          'querytype=subject&target=ruby' )
}

2.3 プロクシ経由のアクセス

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 自身を返すので 上のコードのように書いておけばプロクシなしの場合にも対応できます。

2.4 リダイレクトに対応する

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 クラスが標準添付になればもっと簡単になるはずです。

2.5 Basic 認証

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
}

3 新しい仕様への変更と移行措置について

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)... }

この機能はスレッドセーフではありません。

4 class Net::HTTP

4.1 クラスメソッド

new( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil )

新しい HTTP オブジェクトを生成します。address は HTTP サーバーの FQDN で、 port は接続するポート番号です。このメソッドではまだ接続はしません。

proxy_addr を与えるとプロクシを介して接続するオブジェクトを生成します。

start( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil )
start( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil ) {|http| .... }

以下と同じです。

Net::HTTP.new(address, port, proxy_addr, proxy_port).start(&block)
get( address, path, port = 80 )

ホスト address の port 番ポートに接続して path の表現する エンティティを取得、文字列で返します。

get_print( address, path, port = 80 )

ホスト address の port 番ポートに接続して path の表現する エンティティを取得したうえ、$stdout に << で出力します。

Proxy( address, port = 80 )

常に指定されたプロクシに接続するクラスを作成し返します。 このクラスは 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_class?

自身が (Proxy メソッドによって作成された) プロクシ用のクラスならば真。

port

HTTP のデフォルトポート (80)。

4.2 メソッド

start
start {|http| .... }

TCP コネクションを張り、HTTP セッションを開始します。 すでにセッションが開始していたら何もせずに false を返します。

イテレータとして呼ばれた時はブロックの間だけセッションを接続し、 ブロック終了とともに自動的にセッションを閉じます。

active?

HTTP セッションが開始されていたら真。

address

接続するアドレス

port

接続するポート番号

open_timeout
open_timeout=(n)

接続時に待つ最大秒数。この秒数たってもコネクションが 開かなければ例外 TimeoutError を発生します。

read_timeout
read_timeout=(n)

読みこみ (read(1) 一回) でブロックしてよい最大秒数。 この秒数たっても読みこめなければ例外 TimeoutError を発生します。

finish

HTTP セッションを終了します。セッション開始前にこのメソッドが 呼ばれた場合はなにもせずに false を返します。

proxy?

プロクシを介して接続するなら真。

proxy_address

プロクシ経由で接続する HTTP オブジェクトならプロクシのアドレス。 そうでないなら nil。

proxy_port

プロクシ経由で接続する HTTP オブジェクトならプロクシのポート。 そうでないなら nil。

get( path, header = nil, dest = '' )
get( path, header = nil ) {|str| .... }

サーバ上の 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
}
head( path, header = nil )

サーバ上の 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'
post( path, data, header = nil, dest = '' )
post( path, data, header = nil ) {|str| .... }

サーバ上の 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( request [, data] )
request( request [, data] ) {|response| .... }

リクエストオブジェクト request を送信します。POST の時は data も 与えられます。(POST 以外で data を与えると ArgumentError を発生します)

ブロックとともに呼びだされたときは接続を保持したまま HTTPResponse オブジェクトをブロックに与えます。

5 class Net::HTTP::Get, Head, Post

HTTP リクエストを抽象化するクラス。key はすべて大文字小文字を 区別しません。

5.1 クラスメソッド

new

HTTP リクエストオブジェクトを生成します。

5.2 メソッド

self[ key ]

key ヘッダフィールドの文字列。 key は大文字小文字を区別しません。

self[ key ] = val

key ヘッダフィールドに val をセットします。 key は大文字小文字を区別しません。

each {|name, val| .... }

ヘッダ名とその値に対するくりかえし。ヘッダ名は小文字で統一されます。

basic_auth( account, password )

Authrization: ヘッダを basic auth 用にセットします。

range

Range: ヘッダの示す範囲を Range オブジェクトで返します。

range = r
set_range( i, len )

範囲を指定してエンティティを取得するためのヘッダ Range: をセットします。 r は Range オブジェクト、i, len は始点と長さです。

content_length

Content-Length: ヘッダの値 (整数)。

content_range

Content-Range: ヘッダの値 (Range)。

6 class Net::HTTPResponse

HTTP レスポンスのクラスです。 引数がヘッダフィールド名である場合、大文字小文字を区別しません。

6.1 メソッド

self[ key ]

key ヘッダフィールド(文字列)です。たとえばキー 'content-length' に対しては '2048' のような文字列が得られます。 key は大文字小文字を区別しません。

self[ key ] = val

key ヘッダフィールドを value に設定します。 key は大文字小文字を区別しません。

key?( key )

key というヘッダフィールドがあれば真。 key は大文字小文字を区別しません。

each {|name,value| .... }

すべてのヘッダフィールド名とその値のペアに対するくりかえし。

canonical_each {|name,value| .... }

ヘッダフィールドの正式名とその値のペアに対して繰り返します。

code

HTTP のリザルトコードです。例えば '302' などです。

message

HTTP サーバがリザルトコードに付加して返すメッセージです。 例えば 'Not Found' などです。

read_body( dest = '' )

エンティティボディを取得し dest に << メソッドを使って書きこみます。 同じ HTTPResponse オブジェクトに対して二回以上呼ばれた場合、 二回目からはなにもせずに一回目の返り値をそのまま返します。

read_body {|str| .... }

エンティティボディを少しづつ取得して順次ブロックに与えます。

body

エンティティボディです。read_body を呼んでいればその引数 dest、 呼んでいなければエンティティボディを文字列として読みこんで返します。

Title: net/pop.rb version 1.2.1

1 このライブラリについて

メールを受信するためのプロトコル POP3 (Post Office Protocol version 3) を を扱うライブラリです。POP3 の実装は [RFC1939] <URL:http://www.ietf.org/rfc/rfc1939.txt> に基いています。

2 使用例

2.1 メールの受信

メールを受信してファイル '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."
}

2.2 短くする

以下は動作は同じでコードを短くしたバージョンです。

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

2.3 ファイルに直接書く

これまでの例では 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

2.4 APOP

APOP 認証を使うには

  1. POP3 クラスのかわりに APOP クラスを使う
  2. POP3.start の第五引数に true を渡す

の二通りの方法があります。

# (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.
}

3 Net::POP3 class

3.1 クラスメソッド

new( address = 'localhost', port = 110, apop = false )

Net::POP3 オブジェクトを生成します。まだ接続はしません。 apop が真のときは APOP 認証を行うオブジェクトを生成します。

start( address = 'localhost', port = 110, account, password )
start( address = 'localhost', port = 110, account, password ) {|pop| .... }

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
foreach( address = 'localhost', port = 110, account, password ) {|mail| .... }

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
delete_all( address = 'localhost', port = 110, account, password )
delete_all( address = 'localhost', port = 110, account, password ) {|mail| .... }

POP セッションを開き、サーバ上のメールをすべて削除します。 ブロックが与えられた時は削除する前にブロックにそのメールを 渡します。以下と同じです。

# example
Net::POP3.delete_all( addr, nil, 'YourAccount', 'YourPassword' ) do |m|
  m.pop file
end
auth_only( address = 'localhost', port = 110, account, password )

POP セッションを開き認証だけを行って接続を切ります。 POP before SMTP 専用です。

# example
pop = Net::POP3.auth_only( 'your.pop3.server',
                            nil,     # using default (110)
                           'YourAccount',
                           'YourPassword' )

3.2 メソッド

start( account, password )
start( account, password ) {|pop| .... }

リモートホストとの接続を開始し、アカウントに account、 パスワードに password を使って POP ログインします。

active?

POP3 セッションが開始されていたら真。

address

接続するアドレス

port

接続するポート番号

open_timeout
open_timeout=(n)

接続時に待つ最大秒数。この秒数たってもコネクションが 開かなければ例外 TimeoutError を発生します。

read_timeout
read_timeout=(n)

読みこみ (read(1) 一回) でブロックしてよい最大秒数。 この秒数たっても読みこめなければ例外 TimeoutError を発生します。

finish

POP3 セッションを終了します。セッション開始前にこのメソッドが 呼ばれた場合はなにもせずに false を返します。

mails

Net::POPMail オブジェクトの配列をかえします。 この配列はセッションを開始したときに自動的に更新されます。

each_mail {|popmail| .... }
each {|popmail| .... }

pop3.mails.each と同じです。

delete_all
delete_all {|popmail| .... }

サーバ上のメールを全て消去します。 ブロックを与えられたときは消去する前にその POPMail オブジェクトを ブロックに渡します。

# example
n = 1
pop.delete_all do |m|
  File.open("inbox/#{n}") {|f| f.write m.pop }
  n += 1
end
auth_only( account, password )

POP セッションを開き認証だけを行って接続を切ります。 POP before SMTP 専用です。

# example
pop = Net::POP3.new( 'your.pop3.server' )
pop.auth_only 'YourAccount', 'YourPassword'
reset

セッションをリセットします。 具体的には POPMail#delete で消したメールが全て復活します。 (POP3 ではメール一個だけを復活する方法はありません)

4 Net::APOP

このクラスでは新しいメソッドは導入していません。 認証方式が APOP に変わるだけです。

4.1 スーパークラス

Net::POP3

5 Net::POPMail

POP サーバー上のメール一通を抽象的に表現するクラス。 メールの取得や消去といった操作をカプセル化します。

5.1 メソッド

pop( dest = '' )

メールを受信して dest に << メソッドを使って書きこみます。 dest を返します。

# example
allmails = nil
POP3.start( 'your.pop3.server', 110,
            'YourAccount, 'YourPassword' ) do |pop|
  allmails = pop.mails.collect {|popmail| popmail.pop }
end
pop {|str| .... }

メールの文字列を少しづつ読みこみ、順次ブロックに与えます。

# example
POP3.start( 'localhost', 110 ) {|pop3|
  pop3.each_mail do |m|
    m.pop do |str|
      # do anything
    end
  end
}
header

ヘッダだけを受信して文字列で返します。

top( lines )

メールヘッダと lines 行ぶんの本文を取得し文字列で返します。

delete

サーバ上からメールを削除します。

size

メールのサイズ (単位はバイト) をかえします。

deleted?

メールがサーバ上で消去されているとき真。消去してしまったら POP3#reset を使う以外に復活する方法はありません。

Title: net/smtp.rb version 1.2.1

1 このライブラリについて

メールを送信するためのプロトコル SMTP (Simple Mail Transfer Protocol) を扱うライブラリです。ヘッダなどメールのデータを扱うことはできません。 SMTP の実装は [RFC2821] <URL:http://www.ietf.org/rfc/rfc2821.txt> に基いています。

2 使用例

2.1 とにかくメールを送る

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
}

2.2 文字列以外からの送信

ひとつ上の例では文字列リテラル(ヒアドキュメント)を使って送信しましたが、 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'
  }
}

2.3 Hello ドメイン

SMTP ではメールを送る側のホストの名前を要求されるのですが、 ダイヤルアップなどの場合には自分のマシンに正式な名前がない場合が あります。そのような場合は適宜 SMTP サーバの名前などを与えてやら ないと配送を拒否されることがあります。SMTP.start あるいは SMTP#start の引数 helo_domain がそれです。

Net::SMTP.start( 'your.smtp.server', 25,
                 'mail.from.domain' ) {|smtp|

3 class Net::SMTP

3.1 クラスメソッド

new( address = 'localhost', port = 25 )

新しい SMTP オブジェクトを生成します。address はSMTPサーバーのFQDNで、 port は接続するポート番号です。ただし、このメソッドではまだ接続はしません。

start( address = 'localhost', port = 25, helo_domain = Socket.gethostname, account = nil, password = nil, authtype = nil )
start( address = 'localhost', port = 25, helo_domain = Socket.gethostname, account = nil, password = nil, authtype = nil ) {|smtp| .... }

以下と同じです。

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'
}

3.2 メソッド

start( helo_domain = <local host name>, account = nil, password = nil, authtype = nil )
start( helo_domain = <local host name>, account = nil, password = nil, authtype = nil ) {|smtp| .... }

TCP コネクションを張り、同時に SMTP セッションを開始します。そのとき、 こちらのホストの FQDN を helo_domain に指定します。 もしすでにセッションが開始していたら何もせずに false を返します。

account と password の両方が与えられた場合、AUTH コマンドによって 認証を行います。authtype は使用する認証のタイプで、シンボル で :plain か :cram_md5 を指定します。

active?

SMTP セッションが開始されていたら真。

address

接続するアドレス

port

接続するポート番号

open_timeout
open_timeout=(n)

接続時に待つ最大秒数。この秒数たってもコネクションが 開かなければ例外 TimeoutError を発生します。

read_timeout
read_timeout=(n)

読みこみ (read(1) 一回) でブロックしてよい最大秒数。 この秒数たっても読みこめなければ例外 TimeoutError を発生します。

finish

SMTP セッションを終了します。セッション開始前にこのメソッドが 呼ばれた場合はなにもせずに false を返します。

send_mail( mailsrc, from_addr, *to_addrs )

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'
}
ready( from_addr, *to_addrs ) {|adapter| .... }

メール書きこみの準備をしたうえで、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
}

4 発生する例外

セッション中に (SMTP レベルの) エラーがおこった場合、 以下の例外が発生します。

Net::ProtoSyntaxError

SMTP コマンドの構文ミス(500番台)

Net::ProtoFatalError

恒久的なエラー(550番台)

Net::ProtoUnknownError

予期しないエラー。おそらくバグ

Net::ProtoServerBusy

一時的なエラー(420/450番台)

Title: net/telnet.rb

--> Net::Telnet

Title: Net::Telnet

1 使用例

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

2 スーパークラス:

SimpleDelegator

Net::Telnet のインスタンスは、ソケットのメソッドをdelegateします(例え ば、セッションが終わった後は close を実行した方が良いでしょう)。

3 クラスメソッド:

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#cmdNet::Telnet#login の内部でも使用されています。

ブロックを指定した場合、接続前に

"Trying #{ホスト名} ...\n"

接続後に

"Connected to #{ホスト名}.\n"

という文字列を引数にそれぞれブロックを実行します。

4 メソッド:

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 オブジェクトを返します。

Title: SimpleDelegator

--> SimpleDelegator

Title: nkf.so

--> NKF

Title: NKF

nkf(1) (Network Kanji code conversion Filter version 1.7)を ruby から使うためのモジュールです。

1 使い方:

以下は、漢字コード変換コマンドの例です。

#!/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

2 モジュール関数:

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 モジュールのモジュール定数です(下記参照)。

3 定数

NKF::JIS

JISコードを表します。

NKF::EUC

EUCコードを表します。

NKF::SJIS

SJISコードを表します。

NKF::BINARY

入力が binary であることを表します。

NKF::UNKNOWN

コード判定に失敗したことを表します。 入力が ASCII 文字列でもこの値になります。

Title: observer.rb

--> Observable

Title: Observable

1 目的・概要

Mix-inによりobserverパターンを提供する。

Observableモジュールをincludeしたクラスは Observable#changedメソッドにより更新フラグを立て、 Observable#notify_observers()が呼び出されると 更新フラグが立っている場合はオブザーバに通知する (オブザーバのupdateメソッドを呼び出す)。 Observable#notify_observers()の引数は そのままオブザーバのupdateメソッドに渡される。

2 サンプルコード

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)

3 モジュールメソッド

Observable#add_observer(observer)

オブザーバを追加する。 オブザーバはupdateメソッドを備えている必要がある。

observerupdateメソッドを持たないときは 例外NameErrorを発生する。

Observable#delete_observer(observer)

オブザーバを削除する。

Observable#delete_observers

オブザーバをすべて削除する。

Observable#count_observers

オブザーバの数を返す。

Observable#changed(state=true)

更新フラグを立てる。

Observable#changed?

更新フラグの状態を返す。

Observable#notify_observers(*arg)

更新フラグが立っていたら、オブザーバのupdateメソッドを呼び出す。 与えられた引数はそのupdateメソッドに渡される。 更新フラグはfalseになる。

Title: open3.rb

--> Open3

Title: Open3

[2001/02/05] るびきち

1 open3.rb

perlにあるopen3のruby版。

2 使い方

2.1 その1

require "open3" 

inn, out, err = Open3.popen3('nroff -man')

2.2 その2

include Open3
inn, out, err = popen3('nroff -man')

2.3 その3

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として返す。 標準添付希望。

2.4 その3修正版

[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

3 モジュール関数

Open3.popen3(cmd)

外部プログラムcmdを実行し、そのプロセスの標準入力、標準出力、 標準エラー出力に接続されたパイプを3要素の配列で返す。 cmdexecと同じ規則で解釈される。

ブロックを指定するとパイプの配列を引数にブロックを実行し、最後に パイプを 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"

Title: ostruct.rb

--> OpenStruct

Title: OpenStruct

[2001/02/07] るびきち

手軽な構造体クラス。 method_missingの使い方の例でもある。

1 使い方

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"

2 クラスメソッド

OpenStruct.new(hash = nil)

OpenStructオブジェクトを生成。 hashが与えられたとき、

3 メソッド

OpenStruct#delete_field(name)

nameで指定された要素を削除。 その後その要素を参照したらnilが返る。

Title: parsearg.rb

Author: <jammy@shljapan.co.jp>

オプションを解析し、`$OPT_xxx'に値を設定します。更に指定したオプシ ョンが条件にあっていない場合、USAGE を表示します。

1 使用しているライブラリ:

2 書式:

parseArgs(MIN_ARGCCHECH_OPTSSINGLE_OPTS、*OPTS)
第一引数:

`-'や`--'を伴って指定するオプション以外のオプションの最低必要数 を指定します。存在しない場合は0を指定します。

第二引数:

どのオプションが必要条件かを指定します。第三、第四引数で指定する オプションのうち必要なものを'('、')'、'|'、'&' を使って並べ、全 体をダブルクォテーションで括ります。 Rubyスクリプト実行時に全て のオプションが省略可能ならば `nil'を指定して下さい。 以下の例では、"-d" と最低でも "-x"、"-y"、"--geometry"のど れか一つが実行時に必要なオプションとなります。 `parseArgs(0、"d&(x|y|geometry)"、"fd"、"x:"、"y:"、"geometry:"、"version")'

第三、第四引数:

getopts の第一、第二引数と同じです。

3 オプション解析:

getopts のオプション解析と同じです。

4 USAGEの設定:

`$USAGE'に`usage()'(名前は何でもよい)をセットします。

def usage()
  printf("Usage:\n")
        :
end
$USAGE='usage'

5 参照:

Title: parsedate.rb

parsedate[23] - 日付と時刻の解析

<URL:http://www.funaba.org/ruby.html#date2>*99

--> ParseDate

Title: ParseDate

これはもうひとつの日付解析モジュールです。

このモジュールは与えられた日付表現を解析するメソッドを提供します。 これは、ctime(3)、伝統的な date(1)、 RFC 822 日付、RFC 850 日付、 ISO 8601 の一部、JIS X0301 拡張の一部、などを受けつけます。

1 使用例

解析結果を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

2 モジュール関数

ParseDate.parsedate(date, cyear=false)

dateは日付文字列。 さまざまな形式に対応している。 cyearが指定してあるときは、年を2桁表記から4桁表記に直す。 二桁表記で69以上ならば1900年代、それ未満のときは2000年代とみなされる。 [年, 月, 日, 時, 分, 秒, タイムゾーン, 曜日] の配列が返る。

Title: ping.rb

--> Ping

Title: Ping

1 モジュール関数:

Ping.pingecho(host, timeout=5, service='echo')

host の TCP サービスserviceに対して接続を試み 成功すれば true を返します。ping(1) と異なり ICMP を使用しないので root 権限を必要としない利点があります。

注: 最近は不要なサービスを受け付けないホストが多いので必ずしもこの モジュールが有用とは限りません*100

Title: pstore.rb

--> PStore

Title: PStore

Rubyのオブジェクトを外部ファイルに格納するためのクラス。 内部でMarshalを使っている。

1 使い方

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ライクである。

2 クラスメソッド

PStore.new(file)

ファイル名fileでデータベースを読み書きする。 fileのあるディレクトリは書き込み可能である必要がある。 なぜなら、データベースを更新するときにバックアップファイルが作成されるからだ。 バックアップファイル名はファイル名の後に~がつく。

3 メソッド

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ブロックから抜けるが、データベースの変更は反映されない。

4 プライベートメソッド

PStore#in_transaction

トランザクションの中でなければ例外を発生させる。

Title: pty.so

--> PTY

Title: PTY

疑似端末(Pseudo tTY)を扱うモジュール

--> ruby-src:ruby/ext/pty/README.ja

Title: rational.rb

--> Rational

1 関数:

Rational(a, b)

執筆者募集

2 Integer

2.1 メソッド:

gcd(n)
lcm(int)
gcdlcm(int)
to_r

Title: Rational

執筆者募集

1 スーパークラス:

2 インクルードしているモジュール:

3 メソッド:

self + other
self - other
self * other
self / other
self % other
self ** other
divmod
abs
self <=> other
to_i
to_f
to_s

Title: rbconfig.rb

--> Config

Title: readbytes.rb

1 メソッド:

IO#readbytes(size)

IO#readと同様にsizeバイト読み込みますが、 EOFに到達した時に例外 EOFError を発生させます。 sizeバイト未満しか読み込めなかった時には 例外 TruncatedDataError を発生させます。

2 TruncatedDataError

IO#readbytes が発生させる例外

2.1 スーパークラス:

2.2 メソッド:

TruncatedDataError#data

例外が発生するまでに読み込んだデータを文字列で返します。

Title: readline.so

--> Readline

Title: Readline

GNU Readline によるコマンドライン入力インタフェースを提供するモジュー ルです。

1 使い方

このようにして使います。

require "readline"

while buf = Readline.readline("> ", true)
    print "-> ", buf, "\n"
end

2 モジュール関数

Readline.readline([prompt, [add_hist]])

ユーザからのキー入力を求め、入力した文字列を返します。EOF(UNIX で は ^D)を入力すると nil を返します。

入力時には行内編集が可能で、vi モードと Emacs モードが用意されています。 (Readline.vi_editing_modeReadline.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

3 モジュールメソッド

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 のマニュアルを参照してください。

4 定数

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

5 備考

6 履歴

version 1.8

以上が追加されました。

version 1.5 (ruby version 1.6.5?)

Title: resolv-replace.rb

BasicSocket#sendIPSocket.getaddressTCPSocket.newTCPSocket.openUDPSocket#connectUDPSocket#sendの 名前解決にResolvを使うようにメソッドの書き換えをする。

*102

Title: resolv.rb

--> Resolv

Title: 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.

執筆者募集

1 例:

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]}

2 クラスメソッド:

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"

3 Resolv::Hosts

hostname resolver using /etc/hosts format.

3.1 クラスメソッド:

Resolv::Hosts.new(hosts='/etc/hosts')

3.2 メソッド:

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.

4 Resolv::DNS

DNS stub resolver.

4.1 クラスメソッド:

Resolv::DNS.new(resolv_conf='/etc/resolv.conf')

4.2 メソッド:

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.

5 Resolv::DNS::Resource::IN::NS

name

6 Resolv::DNS::Resource::IN::CNAME

name

7 Resolv::DNS::Resource::IN::SOA

mname
rname
serial
refresh
retry
expire
minimum

8 Resolv::DNS::Resource::IN::HINFO

cpu
os

9 Resolv::DNS::Resource::IN::MINFO

rmailbx
emailbx

10 Resolv::DNS::Resource::IN::MX

preference
exchange

11 Resolv::DNS::Resource::IN::TXT

data

12 Resolv::DNS::Resource::IN::A

address

13 Resolv::DNS::Resource::IN::WKS

address
protocol
bitmap

14 Resolv::DNS::Resource::IN::PTR

name

15 Resolv::DNS::Resource::IN::AAAA

address

16 Resolv::DNS::Name

16.1 クラスメソッド:

Resolv::DNS::Name.create(name)

16.2 メソッド:

Resolv::DNS::Name#to_s

17 Resolv::DNS::Resource

18 Resolv::IPv4

18.1 クラスメソッド:

Resolv::IPv4.create(address)

18.2 メソッド:

Resolv::IPv4#to_s
Resolv::IPv4#to_name

18.3 定数:

Resolv::IPv4::Regex

IPv4のアドレスの正規表現。

19 Resolv::IPv6

19.1 クラスメソッド:

Resolv::IPv6.create(address)

19.2 メソッド:

Resolv::IPv6#to_s
Resolv::IPv6#to_name

19.3 定数:

Resolv::IPv6::Regex

IPv6のアドレスの正規表現。

20 Bugs

NISはサポートされていません。

Title: sdbm.so

--> SDBM

Title: SDBM

執筆者募集

Title: sha1.rb

digest/sha1.so をロードして SHA1 を Digest::SHA1 に置き換えます

Title: shell.rb

ruby-src:ruby/doc/shell.rd を参照

Title: shellwords.rb

--> Shellwords

Title: Shellwords

執筆者募集

1 モジュールメソッド:

shellwords(line)

Unixのシェルと同じように単語に分割して、 分割した単語の配列を返す。

Title: singleton.rb

--> Singleton

Title: Singleton

1 目的・概要

Mix-inによりsingletonパターンを提供する。

Singletonモジュールをincludeすることにより、クラスは 高々ひとつのインスタンスしか持たないことが保証される。

Singletonをmix-inしたクラスの クラスメソッドinstanceはその唯一のインスタンスを返す。

newはprivateメソッドに移され、外部から呼び出そうとするとエラーになる。

2 サンプルコード

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)

3 モジュールメソッド

Singleton#instance

そのクラスの唯一のインスタンスを返す。 最初に呼ばれたときはそのインスタンスを生成する。

Singletonをincludeしたクラスで定義されるので、 正確にはSingletonモジュールのメソッドではない。

Title: socket.so

1 クラス

2 モジュール

3 ホスト指定形式

AF_INETなソケットにおいてホストを指定するには以下のいずれか の形式を指定します。

4 サービス指定形式

サービスを指定するには以下のいずれかの形式を指定します。

Title: BasicSocket

ソケットを表す抽象クラス。具体的なソケット操作はサブクラスで 定義されます。 例えばインターネットドメインストリームソケットの場合は TCPSocketを用います。

1 スーパークラス:

2 クラスメソッド:

do_not_reverse_lookup
do_not_reverse_lookup = bool

この値が真ならアドレスからホスト名への逆引きを行わなくなります。 デフォルトは 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 から対応するソケッ トクラスを作ることができます。

3 メソッド:

getpeername

接続の相手先のソケットの情報を取得します。sockaddr構造体をパッ クした文字列を返します。getpeername(2)を参照の こと。

getsockname

ソケットの情報を取得します。sockaddr構造体をパックした 文字列を返します。getsockname(2)を参照のこと。

getsockopt(level, optname)

ソケットのオプションを取得します。getsockopt(2) を参照のこと。取得したオプションのデータをパックした文字列を 返します。

recv(len[, flags])

ソケットからデータを受け取り、文字列として返します。 lenは受け取る最大の長さを指定します。 flagsについてはrecv(2)を参照。flagsの デフォルト値は0です。flagsの指定に必要な定数は Socketクラスで定義されています。(例: Socket::SO_LINGER)

send(mesg, flags[, to])

ソケットを介してデータを送ります。flagsに関しては send(2)を参照してください。connect していないソケットに対しては送り先であるtoを指定 する必要があります。実際に送ったデータの長さを返します。

setsockopt(level, optname, optval)

ソケットのオプションを設定します。setsockopt(2) を参照のこと。*104

shutdown([how])

ソケットの以降の接続を終了させます。howが0である 時、以降の受信が、1である時は、以降の送信が拒否されます。 howが2の時には、それ以降の送信、受信ともに拒否さ れます。howを省略すると2を指定したことになります。 shutdown(2)を参照。

Title: IPSocket

インターネットドメインソケットのクラス。通常の IOクラスのサブクラスと同 様の入出力ができます。

1 スーパークラス:

2 クラスメソッド:

getaddress(host)

ホスト名からホストのアドレスを返します。ホストのアドレスは文 字列はoctet decimalの文字列(例:127.0.0.1)です。

3 メソッド:

addr

ソケットの接続情報を表す配列を返します。配列の各要素は第1要 素が文字列 "AF_INET"、第2要素がport番号、第3要素がホストを表 す文字列、第4要素がホストのIPアドレスを表す文字列(octet decimal)です。*105

peeraddr

接続相手先ソケットの情報を表す配列を返します。配列の各要素は IPSocket#addrメソッドが返す配列 と同じです。

recvfrom(len[, flags])

recvと同様にソケットからデータを受け取りますが、 戻り値は文字列と相手ソケットのアドレス(形式は IPSocket#addr参照)のペアです。引数につ いてはBasicSocket#recvと同様です。

Title: TCPSocket

インターネットドメインのストリーム型ソケットのクラス。通常の 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

1 スーパークラス:

2 クラスメソッド:

open(host, service [local_host, local_serice])
new(host, service [local_host, local_serice])

hostで指定したホストのserviceで指定したポートと接続したソケッ トを返します。hostはホスト名、またはoctet decimal によるインターネットアドレスを示す文字列、service/etc/services(またはNIS)に登録されているサー ビス名かポート番号です。

ruby 1.7 feature: 引数 local_host, local_service を指定した場合、そのアドレス に対してbind(2)します。

gethostbyname(host)

ホスト名またはIPアドレス(整数または"127.0.0.1" のような文字列)からホストの情報を返します。ホスト情報は、ホ スト名、ホストの別名の配列、ホストのアドレスタイプ、ホストの アドレスを各要素とする配列です。ホストのアドレスはoctet decimalの文字列("127.0.0.1"のような文字列)です。

*106

Title: TCPServer

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

1 スーパークラス:

2 クラスメソッド:

TCPServer.new([host, ]service)
TCPServer.open([host, ]service)

新しいサーバー接続をオープンします。service/etc/services(またはNIS)に登録されているサービ ス名かポート番号で指定します。hostを指定した時は 指定したホストに対しての接続だけを受け付けます。省略時は全てのホ スト(インタフェース)への接続要求を受け付けることになります。

3 メソッド:

accept

クライアントからの接続要求を受け付け、接続した TCPSocketのインスタンスを返します。

listen(backlog) ((<ruby 1.7 feature>))

listen(2) を実行します。 (listenと同じ)

backlog は、クライアントからの接続要求を保留できる数です。 TCPServer のインスタンスは最初は backlog の値は 5 で生成されます。

listen(2) が成功すれば 0 を返します。 失敗すれば 例外 Errno::EXXX が発生します。

Title: SOCKSSocket

TCPSocketSOCKS 対応したクラスです。

執筆者募集

Title: UDPSocket

UDP/IPデータグラム型ソケットのクラス。

1 スーパークラス:

2 クラスメソッド:

open
new

新しいUDPソケットを返します。

3 メソッド:

bind(host, port)

ソケットをhostportに結合します。

connect(host, port)

ソケットをhostportにconnectします。

*107

send(mesg, flags[, host, port])

ソケットを介してデータを送ります。flagsに関しては send(2)を参照してください。connect していないソケットに対しては送り先を指定するためhostportを指定する必要があります。実際に送ったデー タの長さを返します。

Title: UNIXSocket

UNIXドメインのストリーム型ソケットのクラス。通常の IOクラスのサブクラスと同様の 入出力ができます。

1 スーパークラス:

2 クラスメソッド:

open(path)
new(path)

pathで指定したパス名を用いて接続したソケットを返 します。

pair([type[, protocol]]) ruby 1.7 feature
socketpair([type[, protocol]]) ruby 1.7 feature

相互に結合されたUNIXソケットのペアを含む2要素の配列を返します。 type が省略された場合、Socket::SOCK_STREAM が使われます。 protocol が省略された場合、0 が使われます。

3 メソッド:

addr

ソケットの接続情報を表す配列を返します。配列の各要素は第1要 素が文字列 "AF_UNIX"、第2要素がパスを表す文字列です。

path

UNIXソケットのパスを返します。

peeraddr

接続相手先ソケットの情報を表す配列を返します。配列の各要素は IPSocket#addrメソッドが返す配列 と同じです。

recvfrom(len[, flags])

recvと同様にソケットからデータを受け取りますが、 戻り値は文字列と相手ソケットのパスのペアです。引数につい てはrecvと同様です。

recv_io([klass[, mode]]) ruby 1.7 feature

ファイルディスクリプタを受け取ります。

klass が nil の場合、ファイルディスクリプタが Fixnum として 返されます。

klass が nil でない場合、 klass.for_fd(fd[, mode]) が呼ばれ、その値が返されます。 klass が省略された場合は IO が指定されたものとみなされ、 IO.for_fd(fd[, mode]) が呼ばれます。

send_io(io) ruby 1.7 feature

IO や Fixnum に対応するファイルディスクリプタを送ります。

Title: UNIXServer

UNIXストリーム型接続のサーバ側のソケットのクラス。

1 スーパークラス:

2 クラスメソッド:

UNIXServer.open(path)
UNIXServer.new(path)

pathで指定したパス名を用いて接続を受け付けるソケットを返 します。

3 メソッド:

accept

クライアントからの接続要求を受け付け、接続した UNIXSocketのインスタンスを返します。

listen(backlog) ((<ruby 1.7 feature>))

listen(2) を実行します。 (listenと同じ)

backlog は、クライアントからの接続要求を保留できる数です。 UNIXServer のインスタンスは最初は backlog の値は 5 で生成されます。

listen(2) が成功すれば 0 を返します。 失敗すれば 例外 Errno::EXXX が発生します。

Title: Socket

ソケットそのものに対するシステムコールレベルのアクセスを提供 するクラス。Perlのソケットに対するアクセスと同レベルの機能を 提供してます。このクラスではソケットアドレスは pack された文字列で指定します。

一般的なソケットプログラミングはより高レベルの TCPSocketクラスや TCPServerクラスを用い て行われることが多く、このクラスはあまり用いられません。

1 スーパークラス:

2 クラスメソッド:

Socket.open(domain, type, protocol)
Socket.new(domain, type, protocol)

新しいソケットを生成します。domaintypeprotocol はインクルードファイルにある定数で指定しま す。ほとんどの定数は Socket::AF_INET のように Socket クラスの定数として定義されています。domaintype に関しては、"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つの要素からなる次の 形の配列です。

必須引数の意味は以下の通りです。

残りの引数は省略可能です。

引数に指定できる定数の意味については getaddrinfo(3) を参照して下さい。

Socket.getnameinfo(sa[, flags])

RFC:2553 で定義されたgetnameinfo() の機能を提供するク ラスメソッド。 gethostbyaddr()getservbyport() の代 わりとして用意されています。IPのバージョンに依存しないプログラムを 書くための標準的なAPIです。

配列を返し、その要素はアドレスとポートを表す文字列です。

引数 sa には文字列か配列を与えます。文字列の場合は sockaddr 構造体 のパック文字列を与えます。具体的には getsockaddr の値が利用できます。配列を与える場合には、要素が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_MAXHOSTSocket::NI_MAXSERVSocket::NI_NOFQDNSocket::NI_NUMERICHOSTSocket::NI_NAMEREQDSocket::NI_NUMERICSERVSocket::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"

3 メソッド:

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と同様です。

Title: Socket::Constants

ソケット操作の指定のための定数を定義したモジュール。このモジュー ルをインクルードすれば、定数(AF_INETなど)を直接参照できます。

これらの定数はSocketの定数としても定義されています。

1 アドレスファミリー

AF_INET
AF_UNSPEC
AF_INET6
AF_UNIX
AF_AX25
AF_IPX
AF_APPLETALK

2 ソケットタイプ

SOCK_STREAM
SOCK_DGRAM
SOCK_RAW
SOCK_RDM
SOCK_SEQPACKET
SOCK_PACKET

3 プロトコル

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

4 フラグ

AI_PASSIVE
AI_CANONNAME
AI_NUMERICHOST

Socket.getaddrinfo の flags

Title: sync.rb

Title: Sync_m

Synchronizer_mの別名

1 目的・概要

Mix-inにより再入可能なreader/writerロック機能を提供する。

includeしたクラスではinitializeでsuperを呼び出しておく必要がある。 (ruby 1.7 feature)

2 ロック状態

Sync_m::UN

ロックされていない状態。

Sync_m::EX

排他ロック。 オブジェクトの状態を更新する場合のように、 1つのスレッドがオブジェクトを独占的に使用したい場合に用いる。 排他ロック中に他のスレッドはオブジェクトを共有/排他ロックできない。

Sync_m::SH

共有ロック。 複数のスレッドが同時にオブジェクトを使用できる場合に用いる。 複数のスレッドが共有ロックしている場合、 どのスレッドもオブジェクトを排他ロックできない。

3 モジュールメソッド

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) {...}

ロック状態を変更してブロックを実行する。

Title: Synchronizer_m

Sync_mの別名

Title: Sync

Sync_mincludeしたクラスでSynchronizerの別名。 使い方はSync_mを参照してください。

Title: Synchronizer

Sync_mincludeしたクラスSync の別名。 使い方はSync_mを参照してください。

Title: syslog.so

1.6.6以降に標準添付されています。

1 クラス

2 モジュール

Title: Syslog

UNIXのsyslogのラッパークラスです。 執筆者募集

1 スーパークラス:

2 クラスメソッド:

open(ident=$0, options=Syslog::LOG_PID|Syslog::LOG_CONS, facility=Syslog::LOG_USER)
open(ident=$0, options=Syslog::LOG_PID|Syslog::LOG_CONS, facility=Syslog::LOG_USER) { |syslog| ... }

与えられた引数でsyslogを開いて、Syslogの唯一の インスタンスを返す。 ブロック付きで呼ばれた場合は、インスタンスを引数として ブロックを呼び出す。 syslogを既に開いていた場合はRuntimeErrorが 発生する。

ident はすべてのログにつく識別子で、どのプログラムから 送られたログなのかを識別するために使われる。 optionsfacility については Syslog::Constants を参照。

例:
  sl = Syslog.open('ftpd', Syslog::LOG_PID | Syslog::LOG_NDELAY,
                   Syslog::LOG_FTP)
instance

Syslog の唯一のインスタンスを返す。 (Singleton参照。)

LOG_MASK(priority)

1つの優先度に対するマスクを作成する。

LOG_UPTO(priority)

priorityまでのすべての優先度のマスクを作成する。

3 メソッド:

open(ident=$0, options=Syslog::LOG_PID|Syslog::LOG_CONS, facility=Syslog::LOG_USER)

与えられた引数でsyslogを開く。 syslogを既に開いていた場合はRuntimeErrorが 発生する。

reopen(ident=$0, options=LOG_PID|LOG_CONS, facility=LOG_USER)
open!(ident=$0, options=LOG_PID|LOG_CONS, facility=LOG_USER)

最初にcloseしてからopenと同様に開く。

opened?

syslogを既に開いていればtrueを、 開いていなければfalseを返す。

ident
options
facility

最後のopenで与えられた対応する引数を返す。

log(priority, format, ...)

syslogにメッセージを書き込む。 format以降はsprintfと同じです。

例:
  sl.log(Syslog::LOG_CRIT, "the sky is falling in %d seconds!", 10)
crit(message, ...)
emerg(message, ...)
alert(message, ...)
err(message, ...)
warning(message, ...)
notice(message, ...)
info(message, ...)
debug(message, ...)

Syslog#log()のショートカットメソッドです。 システムによっては定義されていないものもあります。

例:
  sl.crit("the sky is falling in %d seconds!",5)
mask
mask=(mask)

ログの優先度のマスクを取得または設定する。 マスクは永続的であり、 Syslog::open/Syslog#open/Syslog#close ではリセットされない。

例:
  sl.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR)
close

syslogを閉じる。

inspect

inspect参照。

Title: Syslog::Constants

執筆者募集

このモジュールにはシステムで使用可能なLOG_*定数が定義されている。

例:
  require 'syslog'
  include Syslog::Constants

1 定数:

1.1 オプション(options)

LOG_PID
LOG_CONS
LOG_ODELAY
LOG_NDELAY
LOG_NOWAIT
LOG_PERROR

1.2 機能(facilities)

LOG_AUTH
LOG_AUTHPRIV
LOG_CONSOLE
LOG_CRON
LOG_DAEMON
LOG_FTP
LOG_KERN
LOG_LPR
LOG_MAIL
LOG_NEWS
LOG_NTP
LOG_SECURITY
LOG_SYSLOG
LOG_USER
LOG_UUCP
LOG_LOCAL0
LOG_LOCAL1
LOG_LOCAL2
LOG_LOCAL3
LOG_LOCAL4
LOG_LOCAL5
LOG_LOCAL6
LOG_LOCAL7

1.3 優先度(priorities)

LOG_EMERG
LOG_ALERT
LOG_CRIT
LOG_ERR
LOG_WARNING
LOG_NOTICE
LOG_INFO
LOG_DEBUG

Title: tempfile.rb

--> Tempfile

Title: Tempfile

テンプラリファイルを操作するためのクラスです。

1 super class:

SimpleDelegator

2 delegating class:

File

3 class methods:

Tempfile.new(basename[, tempdir])
Tempfile.open(basename[, tempdir])

"basenamepid.n" というファイル名で テンポラリファイルを作成します。

テンポラリファイルは、ディレクトリ tempdir に作成されます。 このデフォルト値は、

ENV['TMPDIR'] || ENV['TMP'] || ENV['TEMP'] || '/tmp'

です。

4 methods:

Tempfile#close([real])

テンポラリファイルをクローズします。 realが偽でなければ、テンポラリファイルはすぐに削除されます。 そうでなければ、GC によって削除されます。realのデフォルト値は false です。

Tempfile#open

クローズしたテンポラリファイルを再オープンします。 "r+" でオープンされるので、クローズ前の内容を再度読む ことができます。

Tempfile#path

テンポラリファイルのパス名を返します。

Title: thread.rb

Threadを拡張するライブラリです。rubyインタプリタを デバッグオプション付き($DEBUGを真)で実行したときには、 Thread.abort_on_exceptionをtrueにします*109

以下のクラスが定義されています。

また、Threadクラスに以下のクラスメソッドを追加定義します。

Thread.exclusive { ... }

ブロック実行中、Threadの切り替えを行いません。

Title: ConditionVariable

執筆者募集 *110 *111

スレッドの同期機構の一つである状態変数を実現するクラス。 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 を実行しているスレッドに対し て条件が成立したことを通知するのが典型的な使用例です。

*112

以下は 「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
}

1 スーパークラス:

2 クラスメソッド:

new

状態変数を生成して返します。

3 メソッド:

broadcast

状態変数を待っているスレッドをすべて再開します。再開された スレッドは ConditionVariable#wait で指定した mutex のロックを試みます。

実行待ちしていたスレッドの配列を返します。

signal

状態変数を待っているスレッドを1つ再開します。再開された スレッドは ConditionVariable#wait で指定した mutex のロックを試みます。

状態を待っているスレッドがあった場合は、そのスレッドを返します。 そうでなければ nil を返します。

wait(mutex)

mutex のロックを開放し、カレントスレッドを停止します。 ConditionVariable#signalまたは、 ConditionVariable#broadcastで送られたシグナルを 受け取ると、mutexのロックを取得し、実行状態となります。

self を返します。

Title: Mutex

Mutex(Mutal Exclusion = 相互排他ロック)は共有データを並行アクセスから保護する ためにあります。Mutex の典型的な使い方は(mMutexオブジェクトとします):

m.lock
begin
  # mによって保護されたクリティカルセクション
ensure
  m.unlock
end

または、より簡単に

m.synchronize {
  # mによって保護されたクリティカルセクション
}

1 スーパークラス:

2 クラスメソッド:

Mutex.new

新しい mutex を生成して返します。

3 メソッド:

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 を返します。

Title: Queue

Queueはスレッド間のFIFO(first in first out)の通信路です。ス レッドが空のqueueを読み出そうとすると停止します。queueになんら かの情報が書き込まれると実行は再開されます。

1 スーパークラス:

2 クラスメソッド:

Queue.new

新しいqueueオブジェクトを生成します。

3 メソッド:

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の値を追加します。待っているスレッドがいれば実行を再開 させます。

Title: SizedQueue

執筆者募集

1 スーパークラス:

2 クラスメソッド:

new(max)

3 メソッド:

max
max= n

Title: thwait.rb

Title: ThreadsWait

provides synchronization for multiple threads.

1 Class Methods:

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.

2 Methods:

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.

Title: ThWait

ThreadsWait の別名

Title: time.rb

Timeクラスを拡張して日時を表す文字列とTimeオブジェクトとの変換を行います。

1 Design Issue

ruby-src:ruby/lib/time.rb参照 執筆者募集

2 クラスメソッド:

Time.parse(date, now=Time.now)
Time.parse(date, now=Time.now) {|year| year}

dateParseDate.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

*114

ParseDatedateから情報を取り出せないとき、または 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で更新された形式と 同じです。

dateRFC:2822に準拠していない、または Timeクラスが指定された日時を表現できないときにArgumentErrorが 発生します。

Time.httpdate(date)

RFC:2616で定義されているHTTP-dateとしてdateをパースして Timeオブジェクトに変換します。

dateRFC:2616に準拠していない、または Timeクラスが指定された日時を表現できないときにArgumentErrorが 発生します。

Time.xmlschema(date)
Time.iso8601(date)

XML Schema で定義されているdateTimeとしてdateをパースして Timeオブジェクトに変換します。

dateがISO 8601で定義されている形式に準拠していない、または Timeクラスが指定された日時を表現できないときにArgumentErrorが 発生します。

3 メソッド:

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です。

Title: timeout.rb

タイムアウトを行うライブラリ。

1 関数:

timeout(sec) {|i| .... }
timeout(sec, exception_class) {|i| .... } ((<ruby 1.7 feature>))

ブロックを sec 秒の期限付きで実行します。 ブロックの実行時間が制限を過ぎたときは例外 TimeoutError が発生します。 exception_class を指定した場合には TimeoutError の代わりに その例外が発生します。

また secnil のときは制限時間なしで ブロックを実行します。

注意

timeout による割り込みは Thread によって実現されています。C 言語 レベルで実装され、Ruby のスレッドが割り込めない処理*115に対して timeout は無力です。その処理を Ruby で実装しなおすか C 側で Ruby のスレッドを意識してあげる必要があります。 timeoutの落し穴も参照

Title: TimeoutError < Interrupt

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
}

*116

1 スーパークラス:

Interrupt

Title: Tracer

--> tracer.rb

Title: weakref.rb

1 目的・概要

WeakRefクラスによりweak referenceを実現する。

WeakRefオブジェクトは与えられたオブジェクトをポイントするが、 ポイント先のオブジェクトはGCされる可能性がある。 アクセスしようとしたときにオブジェクトがGCされていれば WeakRef::RefErrorが発生する。

2 サンプルコード

require 'weakref'
foo = Object.new
ref = WeakRef::new(foo)
ref.some_method_of_foo

3 class WeakRef

weak referenceを提供するクラス。

上位クラス

Delegator

3.1 クラスメソッド

WeakRef.new(obj)

objへのweak referenceを生成する

3.2 インスタンスメソッド

WeakRef#weakref_alive?

参照先のオブジェクトがまだ生きていればtrueを返す

4 class WeakRef::RefError

GCされたオブジェクトを参照しようとしたときに発生する例外。

上位クラス

StandardError

5 see also

Title: Delegator

--> Delegator

Title: Win32API.so

--> Win32API

Title: Win32API

Win32 API をコールするためのクラスです。

1 メソッド

Win32API.new(dllname, proc, import, export)

DLL dllname をロードし、API関数 proc のオブジェクトを 生成します。import には proc の引数の型のリストを、 export には proc の戻り値の型を指定します。

型の指定は以下の文字列または配列です。

importnil の場合は引数なしと見なされます。また、 exportnil の場合は戻り値なし(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"))

2 使用例

*119

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"

Title: Ruby変更履歴

Title: ruby 1.6 feature

ruby version 1.6 は安定版です。この版での変更はバグ修正がメイン になります。

stable-snapshot は、日々更新される安定版の最新ソースです。

1 1.6.7 (2002-03-01) -> stable-snapshot

class variable

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

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"

2 1.6.6 (2001-12-26) -> 1.6.7 (2002-03-01)

time.rb, URI

追加されました。

Ruby/Tk

バグ修正、機能追加 ruby-dev:16139,ruby-dev:16153

数値リテラルの `_'

`_' を置ける場所の規則が見直され、String#hex などの数値変換メソッド の挙動と共に規則が統一されました。rubyist:1018, ruby-dev:15684, ruby-dev:15757

include

モジュールが再帰的に 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

rb_define_module_under()

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 以降の修正版で直ってます。っと一度ハマッたので書いておきま す)。

3 1.6.5 (2001-09-19) -> 1.6.6 (2001-09-19)

Syslog

追加されました。

CGI

Netscape(バージョンは?) のバグに対処しました ruby-list:32089

Time#localtime
Time#gmtime

フリーズした 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
File::SEPARATOR
File::ALT_SEPARATOR
File::PATH_SEPARATOR
RUBY_PLATFORM
RUBY_RELEASE_DATE
RUBY_VERSION

これらは、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
Integer[nth]

大きな値のインデックスに対して例外が発生していました。 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
Numeric#remainder

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 ブロックの中の 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
String#succ

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"
method_missing

以下が 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)
%q(...)

% 記法によるリテラル表記でその区切り文字として英数字を指定 できなくなりました。

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#=~ の呼出で両辺ともリテラルであったときに速度重視のためにメソッ ドコールを行わなくなりました。(実際は、前からこのようにしようとして いたがバグによりメソッドが呼び出されていた(しかも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 をしてほしいなあ)

class 定義

既にクラスが定義されていて、そのクラスと異なるスーパークラスを明示的 に指定して再定義したとき、指定したスーパークラスが反映されていません でした。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(...)

配列リテラル %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

Thread#status が aborting 状態に対して "run" を返していたバグが修正 されました。また、Thread#priority = val が val でなく self を返して いました。rubyist:0820, ruby-dev:14903

UNIXSocket#addr

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]
Subclass of String and Array

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

4 1.6.4 (2001-06-04) -> 1.6.5 (2001-09-19)

$_, $~, if a..b

関数の中から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.rb

Net::Telnet が特定のホストへ接続後、動かない事がありました。 ruby-list:31303

CGI#header

以下のようなスクリプトで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
Dir.chdir

環境変数 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.glob

以下のコードが無限ループになっていました。

Dir.mkdir("test?") rescue nil
p Dir.glob("test?/*")
=> ruby 1.6.5 (2001-09-19) [i586-linux]
   []
jcode.rb

バグがいくつか修正されました。ruby-list:31238

〜この間、空白期間〜

Dir.glob

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

モジュールの 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
Regexp

括弧の数より大きな数のバックリファレンスが何にでもマッチしていました。 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
TCPSocket.open

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 等など

lib/resolv.rb, lib/resolv-replace.rb

追加。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"
Digest モジュール

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")
Struct

フリーズされた構造体オブジェクトが変更できていました。また、$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
String#rindex

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

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"
String#each_line

正しく汚染が伝搬していませんでした。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
NKF::nkf

正しく汚染が伝搬していませんでした。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
ruby -x

オプション -x を指定したときにスクリ プトを実行せずに終了することがありました。ruby-dev:13752

attr_*

アクセサに余計な引数を渡してもエラーになりませんでした。 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
Readline::completion_append_character
Readline::completion_append_character=

追加。GNU Readline ライブラリの変数 rl_completion_append_character のアクセサ。(この変数は GNU readline 2.1 以降で使えます) ruby-ext:01760

Socket::Constants

ソケット関連の定数のうち以下が新規に追加されました(システムに定義さ れている場合に限る)。

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
require / $LOAD_PATH

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

lib/sync.rb
lib/mutex_m.rb

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
$SAFE / load

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
Regexp

以下で、前者がマッチしませんでした。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
$SAFE / def

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");

また今度調べ直します。

IO#ioctl

第二引数に Bignum も受け付けるようになりました(long int の範囲をカバー するため)

5 1.6.3 (2001-03-19) -> 1.6.4 (2001-06-04)

Hash#replace

ハッシュのイテレート中に、そのハッシュのある要素を削除して、 他のハッシュへ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
}
$SAFE / File::unlink

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
Object#untaint

凍結したオブジェクトに対して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
ruby -T4

オプション -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)
Regexp

正規表現中の \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
rb_yield_0()

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 / alias

$SAFE = 4 のときグローバル変数のエイリアスを許さないようにしました。 ruby-dev:13287

Open3::popen3

終了したプロセスが at_exit を呼ばないようにしました。 (exit を exit! に修正) ruby-dev:13170

SizedQueue#pop

以下のコードでデッドロックが起こらないようにしました。ruby-dev:13169

ruby -r thread -e 'q = SizedQueue.new(1); q.push(1);'\
               -e 'Thread.new{sleep 1; q.pop}; q.push(1);'
SizedQueue#max=

maxが現在値より大きい時にその差の分だけ待ちスレッドを起こす処理 の判定に誤りがありました。ruby-dev:13170

Queue
SizedQueue

Thread#run を呼ぶ直前にスレッドが死んでいた場合に ThreadError が発生する問題に対処しました。ruby-dev:13194

Ctrl-C (Interrupt)が効かなくなる

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 には取り込まれていません)

Array#&
Array#|
Array#uniq

結果の配列の要素が 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

shell.rb 0.6 が標準ライブラリとして新規に追加されました。 (ドキュメントが doc ディレクトリにあります)

forwardable.rb

forwardable.rb 1.1 が標準ライブラリとして新規に追加されました。 (ドキュメントが doc ディレクトリにあります)

irb.rb & irb-tools

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
SIGINFO

4.4BSD のシグナル SIGINFO に対応しました。ruby-bugs-ja:PR#45

Thread.stop で SEGV

Thread.stop で SEGV することがありました。ruby-dev:13189

rescue 修飾

以下が 1.6.3 で parse error になっていたバグが修正されました。 ruby-dev:13073, ruby-dev:13292

raise "" rescue []
raise "" rescue (p "foo"; true)
raise "" rescue -1
raise "" rescue (-1)
Thread

以下は 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]
Module#const_defined?
Module#const_get
Module#const_set

これらのメソッドが定数以外にアクセス可能になっていたバグが修正されました ruby-dev:13019

Marshal.dump

Float を dump するときの精度が "%.12g" から "%.16g" になりました。 ruby-list:29349

Fixnum#[]

sizeof(long) > sizeof(int) なシステムでのバグが修正されたようです。

正規表現

まれなバグが2件修正されました ruby-talk:13658, ruby-talk:13744

retry

以下が 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
File::Stat#size

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
Float#modulo, Float#divmod

なんか修正されたみたいです ruby-dev:12718

ObjectSpace#_id2ref

不正に例外を返す場合がありました。

malloc の再帰呼び出し問題

stdio が内部で malloc() を呼び出す場合、Thread と相性が悪かったことに対 処しました。(setvbuf() を使用することで malloc() が呼ばれるのを避けた) ruby-dev:12795

File#flock

File#flock がロック済みの場合に false を返さず Errno::EACCES 例外を あげる場合がありました(flock()がないシステムの場合)

File::Stat.new(filename)

追加 ruby-dev:12803

Bignum#% の計算誤り

% の計算に誤りが出ることがあるバグが(再度)修正されました

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
Marshal

Bignum を dump -> load した結果が元の値と異なる場合がありました。

これに関連する修正が 1.6.3 リリース後、3回ほど行われています。 stable-snapshot の

ruby 1.6.3 (2001-03-22)

以降を使用してください。

Universal Naming Convention(UNC) のサポート(win32)

UNC 形式のパス名 (//host/share) がサポートされました。 バックスラッシュ(`\')ではなくスラッシュ(`/')を使います。 (元もとサポートされてたのがバグ修正された??)

Dir.glob (win32)

カレントディレクトリ(./)に対するglobが失敗していました。

p Dir["./*.c"]
=> []

6 1.6.2 -> 1.6.3 (2001-03-19)

do .. end と { .. }

結合強度の違いがなくなっていたバグが修正されました。

1.6.0 から 1.6.2 までのバージョンでは、

method v { .. }
method v do .. end

の両者に違いがありませんでした。本来の挙動はイテレータ に書かれた通りです。

Bignum#% の計算誤り

% の計算に誤りが出ることがあるバグが修正されました

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
String#count
String#delete
String#squeeze
String#tr
String#tr_s

'\-' で '-' を指定可能になりました(tr! 等、bang method も同様)。 以前は、文字列の先頭または末尾の'-'だけを'-'と見なしていました。

p "-".tr("a-z",  "+")  # => "-"
p "-".tr("-az",  "+")  # => "+"
p "-".tr("az-",  "+")  # => "+"
p "-".tr('a\-z', "+")  # => "+" # シングルクォート文字列であることに注意
p "-".tr("a\\-z", "+") # => "+" # "" では二重に\が必要
Regexp#==

すべてのオプションも同じならば同じと判断するようになりました。 以前は、漢字コード指定と /i (case-insensitive) の指定が同じで あれば同じと判断していました。

%q(), %w()

リテラルの終了文字(`)'など)をバックスラッシュエスケープ可能になりました。

Dir.glob

"**/" がシンボリックリンクを辿らなくなりました。

String#[]

"a"[1,2] が "" を返すようになりました。

p "a"[1,2]
=> ""

これは本来の挙動です。過去のバージョン(1.4.6など)もこの値を返していました。 1.6.0 以降 1.6.2 までは上記は nil になります。

p "a"[2,1] は、nil を返します。

Object#taint

freeze したオブジェクトに対して taint できなくなりました

obj = Object.new.freeze
obj.taint
=> -:2:in `taint': can't modify frozen object (TypeError)
           from -:2

Title: ruby 1.7 feature

ruby version 1.7 は開発版です。以下にあげる機能は将来削除されたり互換 性のない仕様変更がなされるかもしれません。

getopts.rb *ドキュメント未反映*

refine. ruby-dev:16193, ruby-dev:16213

GDBM *ドキュメント未反映*
DBM *ドキュメント未反映*
SDBM *ドキュメント未反映*

ruby-dev:16126

Module#include
Object#extend *ドキュメント未反映*

複数のモジュールを渡したときにインクルードされる順序が変更されました。 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]
UNIXSocket.pair([type[, protocol]])
UNIXSocket.socketpair([type[, protocol]])
UNIXSocket#recv_io([klass[, mode]])
UNIXSocket#send_io(io)

追加

Proc#yield *ドキュメント未反映*

ruby-bugs-ja:PR#98

Array#pack, String#unpack

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"
true/false/nil の特異メソッド定義

これら疑似変数に特異メソッドが定義できるようになりました。

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"
LocalJumpError#exitstatus

追加

def foo
  proc { return 10 }
end

begin
  foo.call
rescue LocalJumpError
  p $!.exitstatus
end

=> ruby 1.7.2 (2002-02-14) [i586-linux]
   10
UNIXServer#listen(backlog)
TCPServer#listen(backlog)

追加。Socket#listenと同じ。

Time#getgm
Time#getlocal
Time#getutc
Time#gmt_offset
Time#gmtoff
Time#utc_offset

追加

Module#<=>

継承関係のないクラス/モジュール同士の比較で例外があがるようになりま した。

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]
IO#fsync

追加

Array#pack, String#unpack

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]
Method#inspect

特異メソッドに対する出力形式がより意味のあるものになりました。 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>
Array.new(size) { ... }
Array#fill { ... }

ブロックの評価結果を 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]
File::Stat#rdev_major
File::Stat#rdev_minor

追加

s = File.stat("/dev/null")
p s.rdev_major
p s.rdev_minor

=> ruby 1.7.2 (2002-01-28) [i686-linux]
   1
   3
Hash#update

ブロックを指定できるようになりました。重複したキーに対する振舞いを制 御できます。

Object#clone

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

汚染された Proc は、ブロックにできなくなる(かも) ruby-dev:15682

String#to_i(base=10)

引数に基数(2,8,10,16)を指定できるようになりました。

p "010".to_i(16)
=> ruby 1.7.2 (2002-01-11) [i586-linux]
   16
Hash.new {|hahs, key| ... }

ハッシュのデフォルト値としてブロックを指定できるようになり ました。ブロックを指定すると空のハッシュ要素の参照に対して その都度ブロックを実行し、その結果を返します。 ブロックにはハッシュ自身と、ハッシュを参照したときのキーが渡されます

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]
Array#select
Hash#select
ENV.select

追加

# ブロックを与えなかった場合は、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"]]
MatchData#select

追加。

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"]
String#match(re)

追加 re.match(str) と同じ。

Module#initialize

Module.new, Class.new でブロックが与えられた場合、生成した モジュール/クラスのコンテキストでブロックを実行するように なりました。

trap
trace_var

第二引数に汚染された文字列を渡すと例外 SecurityError が 起こるようになりました。1.6 では、汚染された文字列をセーフレ ベル4で評価するようになっていました。 ruby-list:32215

puts
Array#to_s

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
Integer#to_s(base=10)

引数に基数を指定できるようになりました。

p 10.to_s(16)
=> ruby 1.7.2 (2001-11-25) [i586-linux]
   "a"
String#chomp
String#chomp!
chomp
chomp!

$/ が "\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

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
Marshal

構造体クラスのサブクラスをダンプしたものがロードできませんでした。 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>
alias

グローバル変数のエイリアスが効いていませんでした。 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.new

ブロックを持てるようになりました。ブロックの実行は module_eval と同じように、そのモジュール/クラスのコンテキ スト(self が そのモジュール/クラス)で実行されます

Module.new {|m| p m}

=> ruby 1.7.1 (2001-10-15) [i586-linux]
   #<Module:0x401afd5c>
String#[re, idx]
String#[re, idx] = val

追加

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)

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

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]
   ""
Dir#path

追加

p Dir.open(".").path
=> ruby 1.7.1 (2001-10-05) [i586-linux]
   "."

〜この間、空白期間〜

Readline

Readline.readline 実行中に Ctrl-C により中断した後でも、端末状態を 復帰するようにしました。ruby-dev:14574

Precision.included

追加(Module#included の再定義)

Signal モジュール

追加。

while, until, class, def の値

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
Range#===

文字列の範囲オブジェクトと文字列との比較を行う場合に、 以前は範囲の両端と比較していましたが、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
Enumerable#sort_by

追加。ruby-dev:8986以降で提案された Schwartzian transform を行うための sort です。

Curses

Updated. New methods and constants for using the mouse, character attributes, colors and key codes have been added.

Range#step([step=1])

追加。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"
String#lstrip, rstrip, lstrip!, rstrip!

追加。左端あるいは右端の空白類を取り除きます。

Socket::pack_sockaddr_in(), Socket::unpack_sockaddr_in()

追加。ソケットアドレス構造体(INET domain)のpack/unpack。

Socket::pack_sockaddr_un(), Socket::unpack_sockaddr_un()

追加。ソケットアドレス構造体(UNIX domain)のpack/unpack。

String#casecmp

追加。アルファベットの大小を無視した文字列比較。

String#eql?

$= の値に関らず常にアルファベットの大小を区別するよ うになりました。

Module#include?

Added. ruby-dev:13941

Dir::chdir

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
Proc#yield

追加 ruby-dev:13597

引数の数をチェックしない点を除けば Proc#call と同じです。

File.fnmatch(pattern, path[, flag])
File.fnmatch?(pattern, path[, flag])

追加

このメソッドで使用するフラグ 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"]
Method#==

追加

多重代入

多重代入の規則を見直しました。変更は以下の点だけです。

#
*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 & NoMethodError

NameError を StandardError のサブクラスに戻しました。 クラス階層は以下のようになりました。

NoMethodError < NameError < StandardError.
File.open

第2引数を数値(File::RDONLY|File::CREATとか)で指定した場合に限り、第3 引数を用いていましたが、第3引数が与えられれば常に有効にするように しました。 ruby-bugs-ja:PR#54

Marshal

無名のクラス/モジュールは 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]

*122

モジュールのロードの型チェックに誤りがありました。この変更により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"
constants

内部のハッシュテーブルを使用することにより定数参照の速度を改善したそうです。 (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)

とみなすようになりました(これはまだ実験的な変更です)。

Range#to_ary

追加。これにより(配列への暗黙の変換が適用されるので)以下のように書く ことができます。

a, b, c = 1..3
break and next

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

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 節の例外クラスと発生した例外オブジェクトの比較

発生した例外 $! と rescue 節の例外クラスとは Module#=== を使って比較するようになりました。

以前は kind_of? による比較なので基本的な動作に変わりはありませんが、 SystemCallError.=== は特別に errno が一致する例外を同じと見なすよう に再定義されました。これにより、例えば Errno::EWOULDBLOCK と Errno::EAGAIN が同じ意味(同じerrno)の場合にどちらを指定しても rescue できるようになりました。

Array#collect
Array#map

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
Array#dup

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
Array#fetch

追加

Array#insert(n, other, ...)

追加 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

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]
Array#sort!

常にself返すようになりました。

将来にわたってこのことが保証されるわけではないそうです ruby-dev:12506

Class.inherited

(注: 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]
Dir.open

ブロックを伴う場合File.openと同様に、ブロックの結果がメソッドの 戻り値になりました。(1.6以前は nil 固定)

Dir.chdir

ブロックを指定できるようになりました。

Dir.glob

先行するバックスラッシュにより、ワイルドカードをエスケープ できるようになりました。 また、空白類に特殊な意味はなくなりました('\0'の効果は残っています)。

Enumerable#all?
Enumerable#any?
Enumerable#inject

追加

File.lchmod
File.lchown

追加

IO.for_fd

追加

IO.read

追加。ruby-talk:9460が実装に至った経緯だと思う

Interrupt

Interrupt は、SignalExceptionのサブクラスになりました。 (1.6以前はExceptionのサブクラス)

Marshal::MAJOR_VERSION
Marshal::MINOR_VERSION

追加。Marshal が出力するダンプフォーマットのバージョン番号です。 ruby-dev:14172

MatchData#to_ary

追加 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]

とすることができます。

Math.acos(x)
Math.asin(x)
Math.atan(x)
Math.cosh(x)
Math.sinh(x)
Math.tanh(x)
Math.hypot(x,y)

追加

Module#included

追加。Module#append_feature の後に呼ばれるhook

Module#method_removed
Module#method_undefined

追加

Numeric#/(other)

追加。商を返します。

NoMethodError

追加 ruby-dev:12763

NotImplementError

旧称は削除されました。NotImplementedErrorを使ってください

Object#singleton_method_removed
Object#singleton_method_undefined

追加

Object#singleton_methods([all])

省略可能な引数 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"]
Process.times

Time.times から移動しました。 (Time.times も残っていますが、warningが出ます)

Process::Status

追加。$? の値も整数からこのクラスのインスタンスになりました。

Process.waitall

追加

Range#include?
Range#member?

追加

Range#to_ary

追加。to_a と同じ

Regexp.last_match(n)

optional な引数が追加されました。

Regexp#options

追加

String#casecmp(other)

追加。大文字小文字の区別をせずに文字列を比較。

String#insert(n, other)

追加

str[n, 0] = other と同じ(ただし self を返す)

Symbol.all_symbols

追加 ruby-dev:12921

Symbol#intern

追加

SystemCallError.===

追加 (上記 「rescue 節の...」 を参照のこと) ruby-dev:12670

SystemExit#status

追加

TCPSocket.new
TCPSocket.open

ローカル側アドレスを省略可能な第3,4引数で指定できるようになりました。

Thread#keys

追加。Thread固有データのキーの配列を返します。

Time

負の time_t を扱えるようになりました(OSがサポートしている場合に限る)

p Time.at(-1)
=> Thu Jan 01 08:59:59 JST 1970
Time#to_a
Time#zone

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.

Title: 過去の遺物

以下に挙げる変数名、メソッド名、オブジェクト名は古い名前です。 使用すると、警告が出たり、ある日突然なくなったりするかもしれません。

メソッド indexes, indicies (Array, Hash, ENV)

version 1.7 では、使用すると

warning: Array#indexes is deprecated; use Array#select

と警告が出ます。

メソッド名として動作を正確に表してない、index との混同がややこしいため ということです。 ruby-talk:10830 とか ruby-talk:11066 で議論が起こってい ました。

警告メッセージにあるように select がその候補になっています。 (どこで、select になったのかがわかりません。どなたか教えてください) *123

NotImplementError

NotImplementedErrorの旧称

version 1.7では、旧称は削除されました。

MatchingData

MatchDataの旧称

メソッド Array#filter

Array#collect! に置き換えられました。

このメソッドを使用すると警告メッセージが出ます。 (1.7 ではこのメソッドはなくなりました。)

メソッド Time.times

version 1.7 から Process.times に移動しました。version 1.7 で Time.times を使用すると警告メッセージが出ます。

関数 iterator?

メソッドに付いたブロックが必ずしも繰り返さないことからイテレータはブ ロック付きメソッドの総称ではなくなりました。そのためブロック付きで呼 ばれたかどうかの判断は関数 block_given? に名称が変更されました。

が、イテレータという用語自体は依然使われ続けています。(このマニュア ルでも使っています)そのためこの関数が消えることもないかもしれません。

正規表現の //p オプション

p オプションはなくなりました。入れ代わりに m オプションが導入されましたが これは p オプションとは意味がまったく違います。

正規表現の p および m オプションの違い

//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 を参照するにはこれらの定数を通してしか行えま せんでした。現在、疑似変数 true, false, nil によっ て直接これらの特殊なオブジェクトを参照することが出来るためわざわざ定 数を使う必要はなくなりました。(疑似変数はパーサが解釈するのでほんの わずか速いかもしれません:-)

大文字をこよなく愛する汎用機系の人(偏見)は使い続けても問題ないでしょ う:-)

組込み定数 VERSION,RELEASE_DATE,PLATFORM

RUBY_VERSION,RUBY_RELEASE_DATE,RUBY_PLATFORMの旧称。

ObjectSpace.add_finalizer
ObjectSpace.remove_finalizer
ObjectSpace.call_finalizer
ObjectSpace.finalizers

使用すると warning が出ます。これらのメソッドは以前 final.rb で提供 されていた

ObjectSpace.define_finalizer
ObjectSpace.undefine_finalizer

が組み込まれたことによって obsolete になりました(従って、final.rb も obsolete になりました)。

Title: DOSISH 対応

ruby version 1.7 では、DOSISH対応(DOS/Windows のパス名の扱いに対する変 更)が含まれています*124。 (現在の)変更点を以下に示します。

なお、これらの変更は mswin32版、mingw32版, human68k版, os2_emx版の Ruby にのみあてはまります。

とりあえずの目標として、

への対応が挙げられていますが、ドライブレター対応などの微妙な部分については現在もruby-listなどで議論が継続されています。 現時点では、Fileの各メソッドに対する\対応, マルチバイトパス名対応, UNC 対応が実装されています。ruby-dev:13817, ruby-dev:14097

以下、各メソッドの挙動について...

File.dirname

パスセパレータとして従来の/に加えて\も認識するようになっています。 これに合わせて、マルチバイトで記述されたパス名への対応も行われています。

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:."
File.basename

パスセパレータとして従来の/に加えて\も認識するようになっています。 これに合わせて、マルチバイトで記述されたパス名への対応も行われています。

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.split

File.dirname と File.basename が変更されているので、File.split もそれに準じた 結果を返します。

File.expand_path

ドライブレター対応に関して、下記のような案が提示されています。

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"
   (なんらかの例外)
File.join

ドライブレター対応に関して、下記のような案が提示されています。

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"
File.fnmatch
Dir.glob
Dir[]

Title: 疑似BNFによるRubyの文法

以下に疑似BNFによるRubyの文法を示します。より詳しくは parse.y を 参照してください。sample/exyacc.rbを使うと規則だけを取り出せますので 活用しましょう。

*125 *126 *127 *128

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

Title: Ruby用語集

1 A

AWK

エイホ(A)、ワインバーガー(W)、カーニハン(K)による 小型のスクリプト言語

2 B

blade

ml archive (blade/ruby)

3 C

Coerce

数値の型変換を行うメソッド。数値計算のメソッドは自分の知らな いインスタンスが引数として渡された時にはcoerce メソッドを使って変換を行うように取り決められている。 coerceメソッドは引数として与えられた値(を変換し た値)と自分(必要ならば変換した値)のペアを返す。

Rubyのライブラリの数値型の変換順序は

Fixnum -> Bignum -> Rational -> Float -> Complex

になっている。

4 D

Data

CレベルのポインタをRubyオブジェクトとして見せるためのラッパー。 Cポインタと、mark関数、free関数から作る。Cを使ってRubyに機能 を追加しようとする人はぜひこのクラスの使い方をマスターする必 要がある。逆にいうとそういう予定のない人には用事がないクラス でもある。

defined?

いろいろなもの(式)が本当に定義されているかどうか調べてくれる 演算子。定義されていなければnil、定義されてい ればその式の種別を示す文字列を返す。defined?は メソッドのようにみえるがRubyの文法に組み込まれた演算子で、引 数の評価を行わない。よって

defined? print("abc\n")

はなにも出力しない。

5 E

Eiffel

オブジェクト指向プログラミング言語。matzは昔この言語の作者の 本(Object-oriented Software Construction 邦訳「オブジェクト 指向入門」)を読んで目から鱗が落ちたらしい。その割にはRubyは Eiffelに似ていない。似ているのはブロックがendで 終るところと、rescueという予約語だけか。

end

ブロック構造を終える予約語。ある統計によればRubyを最初に見た 人の33%がこれを見てPascalを連想するという(嘘)。しかし、実際 にはbeginと対にならないこの形式はPascalというよりAdaやEiffel に近い。

RubyがCやPerlで慣れ親しんだ {}を使わなかったの は以下の理由である

ENV

環境変数をアクセスするためのHash と同様の動作をするオブジェクト。実際には特異メソッドを付加し たObjectクラスのイン スタンスである。このオブジェクトによって 環境変数を変更すると、 Rubyの子プロセスにも引き継がれる。

6 F

FAQ
Frequently Asked Questions

よくある質問とその答え集。 Ruby FAQはまだまだ発展途上である。質問と答えは随時募集中。

7 G

goto

Rubyにないもの。gotoがないのはそれが「あるべきでないから」ではなく、 「実装するのが面倒だったから」である。 gotoの代りはcatch/throwや例外で実現する。

8 H

9 I

10 J

JARH
Just another Ruby hacker,

11 K

12 L

13 M

main

トップレベルでのselfselfがないわけにはいかないので、ただそこにある ためだけの単なるObjectクラスのインスタンスであるが、 Objectクラスを操作するため、いくつかの特異メソッドを定義して ある。

定義されている特異メソッド

matz

Rubyの作者。まつもと ゆきひろとも言う。 <URL:http://www.st.rim.or.jp/~fuku/cmail/> と3人の子供の父親でもある。

Mix-in

アイスクリームにいろんなものをまぜて新しい味を作ること。転じ てモジュールをクラスに混ぜて機能を追加 すること。継承を参照。

Rubyでは多重継承を採用せず、is-aの関係のための継承と、機能の 共有のためのMix-inを用意している。これは多重継承を濫用すると 関係が混乱するというmatzの信念のためである。

14 N

15 O

16 P

Perl

何だったっけ?

POLS

Principle of least surprise

Python

Rubyのライバル。「年を経た蛇」。matzがPythonに満足していれば Rubyは生まれなかったであろう。一番気になっているのは名前の長 さ(6文字)である。

17 Q

18 R

RAA

Ruby Application Archive(RAA)

RCR

Ruby Change Request

RD

Ruby Document

Ruby

オブジェクト指向スクリプト言語。Rubyの名前は「Perlに続く (pearlは6月の誕生石、Rubyは7月の誕生石)」という程度の意味で 名付けられた。Rubyは別に何かの略ではない。

19 S

Sather

オブジェクト指向プログラミング言語。matzは EiffelよりもSatherが好きだ。しかし、 SatherもやっぱりRubyには全然似ていない。

self

レシーバを参照する式。なぜ selfかというと、メソッド を動詞と考えるとレシーバは主語に当たり、メソッドから見ると 自分であるからという説があるが、Rubyでは深 く考えず、単にSmalltalkを真似ただけ だ、という説が有力である。

Smalltalk

オブジェクト指向プログラミング言語。現在の オブジェクト指向と いうパラダイムの基礎を築いた言語。

super

オーバーライドしたメソッドから上位のメソッドを呼び出す方法。 引数を省略した時には呼び出し元のメソッドと同じ引数で呼び出さ れる。

20 T

Thread

もとはThread of controlの略。一連の制御の流れのこと。Rubyでは 一つのプログラムの中に複数のスレッドが存在できる。

21 U

undef

メソッドを未定義状態にすること。継承Mix-inもクラスにメソッドを追加するこ とだが、undefを使えばメソッドを取り除くことがで きる。ただし、クラスの実装に必要なメソッド(メソッド内部から 呼ばれているメソッド)を外してしまうと痛い目に遭う。

22 V

23 W

24 X

25 Y

26 Z

27

イテレータ
Iterator

繰り返し子。メソッドに渡すことのできるあるコードの集まりをブ ロックと呼び、ブロックが与えられたメソッドをイテレータと呼ぶ (こともある)。一般にブロックは複数回実行されるので繰り返し子 (iterate=繰り返す)と呼ばれるが、慣習として一度しか実行しな かったり、繰り返さない場合にもブロックの与えられたメソッドを イテレータと呼ぶことがある。しかし、一回でもゼロ回でも繰り返 しには違いないので嘘つきとは呼ばないように。

イテレータの中では yieldを使って ブロックを実行することができる。

あ、そうそう。内部でブロックを評価しないメソッドにブロックを 与えてもなにも起きない。エラーも起きないが、がっかりしないよ うに。

インスタンス
Instance

オブジェクトのこと。オブジェクトがある クラスに所属することを強調する意味あいがあるらしい。オブジェ クトなんだかインスタンスなんだか混乱してオブジェクト指向に挫 折する人は多いと聞く。

インスタンス変数
Instance Variable

オブジェクトに固有の変数のこと。Rubyのインスタンス変数は識別 子の直前に@をつけたものであり、メソッドの中から しか参照できない。

オーバーライド
Override

再定義のこと。スーパークラスまた はincludeしているモジュールで定義され ているメソッドと同じ名前のメソッドを定義すること。オーバーラ イドした上位のメソッドは superを使って呼び出すこと ができる。

オブジェクト
Object

もののこと。「愛」は多分オブジェクトではな いが、「ラブレター」はオブジェクトである。あるものがものであ るか、そうでないかは多分に哲学的である。この辺がオブジェクト 指向は難しいといわれる原因かも知れない。コンピュータ業界では メモリ中の特定の空間のことをオブジェクトと呼ぶ人がいたりする 人がいる。困ったものだ。カプセル化抽象データ型参照。

オブジェクト指向

オブジェクトを基本にしたパラダイム。 英語の"Object-Oriented"という形容詞が、日本に来て名詞化した。 オブジェクトを考え方の中心に置けば、なんでも良いようにも思え るが、一般的には

が必要らしい。 なんでも解決できる「魔法」のように考える人もいるが、世の中そ んなに甘くない。誕生から20数年を経てようやっと実用的に使われ るようになった…んだろうな、多分。

オブジェクト指向設計
Object-Oriented Design

オブジェクトを基本にしたシステム設計

オブジェクト指向プログラミング
Object-Oriented Programming

オブジェクトを基本にしたプログラミング。

オブジェクト指向分析
Object-Oriented Analysis

オブジェクトを基本にしたシステム分析。

28

カプセル化
Encapsulation

データに対する直接的な操作はデータの型に付随する特定の手続き (メソッドと呼ぶ)からだけ行うことにより、 内部構造や処理のアルゴリズムを外部から隠してしまうこと。 抽象データ型参照。

Rubyはインスタンス変数はメソッドからしか参照できないので、カ プセル化が強制されているといえる。

環境変数
Environment Variable

親プロセスから子プロセスに対して受け渡される値。 ENVでアクセスされる。 子プロセスに渡るのは環境変数のコピーなので、子プロセスから親 プロセスに環境変数を使って情報を受け渡すことはできない。 親はなかなか子供に耳を傾けないものである。

関数
Function

厳密にいうとRubyに関数はない。しかし、レシーバを省略したメソッ ド呼び出しは外見が関数に似ているし、 selfやインスタンス変数など レシーバの情報を全く参照しない事実上の関数として働いていると いっても良いメソッドもある。だから厳密でない言い方としてそう いうメソッドを関数と呼ぶこともある。

そういう関数(的メソッド)は大抵レシーバを省略した形式でしか呼 び出せないように可視性がprivateに 設定してある。このようなメソッドの代表として モジュール関数がある。

クラスメソッド
Class Method

クラスのメソッド。全てのクラスのクラス Classで定義されている 全てのクラスで共有されているメソッドとクラスそれぞれが固有に持っている 特異メソッドとがあるが、そんな ことは大した問題ではない。 クラスメソッド内でのselfはクラスであるので勘違いしないように。

グローバル変数
Global Variable

プログラム全体から参照できる変数。危険。多用しないこと。

継承
Inheritance

先祖や親戚から受け継いだものに頼り切って、 自分では最低限のことしかしないこと。現実世界では嫌な奴。 転じて、あるクラスに機能を追加した新しいクラス を作ること。継承はis-aの関係を表現するのに有効である。たとえ ば、学生一般の性質を記述した「学生」クラスを継承して、実験に 苦しめられる「工学部生」クラスを作ることができる。is-aの関係 がなく、単に性質や機能を共有する場合にはMix-in を使うことが望ましいとされる。

29

再定義
Redefinition

オーバーライドのこと。

辞書
Dictionary

項目からその定義を取り出すことができるもの。転じて ハッシュの別名。オブジェクト指向の起源と も呼べるSmalltalkにおいてハッシュに 相当するデータ構造が「辞書」と呼ばれていたせいで辞書という用 語になじんでいる一群の人々がいる。

初期化
Initialize

オブジェクト(あるいは「なにか」)を「使える」状態にすること。 インスタンスの初期化には Object#initialize メソッドを再定義する。クラスのメソッド Class#newのデフォルトの 定義は新たに生成したインスタンスに対して、 initializeを実行する。newへの 引数はそのままinitializeに渡される。また、 newがブロックとともに呼び出された時には initializeにそのブロックがそのまま与えられる。

ということはClass#new を再定義する必要はないはずだ。

スクリプト
Script

台本。転じて、インタープリタが解釈する比較的短いプログラムの こと。もちろん中には超大作の台本もある。

スクリプト言語
Script Language

スクリプトに従ってバッチ処理を行うイン タープリタのこと。人間も台本を読むという点においてスクリプト 言語である。

即値
Immediate Value

参照ではなく、実際の値が変数に格納さ れるもの。Rubyの現在の実装ではFixnumとnil/true/falseだけが即 値である。しかし、Fixnumが即値でないRubyの実装があっても構わ ないし、モデル上全ての値がオブジェクトへの参照であると考えて も差し支えない。

ソート
Sort

順番に並べ替えること。Ruby は数え上げる事ができて (Enumerable がincludeされていて)、各要素に順序 が定義されて(<=> が定義されて)いれば、配列に限らずどん な複雑なオブジェクトの集まりもソートしてくれる。

30

大域脱出
Non-Local Exit

break, next, redo, retry, return などのメソッドの範囲内での脱出ではなく、捕捉されない限りメソッ ド呼び出しの階層を遡って中断するタイプのものを大域脱出と呼ぶ。 Rubyの大域脱出には、例外によるものとcatch/throwがある。

ほとんどの例外は(exitで発生するSystemExit を含めてrescue で捕捉できるが、捕捉することに意味がない例外 (例:メモリ割当に失敗した/インタプリタそのもののバグ)は 捕捉の対象にならない。

catch/throwはthrowされると指定されたタグと同じ タグを持つcatchまで一気にジャンプするものである。

ダイナミックローカル変数
Dynamic Local Variable

ローカル変数 の一種。Rubyのローカル変数はスコープが 静的に決まるためコンパイル時に変数が作成されるが、ダイナミックローカ ル変数は、実行の都度変数が作成される。ブロックの中で初めて代入された ローカル変数はダイナミックローカル変数となり、そのスコープはブロック の中だけとなる。これは、Thread 毎に独立した変数を持 つためにある。

抽象データ型
Abstract Data Type

データの構造とそのデータに対する操作をひとまとめにしたものを 抽象データ型と呼ぶ。抽象データに対する操作は必ずその操作を経 由する必要がある。結果、データ構造は外部からは直接参照されず、 内部構造の変更が外部に悪影響を及ぼさない。このことを カプセル化と呼ぶ。

定数
Constant

一度定義したら値を変えることができない変数。 でも、この定義は矛盾しているなあ。

動的結合
Dynamic Binding

操作の対象のデータ型に合わせて適切な手続き(メソッド)が実行時 に選択されること。プログラムの柔軟性を高める働きがある。 オブジェクト指向の要件のひとつ。 Rubyでは変数に型が無いので動的結合は必然である。

特異クラス
Singleton Class

ある特定のオブジェクトだけのための仮想的なクラス。

特異メソッド
Singleton Method

ある特定のオブジェクトにだけ定義されたメソッド。 メソッド参照。 特異メソッドは以下の場合に他のオブジェクトにも引き継がれる。

特異メソッドで元のクラスのメソッドをオーバーライドした場合は もとのメソッドはsuperで呼び 出すことができる。

ドキュメント
Document

matzの苦手なもの。彼は普段から「ソースがドキュメントだ。バグ も完全に記述されている」と主張しているが、誰も受け入れない。 当り前だ。

31

32

バイトオーダー
Byte Order

0x01020304という4バイトデータを1,2,3,4 と配置するか、4,3,2,1と配置するかということ。前 者をビッグエンディアン、後者を リトルエンディアンと呼ぶ。どちらが 良いかという論争は時のはじめから続いていてまだ結論が出ていない。

破壊的
Destructive

String#chop!, Array#concat などの メソッドは、レシーバの状態を変化させるので、 「破壊的な作用をする」という。 めったにコンピュータを壊すことはない。

ハッシュ
Hash

Rubyにおけるキーから値へのマッピングを表すデータ構造。 連想配列とか 辞書とも呼ばれる。ハッシュがハッシュ と呼ばれるのはその実現に「ハッシュ表」と呼ばれるアルゴリズム が使われているからである。ハッシュというのは「切り刻む」とい う意味で、「ハッシュド・ビーフ」の「ハッシュ」である。

パラダイム
Paradigm

「考え方」の難しい表現。素直に分かりやすい言葉を使えばいいのに…。

ビックエンディアン
Big Endian

アメリカ大陸原住民…はインディアン。 こっちはエンディアンで語源はスウィフトの「ガリバー旅行記」に出て来る 卵を丸い端から食べる人たちである。 当然、尖った端から食べる人たちは リトルエンディアンである。 コンピュータ業界ではCPUなどがデータを並べる時の形式のひとつで、 ネットワーク族はビッグエンディアンを好むという。 バイトオーダー参照

ビルトインクラス
Built-In Class

Rubyインタプリタ組み込みでインスタンスの構造が 通常のオブジェクトと異なるクラス。 これらのクラスを継承したクラスを定義することはお勧めしない。 Rubyのビルトインクラスは以下の通りである (本当はもっとあるけど気にしないように、ちゃんと 組込みクラス/モジュール/例外クラス に列挙されてるのだから)

ブロック
Block

ループを構成したり、家や塀を建てたり、人を殴ったりするもの。

変数
Variable

オブジェクトにつける名札。Rubyの変数には グローバル変数ローカル変数インスタンス変数がある。 それと定数は値を変えることができない ので、数ではないが、名札であるという点に おいては変数と同じである。

ポリモルフィズム
多態, Polymorphism

対象になるオブジェクトによって実際の操作が決定されること。 Rubyではレシーバのオブジェクトに応じ てメソッドが選択されることによって実現されている。

33

モジュール関数
Module Function

関数のように用いられるメソッドの中で、 モジュールのメソッドとしても、特異メソッドとしても定義されて いるものはモジュール関数と呼ばれる。例えば Mathモジュールのほとんどのメソッドは モジュール関数である。これらのメソッドは、例えば

Math.sqrt(2)

という形式でも

include Math
sqrt(2)

という形式でも使えて便利である。

メソッド
Method

オブジェクトに対する操作。操作対象のオ ブジェクト(レシーバ)は selfで参照できる。 Rubyの場合ビルトインクラスのオブ ジェクトを除けば、オブジェクトの構造は動的に決まるので、ある オブジェクトの性質はそのオブジェクトに定義されているメソッド によって決定される。

34

35

リトルエンディアン
Little Endian

最初10人いて段々減っていく。コンピュータ業界ではデータを並べ る時の形式のひとつで、非常に大きなシェアを持つあるCPUメーカー はリトルエンディアンを好むという。バイトオーダー参照

例外
Exception

例外的な状況で発生するもの。例外が発生すると beginrescue節を使って明示的に捕捉されない限り、 呼び出し階層を遡ってプログラム(thread)の実行は中断される。例外の おかげでRubyプログラムはほとんどの場合例外的な状況についていちいち チェックせずにすむ。例外の発生した場所の情報は $@に、例外そのものに関する情報は$! に格納されている。

レシーバ
Receiver

メソッドの実行主体。メソッド呼び出し式の`.'の左 側にあるもの。メソッド内では selfで参照できる。レシーバ のインスタンス変数@変数名という形式でアクセスできる。

連想配列
Associative Array

ハッシュの別名。ハッシュが任意のキーから 値を取り出すことができるので、「連想」と、またハッシュは添字 が数字でない配列とみなすことができるので「配列」と呼ぶらしい。 昔々は連想配列(連想記憶と呼ばれていた)はハードウェアによって 実現されるものだと考えられていたが、計算速度の向上や適切なア ルゴリズムの発見(「ハッシュ表」と呼ぶ。ハッシュの語源)により ソフトウェアのみによって実現されるようになった。

ローカル変数
Local Variable

ある範囲内でのみ参照可能な変数。その範囲をスコープと呼ぶ。 Rubyのスコープは

で、ブロックだけは外側のスコープのローカル変数もアクセスでき る。ローカル変数の有効範囲はスコープでの最初の代入が現れた場 所からスコープの終りまでである。有効範囲は静的に決まり、実際 に実行されるかどうかは関係ない。

36

37 Symbol

Title: packテンプレート文字列

以下にあげるものは、Array#packString#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の説明」としています。

1 使用例

以下、pack/unpack の使用例の一部です。

pack を使用しなくても同じことができる場合はその例も載せています。 pack は暗号になりやすい面があることを考慮し、pack を使いたくない人 に別解を示すためです。

Title: sprintfフォーマット

Ruby の sprintf フォーマットは基本的に C 言語の sprintf(3) のものと同じです。ただし、short や long などの C 特有の型に対する修飾子が ないこと、2進数の指示子(%b)が存在すること。sprintf のすべての方言をサ ポートしていないこと(': 3桁区切り)などの違いがあります。

rubyのsprintfフォーマットに関する完全な説明は以下の通りです。

以下はsprintfフォーマットの書式です。[]で囲まれた部分は省略可 能であることを示しています。

%[引数指定$][フラグ][幅][.精度]指示子

`%' 自身を出力するには `%%' とします。

以下それぞれの要素に関して説明します。

1 フラグ

フラグには `#', `+', ` '(スペース), `-', `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

出力が右詰めの場合に余った部分に空白の代わりに `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"

2

0以外の数字で始まる数字列は幅指定になります。幅は生成文字列の長さを示 します。後述の「精度」の値によらずこの幅分だ けの文字列が生成されます。

幅の指定は「フラグ」で付与される " ", "+", "-", "0b", "0", "0x", "0X" の長さも考慮されます。

p sprintf("%#05x", 10) # => "0x00a"

幅は「最低限必要な幅」の指定になります。結果の文字列が指定した幅を超 える場合は幅の指定は無効になります。

幅として `*' を指定すると幅の値を引数から得ることになります。

p sprintf("%10s", "foo")    # => "       foo"
p sprintf("%*s", 10, "foo") # => "       foo"

3 精度

"." の後に続く数字列は精度を表します("." のみの場合 ".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"

4 指示子

指示子は引数の型の解釈を示します。指示子を省略することはできません。 指示子には大きく分けて

があります

c

引数の数値(0〜255)を文字コードとみなして対応する文字を出力します。 引数が数値、String、 nil, true, false 以外のオブジェクトでは to_int メソッドによる変換を試みます。

フラグ `-' と「」 の指定だけが意味を持ちます。

s

文字列を出力します。

引数がStringオブジェクトでなければ to_s メソッドにより文字列化 したものを引数として扱います。

d
i

引数の数値を10進表現の整数として出力します。

浮動小数 Float オブジェクトは整数に変換されます(小数部切捨て)。

文字列はInteger()と同じ規則で数値に変換されます。 nil, true, false 以外のオブジェクトでは to_int メソッドによる変換を 試みます。

u

引数の数値を符号なし整数とみなして10進表現の整数として出力します。

p sprintf("%u", -1) # => "..4294967295"

は、p ".." + 0xffff_ffff.to_s を出力しています。

b
o
x
X

整数をそれぞれ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
e
E
g
G

`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"

*132

5 引数指定

利用頻度が低いので最後に説明します。

nth$

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"

Title: Ruby FAQ

  1. 一般的な質問
  2. 変数、定数、引数
  3. イテレータ
  4. 構文
  5. メソッド
  6. クラス、モジュール
  7. 組込みライブラリ
  8. 拡張ライブラリ
  9. ドキュメントされていない機能
  10. 日本語の取り扱い
  11. Rubyの処理系について

1 一般的な質問

2 変数、定数、引数

3 イテレータ

4 構文

5 メソッド

6 クラス、モジュール

7 組込みライブラリ

8 拡張ライブラリ

9 ドキュメントされていない機能

10 日本語の取り扱い

11 Ruby の処理系について

Title: 1. 一般的な質問

1 1.1 Rubyとは何ですか

一言で言えば、

シンプルかつ強力なオブジェクト指向スクリプト言語

です。

perlのようにテキスト処理の分野に威力を発揮します。もちろんそれだけでは なく、Rubyで実用的なサーバーアプリケーションを作成するなどということも 可能です。

Rubyにはたくさんの言語のよい部分が取り込まれており、その結果どの言語とも 異なる言語になっています。

Rubyは以下のような特長を持っています。

2 1.2 名前の由来を教えてください

以下はまつもとさんのruby-talk:00394(June 11, 1999)での紹介の翻訳です。

まつもとさんは、自分の新しい言語の名前をPerlのように何か宝石の 名前からとろうとし、同僚の誕生石がRubyだったので、Rubyとした そうです。

その後、誕生石としては、pearl => 6月、ruby => 7月、活字の 大きさとしては、pearl => 5pt、ruby => 5.5ptなど、rubyが pearlの直後に来ている例があるのに気づき、Perlより新しく、できれば より良い言語の名前としてRubyが新しいスクリプト言語の名前として ふさわしいと思ったそうです。

まつもとさんは、RubyがPerlの代わりになる日を待っています(^^)。

3 1.3 Rubyの歴史を教えてください

まつもとさんのruby-talk:00382(June 4, 1999)での紹介の翻訳です。 Rubyの誕生日はruby-list:15997により修正されました。

4 1.4 どこで手に入りますか

Rubyの最新版は<URL:ftp://ftp.ruby-lang.org/pub/ruby/>で手に入ります。

ミラーサイトは次のとおりです。

cygwin版とmingw版とdjgpp版はRuby Binariesにバイナリがあります。

なお、Windows(cygwin)では初心者向けにRuby Entry Packageが用意されています。 そのインストール方法については初心者のためのRubyインストールガイドを見てください。*134

5 1.5 Rubyのホームページを教えてください

Rubyの公式ページは <URL:http://www.ruby-lang.org/> です。

6 1.6 Rubyのメーリングリストはありますか

現在Rubyの話題を扱う公式のメーリングリストは主に五つあります。

詳しくはRubyメーリングリストをご覧ください。

7 1.7 メイリングリストの過去メールを調べたいのですが

メイリングリスト検索用のフォームが、 <URL:http://blade.nagaokaut.ac.jp/ruby/ruby-list/index.shtml><URL:http://ruby.freak.ne.jp/>にあります。

また、ML Topicsには、 過去メールの主な話題がピックアップされています。

8 1.8 rubyistとruby hackerの違いは

まつもとさんによると、rubyistとRuby hackerは次のような定義だそうです。

Rubyに対して単なるお客さん以上の気持を持っている人がrubyistです。たとえば

一方、Rubyに関して技術レベルの高さをあわらす人はRuby hackerと呼びましょう。 たとえば

などはRuby hackerでしょう。

これらは称号は自称されるもので別に私が公式認定をするようなものではあり ませんが、上の例でほとんど名指しされている人は、まつもとがこの人たちを {rubyist、Ruby hacker}として尊敬を込めて認めていることを表します。

9 1.9 "Ruby"と"ruby"はどっちが正しいのですか

Rubyの正式な表記は"Ruby"です。ただし、コマンド名は"ruby"ですし、 また並列して違和感がない限り、Rubyの代わりにrubyを使うことは 許容されます。

ただし、「RUBY」、「ルビー」、「るびー」は言語名としては許容されていません。

歴史的には"ruby"が正式名称だった時代があります。

10 1.10 Rubyの参考書を教えてください

『オブジェクト指向スクリプト言語Ruby』 まつもと ゆきひろ・石塚圭樹共著 アスキー(ISBN4-7561-3254-5)の他に何冊か刊行されています。 詳しくは「Rubyに関する書籍」をご覧ください。

正規表現に関しては、Jeffrey E. F. Friedl著「詳説正規表現」(ISBN4-900900-45-1)が オライリージャパンから出ています。様々な正規表現の実装に触れており、 Rubyの正規表現を理解するにも有用です。

11 1.11 マニュアルを読んでも理解できないところがあるのですが

Rubyは、基本的な構文はRuby1.0以来大きくは変わっていませんが、絶えず 拡張、修正が行われていますので、ドキュメントが最新バージョンに追い 付いていないところがあります*135。 また、ソースがドキュメントだという説もあります。

分からなくなったら、遠慮なくruby-listで 質問すると、教祖まつもとさんをはじめ、尊師の方々や私もはまったという 人たちに分かりやすく教えていただけます。

質問をするには、ruby -vの結果と、はまったスクリプト (長い場合は本質的なところを切り出して)を示せばよいでしょう。

irbを使っている場合は、irb固有の問題もありますので、 irb --single-irbで試してみるか、rubyで実行し直して 確認することをおすすめします。

MLを検索すれば、かなりの疑問が解決するとは思いますが、メールも 大量になってしまって、ありふれた検索では絞り込みにくくなっています。 最近のものくらいはチェックしておくのがネチケット(RFC1855の3.1.1、3.1.2参照) というものだとは 思いますが、言うは易く、行うは難しですし、新しい視点も生まれるかも しれません。思い切って質問してみましょう。

12 1.12 ruby のキャラクターは羊?

羊、ハチドリ、うさぎ...*136

Title: 2. 変数、定数、引数

1 2.1 変数や定数への代入によりオブジェクトはコピーされますか

変数や定数は、あるオブジェクトを指しています。何も代入しなくても nilオブジェクトを指しています。代入は、変数や定数が新しいオブジェクトを 指すようにします。

したがって、代入によりオブジェクトがコピーされて新しく作られることは なく、右辺の表現の表しているオブジェクトを左辺の変数や定数が指すように することが代入によって行われます。

という説明で満足していただければいいのですが、これでは満足できない という方もいらっしゃるかもしれません。このような理解で問題が 生じることはないのですが、実は、FixnumNilClassTrueClassFalseClass のインスタンスは、直接変数や定数が保持していますので、これらは 代入によってコピーされることになります。これら以外のクラスのインスタンスは メモリの別の場所にあり、それを変数や定数が参照することになります。 即値と参照を参照してください。

2 2.2 ローカル変数のスコープはどのように決められていますか

トップレベル、クラス(モジュール)定義、メソッド定義のそれぞれで 独立したスコープになっています。ブロック内では、新たなスコープが 導入されるとともに、外側のローカル変数を参照できます。

ブロック内が特別になっているのは、Threadや手続きオブジェクトの 中でローカル変数を局所化できるようにするためです。 whileuntilforは制御構造であり、新しいスコープを 導入しません。 loopはメソッドで、後ろについているのはブロックです。

3 2.3 ローカル変数はいつ参照可能になるのでしょうか

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 といった代入文を置くことがすすめられて います。こうすると、ローカル変数の参照が速くなるというおまけもついて います。

4 2.4 定数のスコープはどのように決められていますか

クラス/モジュールで定義された定数は、そのクラス/モジュールの中で 参照できます。

クラス/モジュール定義がネストしている場合には、内側のクラス/モジュール から外側の定数を参照できます。

またスーパークラス及びインクルードしたモジュールの定数を参照できます。

トップレベルで定義された定数は、Objectクラスに追加されますので、 すべてのクラス/モジュールから参照できます。

直接参照できない定数は、::演算子を使って、クラス/モジュール名を 指定することにより参照できます。

5 2.5 実引数は仮引数にどのように渡されますか

実引数は、メソッド呼出しによって仮引数に代入されます。Rubyにおける 代入の意味は、変数への代入を 参照してください。 実引数が参照しているオブジェクトが、自分の状態を変更するメソッドを 持っている時には、副作用(それが主作用かもしれませんが)に注意する 必要があります。破壊的メソッド参照。

6 2.6 仮引数に代入すると実引数に影響を及ぼしますか

仮引数は、ローカル変数であり、仮引数に代入を行うと他のオブジェクトを 指すようになるだけで、元の実引数のオブジェクトには何の影響もありません。

7 2.7 仮引数の指すオブジェクトにメッセージを送るとどうなりますか

仮引数の指すオブジェクトは、実引数の指しているオブジェクトですから、 そのメッセージによってオブジェクトの状態が変化する場合には、呼出し側に 影響が及ぶことになります。破壊的メソッド参照。

8 2.8 *がついた引数は何ですか

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)

現在、*をつけることができるのは

  1. 多重代入の左辺
  2. 多重代入の右辺
  3. 引数リスト(定義側)
  4. 引数リスト(呼び出し側)
  5. casewhen

の末尾だけです。(1)は

x, *y = [7, 8, 9]

のような形式で、この場合 x = 7y = [8, 9] になり ます。

x, = [7, 8, 9]

のような記述もでき、この場合、x = 7

x = [7, 8, 9]

なら、x = [7, 8, 9] になります。

9 2.9 &がついた引数は何ですか

手続きオブジェクトをブロックとして受け渡しするための引数です。 引数列の一番最後に置きます。

10 2.10 仮引数にデフォルト値を指定できますか

できます。

しかもこのデフォルト値は関数の呼び出し時に評価されます。Rubyのデフォル ト値は任意の式が可能で(C++はコンパイル時に決まる定数のみ)、評価はメソッ ドのスコープで呼び出し時に行われます。

11 2.11 ブロックに引数を渡すにはどうしますか

ブロックの先頭に、仮引数を||で囲って置くと、実引数が多重代入されます。 この仮引数は、普通のローカル変数で、ブロックの外側ですでに使われて いる変数の場合は、そのスコープになりますので、注意が必要です。

12 2.12 変数や定数の値が知らないうちに変化することがありますが

次のような例でしょうか。

A = a = b = "abc"; b << "d"; print a, " ", A
#=> abcd abcd

変数や定数への代入は、オブジェクトを後でその変数や定数で参照する ために用いられます。変数や定数にオブジェクトそのものが代入されて いるのではなく、オブジェクトの参照を保持しているだけです。変数は、 この参照を変更して異なるオブジェクトを参照するようにすることが できますが、定数では一度保持した参照を変更することができません。

変数や定数にメソッドを適用すると、そのメソッドは、変数や定数が 指しているオブジェクトに適用されます。上の例では、<<というメソッドが オブジェクトの状態を変えてしまうために、「予期せぬ」結果が生まれて います。オブジェクトが数値の場合には、数値の状態を変えるメソッドが ないため、このような問題は生じません。数値にメソッドを適用した時には 新しいオブジェクトが返されます。

この例では、文字列で示しましたが、配列やハッシュなど、オブジェクトの 状態を変更するメソッドを持っているオブジェクトでも同様のことが起こり 得ます。

13 2.13 定数は変更されませんか

定数があるオブジェクトを指しているとき、別のオブジェクトを指すように すると、warningが出ます。

そのオブジェクトが破壊的メソッドを持っていれば、オブジェクトの内容は変更できます。

Title: 3. イテレータ

1 3.1 イテレータとは何ですか

ブロックや手続きオブジェクトを活用するメソッドをイテレータと呼びます。

イテレータは制御構造(特にループ)の抽象化のために用いられるメソッド の一種です。

といってもよくわかりませんね。実際の例を見た方が早いかもしれません。イ テレータはコレクションの各要素に対して同じ処理を繰り返したいような場合 によく使われます。例えばこんな感じです。

data = [1, 2, 3]
data.each do |i|
  print i, "\n"
end

このコードの出力はこのようになります。

$ ruby test.rb
1
2
3

つまりdoendで囲まれたブロックが配列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ブロックよりも結合強度が強いためです。

2 3.2 イテレータにブロックを渡すにはどうすればいいですか

イテレータにブロックを渡すには、メソッドの後ろにブロックを置く 方法の他に、手続きオブジェクト(を指す変数、定数)の前に&を つけて引数として渡す方法があります。

3 3.3 ブロックは呼び出したメソッドの中からどのように使われますか

メソッドの中からブロックを使用するには、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"}

4 3.4 Proc.newでは手続きオブジェクトが作られませんが

Proc.newは、ブロックを与えられないと手続きオブジェクトを生成できず、 エラーになります。メソッド定義の中で 使われるブロックなしのProc.newは、メソッド呼出しにブロックが与えられて いることを仮定しています。

Title: 4. 構文

1 4.1 :exit等の:のついた識別子は何ですか

シンボルと呼ばれる、識別子と1対1対応するオブジェクトです *137。 "exit".internとしても求められます。catch, throw, autoloadなどでは、 引数として文字列もシンボルも使えます。

method_missing、method_added、singleton_method_addedはシンボルを 要求します。*138

2 4.2 シンボルと同名の変数の値を取り出すにはどうすればいいですか

symbolのスコープでeval( (:symbol).id2name)とすると、 値が取り出せます。

a = 'This is the content of "a"'
b = eval(:a.id2name)
a.id == b.id

3 4.3 loopは制御構造ですか

メソッドです。ブロックは新しいローカル変数のスコープを導入します。

4 4.4 a +bがエラーになりますが

a(+b)と解析されています。+の両側の空白をなくすか、いれるか のどちらかにしてください。

5 4.5 s = "x"; puts s *10 がエラーになりますが

puts s *10 のところが、s(*10)というメソッド呼出しと解析されて しまいます。s*10にするか、s * 10にしてください。

6 4.6 p {}で何も表示されません

{}がハッシュのコンストラクタではなく、ブロックと解析されています。 p({}) か p Hash.new のようにして回避してください。

7 4.7 pos=() という setter メソッドがあるのに、pos = 1 としてもなにも起こっていないように見える

これは以下のような例です。

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 としてください。

8 4.8 '\1''\\1'はどう違いますか

同じです。シングルクォートの中では、\'\\、行末の\ (改行を無効にします)だけが解釈され、それ以外は解釈されません。

9 4.9 p true or true and falsetrueを表示するのに、a=true if true or true and falseでは、atrueが代入されません。

最初の式は、(p true) or true and falseと解釈されます。 and/orは 文の構成要素として解釈され、pの引数を結ぶ演算子としては解釈され ません。

2番目のは、a=true if (true or true and false)と解釈されています。 ifの方がand/orより優先順位が低いこと、 orandの優先順位が同じなので、 左から順に解釈されることによります。

10 4.10 p(nil || "") はなんでもないのに、 p(nil or "") はパースエラーだと言われます

|| は引数を結ぶことができますが、or は文と文を結ぶことしかできず、 引数を結ぶことができないからです。この違いは、たとえば以下のふたつの 式の結果がどうなるか試してみればわかります。

p nil || ""
p nil or ""

Title: 5. メソッド

1 5.1 オブジェクトにメッセージを送った時に実行されるメソッドはどのように捜されますか

特異メソッド、自クラスで定義されたメソッド、スーパークラス(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で直接[]を再定義すれば、 期待どおりになります。

2 5.2 +-は演算子ですか

+-などは演算子ではなくメソッド呼び出しです。したがって オーバーロードすることもできます。

class MyString < String
  def +(other)
    print super(other)
  end
end

ただし、以下のもの及びこれらを組み合わせたもの(!=、!~)は制御構造であり、 オーバーロードできません。

=, .., ..., !, not, &&, and, |, or, ~, ::

単項演算子をオーバーロード(もしくは定義)するには、メソッド名として +@-@を使います。

=は、インスタンス変数へのアクセスメソッドとして, クラス定義の中で次のようにメソッドを定義することができます。 また、+-なども定義することにより、+= などの自己代入演算も可能になります。

def attribute=(val)
  @attribute = val
end

3 5.3 関数はありますか

Rubyにおいて関数のように見えるものはすべてレシーバ(self)を省略した形の メソッドです。例えば

def writeln(str)
  print(str, "\n")
end

writeln("Hello, World!")

のように一見関数のように見えるものも、Objectクラスに定義された メソッドであり、隠されたレシーバーselfに送られているというわけです。 したがってRubyを純粋なオブジェクト指向言語と呼ぶことができます。

組込み関数のように、selfが何であっても同じ結果を返すメソッドは、 レシーバーを意識する必要がありませんので、関数と考えてもいいという ことになります。

4 5.4 オブジェクトのインスタンス変数を外から参照できますか

直接はできません。あらかじめそのオブジェクトにインスタンス変数を 参照するためのメソッド (アクセサと言います) を定義しておく必要が あります。たとえば以下のようにします。

class C
  def name
    @name
  end
  def name=(str)    # name の後に空白を入れてはいけない!
    @name = str
  end
end

c = C.new
c.name = 'やまだたろう'
p c.name                 #=> "やまだたろう"

またこのような単純なメソッド定義は Module#attrattr_readerattr_writerattr_accessor などを使って簡潔に行うことができます。 たとえば上にあったクラス定義は以下のように書き直せます。

class C
  attr_accessor :name
end

なんらかの理由でアクセスメソッドは作りたくないけれど参照はしたい場合は Object#instance_eval を使って参照することもできます。

5 5.5 privateprotectedの違いが分かりません

privateの意味は、メソッドを関数形式でだけ呼び出せるようにし、 レシーバー形式では呼び出せないようにするという意味です。したがって、 可視性がprivateなメソッドは、自クラス及びサブクラスからしか参照 できません。

protectedも同様に、自クラス及びサブクラスからしか参照できませんが、 関数形式でもレシーバー形式でも呼び出せます。

メソッドのカプセル化に必要な機能です。

6 5.6 インスタンス変数をpublicにしたいのですが

インスタンス変数を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も 参照してください。

7 5.7 メソッドの可視性を指定したいのですが

最初に断わっておくと、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)

同様にpublicpublic_class_methodを用いることでメソッドを publicにすることができます。

デフォルトでは、クラス内でのメソッド定義はinitializeを除いてpublic、 トップレベルではprivateになっています。

8 5.8 メソッド名に大文字で始まる識別子は使えますか

使えます。ただし、引数の無いメソッド呼出しに対して引数を括る()を省略できません。

9 5.9 superArgumentErrorになりますが

メソッド定義中でsuperと呼び出すと、引数がすべて渡されますので、 引数の数が合わないとArgumentErrorになります。異なる数の引数を 指定するには、super()に引数を指定してやります。

10 5.10 2段階上の同名のメソッドを呼びたいのですが

superは、1段上の同名のメソッドを呼び出します。それより上の同名の メソッドを呼び出すには、あらかじめそのメソッドをaliasしておきます。

11 5.11 組込み関数を再定義した時に、元の関数を呼びたい時はどうしますか

メソッド定義の中ではsuperが使えます。再定義する前にalias しておくと、元の定義が保たれます。 Kernelの特異メソッドとしても呼べます。

12 5.12 破壊的メソッドとは何ですか

オブジェクトの内容を変更してしまうメソッドで、文字列や配列、ハッシュ などにあります。同名のメソッドがあって、一方はオブジェクトのコピーを 作って返し、もう一方は変更されたオブジェクトを返すようになっている場合、 !のついた方が破壊的メソッドです。String#concatのように!がつかない メソッドでも破壊的なものはあります。

13 5.13 副作用が起こるのはどんな時ですか

実引数であるオブジェクトに対して、メソッドの中から破壊的メソッドを 適用した場合です.

def foo(str)
  str.sub!(/foo/, "baz")
end

obj = "foo"
foo(obj)
print obj
#=> "baz"

この場合、引数となったオブジェクトが変更されています。でも、これは、プログラム の中で必要があって副作用のあるメッセージをオブジェクトに対し て送っているので当たり前です。

14 5.14 メソッドから複数の戻り値を返すことはできますか

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

こんなことができるわけです。

Title: 6. クラス、モジュール

1 6.1 クラス定義は、一度に行わなければなりませんか

同じクラスを再定義すると、前のクラス定義に追加されていきます。 メソッドを再定義した場合には後のものが上書きしますので、前のものは 失われます。

2 6.2 クラス変数はありますか

1.6より実装されました。`@@'で始まる変数はクラス変数です。

class Foo
  @@F = 0
  def foo
    @@F += 1
    print @@F, "\n"
  end
end

1.4以前までは定数に代入されたコンテナクラス(ArrayHashなど) がクラス変数の代わりに使用されていました。

class Foo
  F = [0]
  def foo
    F[0] += 1
    print F[0], "\n"
  end
end

3 6.3 クラスのインスタンス変数とは何ですか

class Foo
  @a = 123 # (1)
  def foo
    p @a  # (2) ... 123でなくnilになる。
  end
end

(1)がクラスのインスタンス変数、(2)が通常のインスタンス変数です。(2)は クラスFooのインスタンスに属するのに対し、(1)はFooというクラ スオブジェクト(Classのインスタンス)に属します。

インスタンスメソッドからクラスのインスタンス変数に直接アクセスすること はできません。

上のように初期化されていないインスタンス変数とみなされ、nilになり ます。

4 6.4 特異メソッドとは何ですか

特異メソッドは特定のインスタンスに固有のメソッドです。

こんな感じで使います。

foo = Foo.new
def foo.hello
  print "Hello\n"
end
foo.hello

クラスにあるメソッドを追加したいが、わざわざサブクラスを作るほどのこと でもない、といった場合に有効です。

Javaをやってる人は匿名のインナークラスに似てると思うかもしれませんね。

5 6.5 クラスメソッドはありますか

クラスの特異メソッドをクラスメソッドと呼びます。特異メソッドは オブジェクトの固有のメソッドだと説明したばかりですが、Rubyには、 メタクラスという概念があり、すべてのクラスは、同名のメタクラスと いうものを持っていて、これは、Classクラスのインスタンスになって います。ここにクラスメソッドが定義されます。

形式的にはクラス名をレシーバーとして呼べるメソッドということに なります。

ClassのインスタンスであるFooの特異メソッドを考えてみま しょう。

class Foo
  def Foo.test
    print "this is foo\n"
  end
end

呼び出す時はこうです。

Foo.test

何か気付きませんか?

そう、これはいわゆるクラスメソッドですね。

もちろんClassで定義されているメソッドもクラスメソッドとして使えま す。

6 6.6 特異クラスとは何ですか

すでに特異メソッドについては 触れました。

簡単におさらいすると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メソッド)を定義する ことができます。

7 6.7 モジュール関数とは何ですか

モジュールの特異メソッドとして、また同時にprivateメソッドして定義されて いるメソッドをRubyではモジュール関数と呼びます。例えば

Math.sqrt(2)

のように用いることも、

include Math
sqrt(2)

のようにincludeして用いることもでき、とても便利です。

あるメソッドをモジュール関数にするには、モジュール定義の中で

module_function :method_name

とします。

8 6.8 クラスとモジュールの違いは何ですか

モジュールはインスタンスを作れません。 クラスはincludeすることができません。

9 6.9 モジュールはサブクラスを作りますか

モジュールは、クラス(モジュール)にincludeされることにより、多重継承に 相当するMix-inを実現します。これは直接の継承であるサブクラスとは 異なりますが、includeされたクラスは、モジュールとis_a?の関係を 持ちます。

10 6.10 クラス定義の中でクラスメソッドを定義するのと、トップレベルでクラスメソッドを定義する違いは何ですか

前者では定数を直接参照することができます。後者ではクラス名をつけて参照 しなければなりません。

11 6.11 loadrequireはどう違いますか

loadはRubyで書かれたソース(*.rb)のみロードします。

require*.oファイルもロードします。さらに一度 requireしたファイルは2度requireしてもロードしません。

ロードパスも違います。

12 6.12 includeextendはどう違いますか

includemoduleをクラス(モジュール)にインクルードして、 メソッドを関数形式で呼べるようにし、extendmoduleをオブジェクト(インスタンス)にインクルードして、メソッドを 特異メソッドとして追加します。

13 6.13 self というのは何ですか

selfは、メソッドが適用されるオブジェクトそれ自身を表わします。 関数形式のメソッドは、selfをレシーバーとします。

14 6.14 MatchDatabeginend は何を返しますか

*139

$~ に作用して、$0$1などの元の文字列での開始位置、 終了位置を返します。タブ展開の例を参照 してください。

Title: 7. 組込みライブラリ

1 7.1 instance_methods(true)は何を返しますか

klass.instance_methods は、あるクラス(またはモジュール) klass で定義されたインスタンスメソッドだけを返しますが、 klass.instance_methods(true) は、 スーパークラスから引き継いだものも含めてすべてのインスタンスメソッドを返します。 (ただし、public メソッドのみ)

private_instance_methodsprotected_instance_methods の引数の意味も同様です。

*140

2 7.2 randがいつも同じ乱数列を出しますが

ruby 1.4.2以前ではrandは、プログラムが実行される度に同じ乱数列を生成します。 異なる乱数列を生成させるためには、srandで毎回異なる乱数の 種を与えてやる必要があります。srandを引数なしで呼ぶと、その時の 時間を種にしますので、異なる乱数列を生成させることができます。

3 7.3 0から51の中から重複のない5つをランダムに選ぶにはどうしますか

次のメソッドは、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

4 7.4 Fixnumtruenilfalseが即値だということですが、参照との違いは何ですか

特異メソッドを定義できないという制限があります。また、同じ数を 表わすFixnumのインスタンスは常に同じものになりますので、 インスタンス変数を定義した場合には、それも同じものを示すことに なります。

5 7.5 nilfalseはどう違いますか

持っているメソッドの違いは、nil.methods - false.methodsfalse.methods - nil.methodsを表示してください。

メソッドが真偽を返す時は、truefalseを、そうでない 時は値かnilを返すようにすることが好まれます。

?のつくメソッドは、真偽を返すのが一般的ですが、 そうでないものもあります。

6 7.6 ファイルを読み込んで書き換えても変化しません

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 の直前に実行する必要があります。

7 7.7 同じ名前のファイルに書き戻したいのですが

コマンドラインオプションの-i、もしくは、組込み変数$-i に""を指定することにより、同じ名前のファイルに書き戻すことができます。

上の問題は、次のように書くことができます。

$ ruby -i -ne 'print "#$.: #$_"' example

元のファイルを残しておきたければ、-i.bakなどとしてください。

8 7.8 ファイルに書き込んでそのファイルをコピーしましたが、全部コピーされません

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"

9 7.9 パイプで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'としても同じ結果となります。

10 7.10 参照されないFileオブジェクトはどうなりますか

open("file").readというように参照されないFile オブジェクトは、次のガーベッジコレクションでcloseされて 捨てられます。

11 7.11 ファイルをcloseしないのは気持ちが悪いのですが

参照されなくなったFileオブジェクトは、GCで自動的にクローズ されますが、明示的にクローズするには、次の3つの構文から選んで下さい。

  1. a = open "file"
    begin
      a.each {|l| print l}
    ensure
      a.close
    end
  2. IO.foreach("file") {|l| print l}
  3. IO.readlines("file").each {|l| print l}

12 7.12 ファイルを時間の新しい順にソートしたいのですが

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

13 7.13 ファイル中の単語の出現頻度を調べたいのですが

ハッシュのデフォルト値に0を指定して、次のようにすることができます。

freq = Hash.new(0)
open("file").read.scan(/\w+/){|w| freq[w] += 1}
freq.keys.sort.each {|k| print k, "--", freq[k], "\n"}

14 7.14 条件に文字列を使ったとき、文字列が空("")の時にもtrueになります

Rubyでは、nilfalseだけが偽で、それ以外はすべて真に なります。文字列が空かどうかを知るには、""と比較、empty?を使う、 length0と比較するなどの方法があります。

15 7.15 英語文字列の配列を辞書順にソートしたいのですが

ary.collect{|f| [f.downcase, f]}.sort.collect{|e| e[1]}

とします。downcaseで等しくなった場合に、元の文字列で比較を行うのが tipsです。

16 7.16 "abcd"[0]は、何を返しますか

文字aのコード97(Fixnum)を返します。これが文字aと一致するかどうか 調べるには、?aと比較します。

17 7.17 タブをスペースに展開したいのですが

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")}

18 7.18 バックスラッシュをエスケープするにはどうしますか

Regexp.quote('\\')で、エスケープされます。

gsubを使う場合には、gsub(/\\/, '\\\\')では、置換文字列が 構文解析で一度'\\'に変換され、実際に置き換えるときにもう一度'\'と 解釈されるので、 gsub(/\\/, '\\\\\\')とする必要があります。\&がマッチ文字列を あらわすことを使えば、gsub(/\\/,'\&\&')と書けます。

gsub(/\\/){'\\\\'}とブロックを使う形にすれば、エスケープが1回しか 解釈されませんので、求める結果が得られます。

19 7.19 subsub!はどう違うのですか

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!のように破壊的なメソッドは予期しない効果をもたらすことがある ので、使用する場合は十分注意してください。

20 7.20 \Zのマッチする場所はどこですか

\Zは、文字列の最後の文字が\nでない時は文字列の末尾に、 \nのときはこの改行の前にマッチします。

\n に関らず、文字列の最後にマッチさせたい場合は \z を使います。

21 7.21 範囲オブジェクトのコンストラクタ.....はどう違いますか

..は終端を含み、...は終端を含みません。

22 7.22 関数ポインタはありますか

Proc.newproclambdaでProcオブジェクトを作れば、 関数ポインタのような働きをさせることができます。

また、MethodオブジェクトやUnboundMethodオブジェクトも関数 ポインタに近いものです。

23 7.23 threadforkはどう使い分けるのですか

threadforkはそれぞれ以下のような特徴を持っています。

一般にforkthreadを混ぜるのはよくないようです。

あと、Rubyのthreadはタイムシェアリング方式なので、threadを使 うことによって処理が速くなることはありません。

24 7.24 Marshalの使い方を教えてください

オブジェクトをファイルや文字列に格納しておき、後で再生できる ようにするものです。格納は

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した文字列を指定します。

25 7.25 例外処理はありますか

他の先進的な言語と同様にRubyも例外処理をサポートします。

begin
  (例外が発生しそうな処理)
rescue (例外クラス)
  (例外が発生した場合の処理)
else
  (例外が発生しなかった場合の処理)
ensure
  (必ず実行したい処理)
end

begin節で例外が発生するとrescue節が実行されます。 例外が発生しなければelseが実行されます。 ensure節は例外が発生してもしなくても必ず実行されます。rescue, else,ensure節はそれぞれ省略できます。 rescureの後ろに例外クラスが 指定されなかった場合は StandardErrorが指定されたものとみなされ、StandardErrorの サブクラスである例外が捕捉されます。

この式の値は、ensure 節を実行する直前の値です。

もっとも最近起った例外はグローバル変数$!により参照できます。 発生した例外の種類は$!.typeにより調べることができます。

26 7.26 trapはどのように使いますか

以下により、シグナル SIGPIPE が発生するとブロックが実行されます (そして、例外が発生します)。

trap("PIPE") {raise "SIGPIPE"}

27 7.27 ファイルの行数を数えたいのですが

ファイルの最後にも改行があるものと仮定すれば、次の方法が一番簡単でしょう。

open("file").read.count("\n")

28 7.28 配列からハッシュへの変換はどうすればできますか

array という配列があった場合、

h = Hash[*array]

とすれば、array の奇数番目の値をキー、偶数番目の値を値とした h というハッシュが作られます。このとき array の要素は偶数個 でなければいけません。

array = [1,2,3,4]
h = Hash[*array]
p h

=> {1=>2, 3=>4}

なお、arrayの前の「*」は、メソッド呼び出しのところで紹介されている、 引数の展開用の記号です。

29 7.29 文字列からArrayを作るのは %w(...) でできますが、同じように文字列からHashを作るにはどうすればよいですか

Arrayのように直接Hashを作るリテラルはありません。 そのかわり、

p h = Hash[*%w(1 foo 2 bar)]

=> {"1"=>"foo", "2"=>"bar"}

などと、いったんArrayを作るようにすれば、そこから簡単にHashを作れます。 (ただし、この場合ハッシュのキーと値は文字列に限定されます)

Title: 8. 拡張ライブラリ

1 8.1 Rubyを対話型で使いたいのですが

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 は別パッケージになって いる可能性があります。各ディストリビューションの状況を調べてみてくださ い。

2 8.2 デバッガはありますか

あります。Rubyを次のように起動してください。詳細は debug.rb を参 照してください。

ruby -r debug your_script

3 8.3 C言語で書かれたライブラリをRubyで使いたいのですが

RubyはCで書かれています。さらに、Cで書かれたライブラリを Rubyで利用できるようにするための部品もととのっていますので、 Cで書かれたライブラリとRubyとの間のインターフェースを書くことに より、Rubyから使えるライブラリができます。

まず、Rubyのソースを展開したディレクトリにある、 ruby-src:ruby/README.EXT.ja を読んでみましょう。この文書はRuby そのものについて知るためにもよいドキュメントになっています。

次にext/ディレクトリの下にあるサブディレクトリを覗いてみると 実例が出てきます。ftpサイトのcontribにあるものも参考になる ことでしょう。

4 8.4 Tcl/Tkのインターフェースはありますか

標準で添付されている拡張ライブラリに、Tcl/Tkのインターフェースが あります。一つは、ext/tcltk/以下のrequire "tcltk"で ロードされるインタ ーフェースで、TclスクリプトをRubyスクリプト中に埋め込むよ うな記述になります。

もう一つはext/tk/以下のrequire "tk"でロードされるインターフェースで、 こちらはよりRubyらしい記述でTkのGUIを実現することができます。

5 8.5 Tkが動かないのですが

お使いのTkのバージョンが古い可能性があります。新しいものと交換してみて ください。

6 8.6 gtk+、xformsのインターフェースはありますか

RAA:Ruby/GTK, RAA:Ruby/Forms を参照してください。

7 8.7 日付の計算をしたいのですが

Timeオブジェクトは、1970年1月1日から2038年1月19日までしか表せま せん。標準添付ライブラリ date.rb を使ってください。 ruby-src:ruby/sample/cal.rb も参照してください。

Title: 9. ドキュメントされていない機能

基本的にドキュメントされてない機能はありません。 書いてないことがあればそれは記述洩れです。

Title: 10. 日本語の取り扱い

1 10.1 漢字を含んだスクリプトが文字化けを出力したり、正しく実行できない場合があります

ruby 1.6以降、デフォルトで漢字コードを特別に解釈しなくなりました。 漢字を扱いたい場合は ruby -Ke などとして$KCODE を適切に設定しておく必要があります。

Windows 上で SJIS を使用している場合、ruby -Ksを、 UNIX 系 OS 上で EUC を使用している場合、ruby -Keを 指定する必要があります。

なお、スクリプトの先頭行に

#! ruby -Ks

などと書けばオプションの指定をスクリプトに埋め込むことができます。 これがもっとも無難でポピュラーな方法です。

2 10.2 オプション-K$KCODE の違いはなんですか?

効果が及ぶタイミングが違います。

例えばSJISコードのファイルで以下のスクリプトがあった場合

$KCODE = 'SJIS'
s = "表"

$KCODE に値を設定する段階ではスクリプトは解析された後です。文字列リテ ラルは($KCODE のデフォルトが "NONE" であるため)マルチバイトとして解釈 されていません。

オプション -K による漢字コードの指定ならばスクリプトを読む前に漢字コー ドが指定されるので、スクリプト解析の段階で漢字コードを認識します。

ちなみに漢字コードを含んだスクリプトで問題が発生する理由は「表」などの 文字がシフトJISコードでバックスラッシュ("\")と同じコードを含むからです。

3 10.3 日本語の識別子は使えますか

-K オプションを正しく指定すれば、漢字で始まる変数名は英小文字に相当するもの として使えます。ポータビリティが低いのでおすすめできません。

Hash を使えば似たようなことができます、こちらの方がより安全と言えます。

var = {'変数' => '値'}
var['変数'] = 1

4 10.4 日本語を含む文字列から1文字ずつ文字列を取り出すにはどうしますか

$KCODE を設定した上で split(//) や scan(/./) を使います。

5 10.5 tr("あ","a")がうまく動きません

組込みの String#tr は、バイトごとに変換します。 require "jcode" とすると、日本語を文字ごとに扱えます。 (jcode.rb を参照)

6 10.6 ひらがなをソートするにはどうしますか

以下は、ひらがなの濁音、半濁音、拗音、撥音の文字を無視してソートを行う例です。 *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)}

と書けます。

7 10.7 SJISの機種依存コード84BF から 889Fまでを空白に置き換えたいのですが

正規表現で[あ-ん]というような範囲表現が使えますが、機種依存文字を直接 書くことはプログラムの可読性を損ないます。かといって

gsub(/[\x84\xbf-\x88\x9f]/s, ' ')

と書くことはできません。このような場合は以下のトリックを使うことで

gsub(Regexp.compile("[\x84\xbf-\x88\x9f]", nil, 's'), ' ')
または
gsub(/#{"[\x84\xbf-\x88\x9f]"}/s, ' ')

2バイトコードの範囲をうまく数値で表現して、空白に置き換えることができ ます。(余談ですが、このようなときには空白でなくゲタ("〓")に置き換えま すけどね)

8 10.8 いわゆる全角文字と半角文字の変換を行うにはどうするのがよいですか?

標準ならば nkf.so ライブラリを使う方法と jcode.rb ライブラ リを使って変換を行う方法があります。あと RAA:Kakasi ライブラリな どでも可能です。

ruby-list:10505, ruby-list:25839, ruby-list:31238, ruby-list:31240, ruby-list:31508 などなど*142

9 10.9 いわゆる半角カナの扱い

Ruby はいわゆる半角カナを完全にはサポートしてません。

# 以下の例で "ア" は半角文字としてみてください
ruby -Ks -e 'p "あア"'
=> "あ\261"

開発中の M17N版 ruby ではこのようなことにはならないそうです。

10 10.10 日本語を含む文字列から n バイトを切り出したいのですが

多バイト文字の切り出しでは、文字の泣き別れが問題になるのです が、これに対しては $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 バイト文字には対応してません。

11 10.11 日本語テキストを n 桁で折り返したいのですが

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 に比べれば格段に遅いです。

Title: 11 Ruby の処理系について

1 11.1 Ruby スクリプトをコンパイルすることはできますか?

RAA に、試験的に作成された x86 向けの Just In Time コンパイラが あります。ただしバージョン 1.5 用ですし、実用にもならないでしょう。

コンパイルしたい理由がソースコードの隠蔽なら、近いうちに進展が あるかもしれません。速度についてはかなり意欲的に改良が進んでいます。

2 11.2 Java VM 上で動く Ruby ってありますか?

JRuby( <URL:http://jruby.sf.net/> ) という処理系が現在開発されています。

3 11.3 オリジナル以外の Ruby の実装はありますか?

現在のところありません。最初の一人を狙うのもいいですね。*143

4 11.4 Ruby 用の indent みたいなものはありますか?

これもありません。基本的に Ruby スクリプトの解析は非常に面倒です。 しかしユーザが増えればかなり実現可能性は高いでしょう。

5 11.5 ネイティブスレッドを使った Ruby はない?

ネイティブスレッドは、現在の GC (ガベージコレクション……自動メモリ回収) の実装と非常に相性が悪いため実現していません。またインタプリタおよび 基本ライブラリには C レベルでスレッドセーフでない部分がありますので その部分を洗いだして修正する必要もあります。

6 11.6 GC が遅い! どうにかならないの?

GC は現在の Ruby インタプリタの最大のボトルネックになりつつあるようで、 特に大規模なプログラムにおいては顕著です。これを解決するのが次の安定版 に向けての核となるでしょう。たとえば世代別 GC のような新アルゴリズムが 試験実装されたりしています。それまでの対処としては 1. 黙って耐える 2. 生成されるオブジェクトを減らす 3. 大量にオブジェクトを生成するのが わかっているならそのあいだだけ GC を止めておく……などが考えられます。

ただし通常のプログラムではそうそう GC の影響を受けることはありません。 安易に GC のせいにせず、どこが遅いのかちゃんと計測してみましょう。

7 11.7 Mac では Ruby は動かないの?

MacOS X ならば .pkg フォーマットのRubyがRAAで公開されています。 MacOS 9 以前でも動いていたことは あるそうですが現在のバージョンは動いていません。消えゆく OS に積極的に 対応しようとする人もあまりいないのでは……。 ++

Title: Rubyの落とし穴

1 文法

2 組込みクラス

3 ライブラリ

Title: ()で解決するもの

Title: 空白文字による違い

Title: \の影響

注:ブラウザや環境によって\が¥に見えます。

Title: スコープ、制御構造

Title: 型変換

Title: 破壊的メソッド

Title: イテレータ

Title: 引数

Title: 真偽値

1 trueとfalse

Title: 暗黙の $_

以下の式の結果は、/foobar/ ではなく nil になります。*147 *148 *149 *150

nil || /foobar/    #=> nil

これは、「条件式に単体の正規表現リテラルだけを書くと$_との正規表現マッ チを行う」というルールがあるためです。つまり、上記の式は

nil || /foobar/ =~ $_

のように解釈されています。

これを避けるには現状

nil || Regexp.new("foobar")

のように単体の正規表現リテラルを書かないようにするしか方法がありません。

論理演算子式の項に現れた正規表現リテラルの特殊解釈はなくす方向で検討さ れていますruby-list:30836

Title: trap::Array

Title: trap::Dir

Title: trap::File

Title: Hash

Title: IO

Title: Process

Title: Regexp

Title: String

Title: Thread

Title: Time

1 タイムゾーン

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

これらの問題の影響を受けるメソッドには以下のものがあります。

Title: timeout

Title: Socket

Title: Ruby/Tk FAQ

  1. 一般的な質問
  2. 動作環境
  3. 参考資料
  4. インストール
  5. はじめの一歩
  6. Widgetに関する質問
  7. Canvasに関する質問
  8. 表記に関する質問
  9. Ruby/TkとTcl/Tk, Perl/Tk, Python Tkinterなどとの違い
  10. Rubyから使えるその他のツールキット
  11. Ruby/Tkで書かれた主なアプリケーション

Title: 1. 一般的な質問

1 1.1 Ruby/Tk とは何ですか?

Ruby/Tk は、強力なオブジェクト指向スクリプト言語である Ruby と、 手軽に GUI プログラムを作成できる Tcl/Tk を組み合わせることで、 楽しく、プログラムをすることを目指したものです。

2 1.2 どんな OS で動作するのでしょうか?

3 1.3 Tcl/Tk でなく Ruby/Tk を使うと何がうれしいのですか?

同じスクリプト言語といっても Ruby は Tcl よりかなり強力です。 Tk は使いたいけど、Tcl は使いたくない人にとって Ruby/Tk を使う意味は 大いにあるでしょう。

4 1.4 Ruby/Tk と tcltk, tcltklib ライブラリの違いは何ですか?

5 1.5 Ruby/Gtk とは何が違うのですか?

Ruby/Tk には以下のような利点があります。

Ruby/Tk には以下のような欠点があります。

6 1.6 Ruby/Qt とは何が違うのですか?

Ruby/Tk には以下のような利点があります。

Ruby/Tk には以下のような欠点があります。

Title: 動作環境

1 Windows では動作しますか?

2 Mac OS では動作しますか?

Title: Ruby/Tk 参考資料

1 Ruby/Tk のチュートリアルはありますか?

2 Ruby/Tk のマニュアルはありますか?

3 Widget Demo の Ruby/Tk 版はありますか?

4 インターネット上の Ruby/Tk のリソース

Ruby関連メーリングリスト トピックス

Tkの項目が参考になります。

rubyによるVerilog用波形ビューワ

菊谷さんのページ

ruby で楽しいプログラミング

近藤さんのページ

Ruby工房

五十嵐さんのページ

Rubyの指環

江田さんのページ

Ruby Ruby Ruby

高橋さんのページ

Ruby > (Smalltalk + Perl) / 2

greenteaさんのページ。『入門 tcl/tk』のサンプルコードを Ruby/Tk のコードに変換しています。

5 Ruby のマニュアル

6 Tcl/Tk のマニュアル

Tcl/Tk の資料が利用できます。Tcl/Tk の文献は…

7 Perl/Tk のマニュアル

Perl/Tk の資料が利用できます。Perl/Tk の文献は…

8 Python Tkinter のマニュアル

Title: Ruby/Tk インストール

1 Ruby/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

してください。

1.1 Cygwin 版の場合

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    

2 Ruby/Tk のバイナリはありますか?

2.1 UNIX 系 OS の場合

Ruby インストールガイドを参考にして下さい。

2.2 Windows の場合

例えば、以下の組合せの場合

以下のようにすれば動作します

Cygwin 環境の ruby からのみ Tcl を使用する場合(必要なライブラリ、DLLをコピー)

普通に Tcl/Tk も使いたい場合

あるいは、

Title: はじめの一歩

他の 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

Title: Widgetに関する質問

1 ruby-1.6.x で font "Helvetica 18" を指定したら怒られてしまいました。なぜですか?

2 TkCanvas#type(tag) を実行したら ... なぜですか?

Title: Canvasに関する質問

Title: 表記に関する質問

1 => とか . とかの意味は?

2 Tk*.new {} などの {} はなんですか?

3 クラス名の規則はありますか?

4 メソッド名の規則はありますか?

method= はほとんどない

setValue 形式もない?

5 proc をつけなくても良い場所はどういう場合ですか?

Title: Ruby/Tk と Tcl/Tk, Perl/Tk, Python Tkinterなどとの違い

1 Ruby/Tk と Tcl/Tk との違いはどこですか?

依存関係のある widget の生成方法

ScrollBar と ListBox, Text, Canvas

TkVariable
スコープ
評価タイミング

2 Ruby/Tk と Tcl/Tk との違い一覧は?

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"

3 Ruby/Tk と Perl/Tk との違いはどこですか?

4 Ruby/Tk と Perl/Tk との違い一覧は?

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"

5 Ruby/Tk と Python Tkinter との違いはどこですか?

6 Ruby/Tk と Python Tkinter との違い一覧は?

Title: Rubyから使えるその他のツールキット

EZWGL を扱うモジュールが 前田さんによって作られています。 現在ネットワーク上では手に入らないかも?

FLTK を扱うモジュールが立石さんによって作られています。 立石さんWebから手にいれることができます。

gtk を扱うモジュールが まつもと さんによって作られています。 現在は、五十嵐さんがメンテしています。Ruby/Gtkにあります。

XForms を扱うモジュールが立石さんによって作られています。 立石さんWebから手にいれることができます。

Athena widget や Motif を扱うモジュールが 前田さんによって作られています。 contrib/ にあります。

XView を扱うモジュールが 立石さんによって作られています。 立石さんWebから手にいれることができます。

Xlib を扱うモジュールが もりきゅうさんによって作られています。 Moriq Rubyから手にいれることができます。

Title: Ruby/Tk で書かれた主なアプリケーション

1 Ruby/Tk で書かれたアプリケーションはありますか?

Title: Rubyに関する書籍

現在発売されているRubyについての本は以下の通りです。(発売順)

Title: 配布条件

本ドキュメントはフリーです。以下に示す条件で本ドキュメントを 再配布できます。

なお,本ドキュメントのオリジナル(2001年12月25日現在 <URL:http://www.ruby-lang.org/ja/doc.html> にあります)に対して加筆、 修正を行った場合、下記条件で再配布されることに同意したものと 見なされます。

  1. 複製は制限なく自由です。フォーマットの変更も文意が変わ らない限り制限はありません。 本ドキュメントの一部を引用するのも制限なく自由です。
  2. 以下の条件のいずれかを満たす時に本ドキュメントの内容を 変更したものを再配布できます。

    1. 変更した本ドキュメントを自分の所属する組織内部だけで 使う。
    2. 変更点を明示したものを、配付物に含める。
    3. 原文の入手法を明示する。
    4. その他の変更条件に関して rubyist ML (rubyist@freeml.com) で合意を取る。

*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 が動作しなければならない。それ以外では succs 回実行する。つまり 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拡張ライブラリによる別実装として、 RAARAA: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