ローカル変数と等号付きメソッド
レシーバを省略するとメソッドではなくローカル変数として扱われます。 普通のメソッドはselfのレシーバを省略できますが、この場合は不可。
class Foo
def bar=(v)
end
def baz
bar = 0 # ローカル変数 bar への代入
self.bar = 0 # メソッド bar= の呼び出し
end
end
制御構造(ifやwhileなど)はスコープを作らない。
while や for がスコープを作らないのに対し、loop や each などのイテレー タはスコープを作ります。
while true
var = true
break
end
p var
# => true
loop {
var = true # このブロックの中でローカル
break
}
p var
# => -:5: undefined local variable or method `var' for #<Object:0x401a7b28> (NameError)
for i in 1..3
var = true
end
p var
# => true
(1..3).each {
var = true # このブロックの中でローカル
}
p var
# => -:4: undefined local variable or method `var' for #<Object:0x401a7b28> (NameError)
多重ループを抜ける
重複したループを抜けるには、break ではなく catch/throw
を使用します。
catch(:last) {
while true
(1..5).each{|x|
throw :last if x == 3
print "#{x}\n"
}
end
}
ローカル変数は本当にローカル。Perl の my とかとは違う
# Ruby
local = "hoge"
def hoge
print local, "\n" # 未定義。エラー
end
hoge
# Perl
my $local = "hoge";
sub hoge {
print $local, "\n"; #=> hoge
}
hoge;
組み込み関数
loadのように組み込み関数と同じ名前のメソッドを定義しているクラスで、 組み込み関数のloadを呼び出すにはKernel::をつけます。
class Hoge
def call_load
load "nosuchfile.rb"
self.load "nosuchfile.rb"
Kernel::load "nosuchfile.rb"
end
def load(arg)
puts "Hoge#load #{arg}"
end
end
Hoge.new.call_load
# => Hoge#load nosuchfile.rb
# Hoge#load nosuchfile.rb
# LoadError: No such file to load -- nosuchfile.rb
ブロックの引数のスコープ
a = [1,2,3]
a.sort{|a,b| b<=>a} # a に代入される
p a.type #=> Fixnum # 最後に代入された a