Ruby Syntax

前 - 次 - 目次

# Rubyの文法

- 字句構造
  - 識別子
  - コメント
  - 埋め込みドキュメント
  - 予約語
- プログラム
- 式
  - 文字列リテラル
  - コマンド出力
  - 正規表現
  - 文字列中の式展開
  - ヒアドキュメント (行指向文字列リテラル)
  - 数値リテラル
  - 変数と定数
  - グローバル変数
  - インスタンス変数
  - ローカル変数
  - 疑似変数
  - 定数
  - 配列式
  - ハッシュ式
  - メソッド呼出し
  - `super`
  - 代入
  - 演算子式
  - 制御構造
    - `if`
    - `if`修飾子
    - `unless`
    - `unless`修飾子
    - `case`
    - `and`
    - `or`
    - `not`
    - 範囲式
    - `while`
    - `while`修飾子
    - `until`
    - `until`修飾子
    - イテレータ
    - `for`
    - `yield`
    - `raise`
    - `begin`
    - `retry`
    - `return`
    - `break`
    - `next`
    - `redo`
    - BEGIN
    - END
  - クラス定義
  - 特異クラス定義
  - モジュール定義
  - メソッド定義
  - 特異メソッド定義
  - `alias`
  - `undef`
  - `defined?`

## 字句構造

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

### 識別子

例:

    	foobar
    	ruby_is_simple

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

### コメント

例:

    	# this is a comment line

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

### 埋め込みドキュメント

例:

    	=begin
    	the everything between a line beginning with `=begin' and
    	that with `=end' will be skipped by the interpreter.
    	=end

Rubyのソースコードにドキュメントを埋め込む事ができます．文が 始まる部分の行頭に`=begin`があると，そこからはじ まって，`=end`で始まる行までは埋め込みドキュメン トとして読み飛ばされます．

### 予約語

予約語は以下にあげるものです:

    	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

予約語はクラス名，変数名などに用いることはできません．しかし， ``$'`, ``@'`が先頭についたものは予約語 と見なされません．明示的にメソッド名であると分かる場合にはメ ソッド名として用いることができます．

## プログラム

例:

    	print "hello world!\n"

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

## 式

例:

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

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

### 文字列リテラル

例:

    	"this is a string expression\n"
    	"concat#{foobar}"
    	'concat#{foobar}'
    	%q!I said, "You said, 'She said it.'"!
    	%!I said, "You said, 'She said it.'"!
    	%Q('This is it.'\n)

文字列はダブルクォートまたはシングルクォートで囲まれています． ダブルクォートで囲まれた文字列ではバックスラッシュによるエス ケープと式展開(後述)が有効になります．シングルクォートで囲ま れた文字列では，`\\`(バックスラッシュそのもの)と `\'`(シングルクォート)を除いて文字列の中身の解釈 は行われません．

`%`で始まる形式の文字列を用いることでバックスラッ シュの数を減らすことができます． `%q!STRING!` はシングルクォート文字列， `%Q!STRING!` (または `%!STRING!`)はダブルクォート文字列と同じ展開を行います． `!`の部分には改行を含めた任意の非英数字を 使うことができます．始まりの区切り文字が括弧 (`(',`[',`{',`<')である時には，終りの区切り文字は対応する括弧になります．

#### バックスラッシュ記法

> `\t`
>   タブ(0x09)
> `\n`
>   改行(0x0a)
> `\r`
>   キャリッジリターン(0x0d)
> `\f`
>   改ページ(0x0c)
> `\b`
>   バックスペース(0x08)
> `\a`
>   ベル(0x07)
> `\e`
>   エスケープ(0x1b)
> `\s`
>   空白(0x20)
> `\nnn`
>   8進数表記(nは0-7)
> `\xnn`
>   16進数表記(nは0-9,a-f)
> `\cx`
> `\C-x`
>   コントロール文字(xはASCII文字)
> `\M-x`
>   メタ x (c | 0x80)
> `\M-\C-x`
>   メタ コントロール x
> `\x`
>   文字xそのもの

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

### コマンド出力

例:

    	`date`
    	%x{ date }

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

`%x/STRING/`形式はコマンド出力式の別の形式です．

### 正規表現

例:

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

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

`i`

  正規表現はマッチ時に大文字小文字の区別を行わない

`o`

  一番最初に正規表現の評価が行われた時に 一度だけ式展開を行う

`x`

  正規表現中の空白を無視する．コメントも付けられる

`p`

  POSIXモード．改行も通常文字と見なす

Rubyは日本語化されているので，上記のオプションの他に `n`, `e`,`s`のオプションが指定できます． これらは`$KCODE`の値にかかわらず， 正規表現がマッチに使用する文字コードを指定するものです．

`%r/STRING/`形式は正規表現式の別の形式です．

`^`
  行頭
`$`
  行末
`.`
  改行を除く任意の1文字
`\w`
  英数字．[0-9A-Za-z_]と同じ
  日本語のいわゆる全角文字も含む
`\W`
  非英数字
`\s`
  空白文字．[ \t\n\r\f]と同じ
`\S`
  非空白文字
`\d`
  数字．[0-9] と同じ
`\D`
  非数字
`\A`
  文字列先頭
`\Z`
  文字列末尾(改行があれば改行の直前)
`\z`
  文字列末尾
`\b`
  語境界(文字クラス外)
`\B`
  非語境界
`\b`
  バックスペース(0x08)([]内)
`[ ]`
  文字クラス指定
`*`
  直前の表現の0回以上の繰り返し
`*?`
  直前の表現の0回以上の繰り返し(最短一致)
`+`
  直前の表現の1回以上の繰り返し
`+?`
  直前の表現の1回以上の繰り返し(最短一致)
`{m,n}`
  直前の表現のm回からn回の繰り返し
`{m,n}?`
  直前の表現のm回からn回の繰り返し(最短一致)
`?`
  0または1回の直前の表現
`|`
  選択
`( )`
  正規表現をグループ化
`(?# )`
  コメント
`(?: )`
  後方参照を伴わないグループ化
`(?= )`
  パターンによる位置指定(幅を持たない)
`(?! )`
  パターンの否定による位置指定(幅を持たない)
`(?ixp-ixp)`
  正規表現中でのiオプション，xオプション，pオプションのon/off．括弧の範囲内で設定
`(?ixp-ixp: )`
  括弧内のiオプション，xオプション，pオプションのon/off．

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

### 文字列中の式展開

例:

    	"my name is #{$ruby}"

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

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

シェルのような行指向の文字列リテラルの表現もあります．このよ うな文字列リテラルを「ヒアドキュメント」と呼びます． `<<`に続いて，引用終了記号になる文字列また は識別子を指定します．文字列を指定した場合は，その文字列の種 別(`""，''，```)が文字列全体の性質を決定します． `<<`の後ろには空白を置くことはできません．

識別子または文字列の前に`-`が置かれた場合，区切り 文字列の前の空白文字(タブとスペース)が取り除かれます．これに よって区切り文字をインデントに合わせることが出来ます．

    	  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

### 数値リテラル

`123`
  整数
`-123`
  符号つき整数
`1_234`
  整数(10進整数は`_`を含むことができる)
`123.45`
  浮動小数点数
`1.2e-3`
  浮動小数点数
`0xffff`
  16進整数
`0b1011`
  2進整数
`0377`
  8進整数
`?a`
  文字`a`のコード(97)
`?\C-a`
  コントロール a のコード(1)
`?\M-a`
  メタ a のコード(225)
`?\M-\C-a`
  メタ-コントロール a のコード(129)
`:symbol`
  識別子/変数名/演算子と一対一対応する整数．

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

### 変数と定数

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

### グローバル変数

例:

    	$foobar
    	$/

``$`'で始まる変数はグローバル変数で，プログラムの どこからでも参照できます．グローバル変数には宣言は必要ありま せん．初期化されていないグローバル変数を参照した時の値は `nil`です．

### インスタンス変数

例:

    	@foobar

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

### ローカル変数

例:

    	foobar

小文字または``_`'で始まる識別子はローカル変数また はメソッド呼出しです．ローカル変数スコープ(クラス，モジュー ル，メソッド定義の本体)における小文字で始まる識別子への最初 の代入はそのスコープに属するローカル変数の宣言になります．宣 言されていない識別子の参照は引数の無いメソッド呼び出しとみな されます．

ローカル変数のスコープは，その変数が宣言されたブロック，メソッ ド定義，またはクラス/モジュール定義の終りまでです．寿命もそ のブロックの終りまで(トップレベルのローカル変数はプログラム の終了まで)ですが，例外としてブロックが手続きオブジェクト化 された場合は，そのオブジェクトが消滅するまで存在します．同じ スコープを参照する手続きオブジェクト間ではローカル変数は共有 されます．

### 疑似変数

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

> `self`
>   現在のメソッドの実行主体
> `nil`
>   NilClassクラスの唯一のインスタンス
> `true`
>   TrueClassクラスの唯一のインスタンス．真の代表値
> `false`
>   FalseClassクラスの唯一のインスタンス．nilとfalseは偽を表します．
> `__FILE__`
>   現在のソースファイル名
> `__LINE__`
>   現在のソースファイル中の行番号

疑似変数の値を変更することはできません．変数への代入は例外を 発生させます．

### 定数

例:

    	FOOBAR

大文字([A-Z])で始まる識別子は定数です．定数の定義(と初期化) は代入によって行われますが，メソッドの中では定義できません． 一度定義された定数に再び代入を行おうとすると例外が発生します． 定義されていない定数のアクセスは例外を発生させます．

定数はその定数が定義されたクラス/モジュール定義の中(メソッド 本体やネストしたクラス/モジュール定義中を含みます)，クラスを 継承しているクラス，モジュールをインクルードしているクラスま たはモジュールから参照することができます．クラス定義の外で定 義された定数は`Object` に所属することになります．

クラス定義は自動的に定数を定義するので，クラス名は定数です．

あるクラスまたはモジュールで定義された定数を外部から参照する ためには``::`'演算子を用います．

`Object`クラスで定義されている定数を参照するため には左辺無しの``::`'演算子を用います．

例:

    	Foo::Bar
    	::Bar

ただし，``::`'演算子を用いた代入はできません．

### 配列式

例:

    	[1, 2, 3]

文法:

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

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

`%w`という形式で文字列の配列を簡単に表現できます． これはシングルクォートで囲んだ文字列を空白文字で分割したのと 同じです．たとえば，

    	%w(foo bar baz)

は`["foo", "bar", "baz"]`と等価です．

### ハッシュ式

例:

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

文法:

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

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

ハッシュの要素が1つ以上ある場合，曖昧でなければ `{`, `}`は省略できます．

### メソッド呼出し

例:

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

文法:

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

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

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

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

    	foo(*[1,2,3])

は

    	foo(1,2,3)

と同じです．

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

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

### `super`

例:

    	super
    	super(1,2,3)

文法:

    	super
    	super(式,...)

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

### 代入

例:

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

文法:

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

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

- 変数

      	変数 `=' 式

  左辺値が変数の場合，式を評価した値が変数に代入される．

- 配列参照

      	式1`[' 式2...`]' `=' 式n

  この形式の代入は，式1を評価して得られるオブジェクトに対して の式2から式nまでを引数とする `[]=` というメソッド 呼出しとして評価されます．

- 属性参照

      	式1 `.' 識別子 `=' 式2

  上記の形式の属性参照ヘの代入は，式1を評価して得られるオブジェ クトに対して，`識別子=`というメソッドを，式2を引 数として呼び出します．

#### 自己代入

例:

    	foo += 12

文法:

    	式1 op= 式2     # 式1は代入可能でなければならない．

この形式の代入は `式1 = 式1 op 式2` と同様に評価 されます．ただし，式1は1度しか評価されません．op は以下のい ずれかの演算子で無ければなりません．

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

演算子と`=`の間にスペースを空けてはいけません．

#### 多重代入

例:

    	foo, bar, baz = 1, 2, 3
    	foo, = list()
    	foo, *rest = list2()

文法:

    	式 `,' [式 `,'...] [`*' 式] = 式 [, 式...][`*' [式]]
    	`*' 式 = 式 [, 式...][`*' expr]

多重代入は複数の式または配列から同時に代入を行います．左辺の 各式はそれぞれ代入可能でなければなりません．右辺の式が一つし か与えられなかった場合，式を評価した値は配列に変換されて，各 要素が左辺のそれぞれの式に代入されます．左辺の要素の数よりも 配列の要素の数の方が多い場合には，余った要素は無視されます． 配列の要素が足りない場合には対応する要素の無い左辺には `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,*bar = 1, 2, 3	# foo = 1; bar = [2, 3]

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

### 演算子式

例:

    	1+2*3/4

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

    	high   ::
    	       []
    	       **
    	       -(unary)  +(unary)  !  ~
    	       *  /  %
    	       +  -
    	       <<  >>
    	       &
    	       |  ^
    	       >  >=  <  <=
    	       <=> ==  === !=  =~  !~
    	       &&
    	       ||
    	       .. ...
    	       =(+=, -=...)
    	       not
    	low    and or

ほとんどの演算子は特別な形式のメソッド呼び出しですが，一部の ものは言語に組み込みで，再定義できません．再定義できない演算 子形式の制御構造は以下の通りです．

    	=, .., ..., !, not, &&, and, ||, or, ::

演算子の組合せである自己代入演算子と`!=`, `!~` も再定義できません．

### 制御構造

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

#### `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

`if`式は条件実行に用いられます．条件式を評価した 値が `false` または `nil` の時，偽であ ると見なされ，それら以外の全ての値は真であると見なされます． Rubyではifを繋げるのに，`elsif`を用い，`else if`(Cのように)でも，`elif`(shのように)でも 無いことに注意してください．

`if` の条件式の部分が文字列または正規表現のリテラ ルである時には，

    	$_ =~ リテラル

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

#### `if`修飾子

例:

    	print "debug\n" if $debug

文法:

    	式 if 式

右辺の条件が成立する時に，左辺の式を評価します．

#### `unless`

例:

    	unless $baby
    	  feed_meat
    	else
    	  feed_milk
    	end

文法:

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

`unless`は条件実行を行いますが，条件が`if` と反対で，条件が偽の時に実行を行います．

#### `unless`修飾子

例:

    	print "stop\n" unless valid($passwd)

文法:

    	式 unless 式

右辺の条件が成立しない時に，左辺の式を評価します．

#### `case`

例:

    	case $age
    	when 0 .. 2
    	  "baby"
    	when 3 .. 6
    	  "little child"
    	when 7 .. 12
    	  "child"
    	when 12 .. 18
      	  # 12はすでに"child"にマッチしている
    	  "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

#### `and`

例:

    	test && set
    	test and set

文法:

    	式 `&&' 式
    	式 `and' 式

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

#### `or`

例:

    	demo || die
    	demo or die

文法:

    	式 `||' 式
    	式 or 式

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

#### `not`

例:

    	! me
    	not me
    	i != you

文法:

    	`!' 式
    	not 式

式の値が真である時偽を，偽である時真を返します．

    	式 `!=' 式

`!(式 == 式)`と同じ．

    	式 `!~' 式

`!(式 =~ 式)`と同じ．

#### 範囲式

例:

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

文法:

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

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

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

#### `while`

例:

    	while sunshine
    	  work()
    	end

文法:

    	while 式 [do]
    	  ...
    	end

式を評価した値が真の間，本体を繰り返して実行します．

#### `while`修飾子

例:

    	sleep while idle

文法:

    	式 while 式

右辺の式を評価した値が真の間，左辺を繰り返して実行します．左 辺の式が `begin` である場合には，それを最低一度は 評価します．

#### `until`

例:

    	until sunrise
    	  sleep
    	end

文法:

    	until 式 [do]
    	  ...
    	end

式を評価した値が真になるまで，本体を繰り返して実行します．

#### `until`修飾子

例:

    	work until tired

文法:

    	式 until 式

右辺の式を評価した値が真になるまで，左辺を繰り返して実行しま す．左辺の式が `begin` である場合には，左辺を最低 一度は評価します．

#### イテレータ

例:

    	[1,2,3].each do |i| print i*2, "\n" end
    	[1,2,3].each{|i| print i*2, "\n"}

文法:

    	method_call do [`|' expr...`|'] expr...end
    	method_call `{' [`|' 式...`|'] 式...`}'

イテレータとは制御構造(特にループ)の抽象化のために用いられる メソッドの一種です．`do ... end`または`{ ... }` で囲まれたコードの断片(ブロックと呼ばれる)を 後ろに付けてメソッドを呼び出すと，そのメソッドの内部からブロッ クを評価できます(おそらくは複数回)．このようなブロックを呼び 出すメソッドをイテレータと呼びます．イテレータからのブロック の呼び出しは`yield`式を用い ます．yieldに渡された値は `|` と `|` の間にはさまれた変数に代入されます．

`{ ... }`の方が`do ... end`ブロックよりも結合強度が 強いです．例えば:

    	foobar a, b do .. end	# foobar がイテレータとして呼び出されます
    	foobar a, b { .. }	# b がイテレータとして呼び出されます

ブロックの中で初めて代入された(宣言された)ローカル変数はその ブロックの中でだけ有効です．例えば

    	foobar {
    	  i = 20		# ローカル変数 `i' が宣言された
    	  ...
    	}
    	print defined? i	# `i' はここでは未定義
    	foobar a, b { .. }	# ブロック内部でだけ有効

#### `for`

例:

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

文法:

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

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

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

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

#### `yield`

例:

    	yield data

文法:

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

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

#### `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`で得られる スタック情報で，例外が発生した場所を示します．

発生した例外は変数 $! に格納されます．また例外が 発生したソースコード上の位置は変数 $@ に格納され ます．

`raise` は Ruby の予約語ではなく， `Kernel` モジュールで定義されている関数的メソッドです． `raise` には `fail` という別名も定義さ れています．

#### `begin`

例:

    	begin
    	  do_something
    	rescue
    	  recover
    	ensure
    	  must_to_do
    	end

文法:

    	begin
    	  式..
    	[rescue [error_type,..]
    	  式..]..
    	[else
    	  式..]
    	[ensure
    	  式..]
    	end

`begin`は本体を評価し，最後に評価された式の値を返 します．

本体の実行中に例外が発生した場合，`rescue` 節が与 えられていた場合例外を捕捉できます．発生した例外と一致する `rescue`節が存在する時には`rescue`節の 本体が実行されます．例外の一致判定は例外のクラスが `rescue`節で指定したクラスと同じかまたはサブクラ スであるかどうか `kind_of?` を用いて判定されます．クラスが省略された時は `StandardError`のサブクラスである全ての例外を捕捉します． Rubyの組み込み例外は (`SystemExit`や`Interrupt`のような 脱出を目的としたものを除いて) `StandardError`のサブクラスです．

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

`begin`には省略可能な`else`節を指定す ることができて，本体の実行によって例外が発生しなかった時に実 行されます．

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

#### `retry`

例:

    	retry

文法:

    	retry

`begin`式の`rescue`節で使われた場合， `begin`式を始めからもう一度実行します．

    	begin
    	  do_something # exception raised
    	rescue
    	  # handles error
    	  retry  # restart from beginning
    	end

イテレータ，ブロックまたはfor文の中で使われた場合には，その イテレータを起動しなおします．イテレータの引数も再評価されま す．

    	for i in 1..5
    	  retry if some_condition # i == 1 からやり直し
    	end

    	# ユーザ定義の "untilループ"
    	def UNTIL(cond)
    	  yield
    	  retry if not cond
    	end

`rescue`節やイテレータ以外でretryが用いられた場合 にはエラーになります．

#### `return`

例:

    	return
    	return 12
    	return 1,2,3

文法:

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

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

#### `break`

例:

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

文法:

    	break

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

- while
- until
- for
- イテレータ

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

#### `next`

例:

    	next

文法:

    	next

`next`はもっとも内側のループの次の繰り返しにジャ ンプします．

#### `redo`

例:

    	redo

文法:

    	redo

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

#### BEGIN

例:

    	BEGIN {
    	  ...
    	}

文法:

    	BEGIN '{' 文.. '}'

初期化ルーチンを登録します．`BEGIN`直後の `{ }`内部(`BEGIN`ブロック)で指定した文 は当該ファイルのどの文が実行されるより前に実行されます．複数 の`BEGIN`が指定された場合には指定された順に実行さ れます． `BEGIN`ブロックは独立したローカル変数のスコープを 導入するため，ローカル変数を外部と共有する事はありません．情 報の伝達にはグローバル変数を使う必要があります．

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

#### END

例:

    	END {
    	  ...
    	}

文法:

    	END '{' 文.. '}'

「後始末」ルーチンを登録します．`END`ブロックで指 定した文はインタプリタが終了する時に実行されます． `END`ブロックは，`BEGIN`ブロックとは異 なり，イテレータと同様のスコープを持ち，周囲とスコープを共有 します．`END`ブロックは一番最初に評価された時に1 回だけ登録を行います．複数登録する必要がある場合には at_exitを使ってください．

`END`もトップレベルにしか置く事はできません． それと，`END`で登録された実行文を取り除く事はで きません．

### クラス定義

例:

    	class Foo < Super
    	  def test
    	     :
    	  end
    	     :
    	end

文法:

    	class 識別子 [`<' superclass ]
    	  式..
    	end

### 特異クラス定義

例:

    	class << obj
    	  def test
    	     :
    	  end
    	     :
    	end

文法:

    	class `<<' expr
    	  式..
    	end

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

### モジュール定義

例:

    	module Foo
    	  def test
    	     :
    	  end
    	     :
    	end

文法:

    	module 識別子
    	  式..
    	end

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

### メソッド定義

例:

    	def fact(n)
    	  if n == 1 then
    	     1
    	  else
    	    n * fact(n-1)
    	  end
    	end

文法:

    	def メソッド名 [`(' [arg ['=' default]]...[`,' `*' arg ]`)']
    	  式..
    	end

メソッドを定義します．メソッド名としては通常の識別子の他に， 再定義可能な演算子(例: ==, +, -など)も指定できます．メソッド は定義する前に呼び出すことはできません．例えば

    	foo
    	def foo
    	  print "foo\n"
    	end

は未定義メソッドの呼び出しで例外が発生します．

仮引数にデフォルト式が与えられた場合，メソッド呼び出し時に実 引数が与えられなかった場合にはデフォルト式を評価した結果で初 期化されます(デフォルト式の評価は呼び出し時に行われます)．最 後の仮引数の直前に`*`がある場合には残りの実引数は みな配列としてこの引数に格納されます．

また最後の仮引数の直前に`&`があるとこのメソッ ドに与えられているブロックが手続きオブジェクトとしてこの引数 に格納されます．`*`と`&`が同時に指 定される場合には`&`が後ろに来ます．

メソッド定義はネストできません．

メソッドの戻り値は`return`で 与えた値か，または本体の最後で評価した式の値です．

メソッドには呼び出し制限を加えることができ，制限を加えられた メソッドは，関数形式でしか呼び出せません(privateメソッド)．

メソッドを定義する場合，クラス定義の外にあるdef式はデフォル トではprivateメソッドを定義し，クラス定義の中にあるdef式は publicメソッドを定義します．これはデフォルトであって， `Module`クラス で定義されている `public`, `private`を用い て変更できます．

また，`initialize`という名前のメソッドは常に privateとして定義されます．

### 特異メソッド定義

例:

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

文法:

    	def 式 `.' 識別子 [`(' [引数 [`=' default]]...[`,' `*' 引数 ]`)']
    	  式..
    	end

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

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

### `alias`

例:

    	alias foo bar
    	alias $MATCH $&

文法:

    	alias 新メソッド名 旧メソッド名
    	alias 新変数名 旧変数名

メソッドあるいは大域変数に別名をつけます．メソッドの定義内で 別名を付けるにはModuleクラスのメソッド alias_method を利用して下さい．

別名を付けられたメソッドは，その時点でのメソッド定義を引き継 ぎ，元のメソッドが再定義されても，再定義前の古いメソッドと同 じ働きをします．

正規表現の部分文字列に対応する変数 `$1`,`$2`,...には別名を付けることがで きません．また，インタプリタに対して重要な意味のある大域変数 を再定義すると動作に支障を来す場合があります．

### `undef`

例:

    	undef bar

文法:

    	undef メソッド名

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

### `defined?`

例:

    	defined? print
    	defined? File.print
    	defined?(foobar)
    	defined?($foobar)
    	defined?(@foobar)
    	defined?(Foobar)

文法:

    	defined? 式

式が定義されていなければ，偽を返します．定義されていれば式の種別 を表す文字列を返します．

前 - 次 - 目次

matz@netlab.co.jp