Thread
や手続きオブジェクトの
中でローカル変数を局所化できるようにするためです.
while
,until
,for
は制御構造であり,新しいスコープを
導入しません.
loop
はメソッドで,後ろについているのはブロックです.
Ruby
スクリプトは,Ruby
インタプリタに実行させようとすると,
まず最後まで一度読みこまれ,構文解析されます.構文上問題が生じなければ,
構文解析で作られた構文木が最初から実行に移されます.
for i in 1..2
if i == 2
print a
else
a = 1
end
end
test.rb
というファイルにいれて,このスクリプトを実行すると,
test.rb:3: undefined local variable or method `a' for
#<Object:0x40101f4c> (NameError)
from test.rb:1:in `each'
from test.rb:1
ということで,i
が1の時は,エラーが起こらず,i
が2になった時に
エラーが起こります.構文解析の時には,最初のprint a
が実際には
a
への代入が行われてから実行されるというところまで解析されず,
この文を構文解析する時までにa
への代入文が現われていないので,
ローカル変数は参照されません.実行時にはa
というメソッドが
ないか探しますが,これも定義されていないのでエラーになります.
a = 1 if false; print a
# ->nil
ローカル変数のこのような振舞いに悩まされないためには,ローカル変数が
参照される文より前に,a = nil
といった代入文を置くことがすすめられて
います.こうすると,ローカル変数の参照が速くなるというおまけもついて
います.
Object
クラスに追加されますので,
すべてのクラス/モジュールから参照できます.
::
演算子を使って,クラス/モジュール名を
指定することにより参照できます.
*
がついた引数は何ですか
*
を付けることで,不定個の引数を配列に格納した形で受け取ることがで
きます.
def foo(*all)
for e in all
print e, " "
end
end
foo(1, 2, 3)
# -> 1 2 3
またメソッド呼び出しで*
を付けた配列を渡すと配列を展開して渡すこと
ができます.
a = [1, 2, 3]
foo(*a)
現在,*
をつけることができるのは
case
のwhen
節
x, *y = [7, 8, 9]
のような形式で,この場合 x = 7
,y = [8, 9]
になり
ます.
x, = [7, 8, 9]
のような記述もでき,この場合,x
= 7 で
x = [7, 8, 9]
なら,x = [7, 8, 9]
になります.
&
がついた引数は何ですか
A = a = b = "abc"; b << "d"; print a, " ", A
# ->abcd abcd
変数や定数への代入は,オブジェクトを後でその変数や定数で参照する
ために用いられます.変数や定数にオブジェクトそのものが代入されて
いるのではなく,オブジェクトの参照を保持しているだけです.変数は,
この参照を変更して異なるオブジェクトを参照するようにすることが
できますが,定数では一度保持した参照を変更することができません.