ブロックと関数の違い [Ruby]
今日 Ruby でブロックを使ったプログラムを書いていてはまったのだけど、ブロックの仮引数のように見えるものはブロックの外側に同名の変数がある場合はそれを参照してしまうようだ。
x="foo"
print "outside (before): " + x + "\n"
["bar"].each{|x|
print "inside block: " + x + "\n"
}
print "outside (after): " + x + "\n"
実行結果:
outside (before): foo inside block: bar outside (after): bar
一方でスコープが無いというわけでもない。
1.times{x=1}
p x
実行結果:
tryme.rb:2: undefined local variable or method `x' for main:Object (NameError)
さて、 def を使った関数定義では仮引数は当然ローカル変数になる。そして Ruby にも lambda 表記があるのだけど、これはブロックを使った表現となる。ということは def による関数定義と変数への lambda の代入は必ずしも置き換えられないということだ。
x=1
def f(x) return x end
f(2)
p x #=>"1"
f = lambda{|x| return x }
f.call(3)
p x #=>3 !!
これはややこしいなあ。というかブロックの仮引数名を決めるときに外側の変数名と衝突しないように気をつけなきゃいけないので関数型プログラミング云々以前で不便な気がする。
コメント 0