SSブログ

ブロックと関数の違い [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 !!

これはややこしいなあ。というかブロックの仮引数名を決めるときに外側の変数名と衝突しないように気をつけなきゃいけないので関数型プログラミング云々以前で不便な気がする。


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。