ネストしたメソッドから外側の変数を参照したいができない(Ruby)
ダメな例
def twice(x) def inner(y) return x + y end return inner(x) end
> twice(2) NameError: undefined local variable or method `x' for main:Object
Rubyではdefしたらスコープが切り替わるため、defの外側のスコープを参照できない。
参考: Ruby のネストしたメソッドと、変数のスコープ | すぐに忘れる脳みそのためのメモ
解決策
def twice(x) inner = lambda {|y| return x + y } return inner.call(x) end
> twice(2) => 4 > twice(3) => 6
ブロックをlambdaでオブジェクト化し、それをローカル変数に代入する。callメソッドで呼び出すときの引数がブロック変数に渡される。関数じゃないけど第一級関数みたいでおもしろい。
参考: 楽しいRuby第4版 p417-p420
innerはアローを使って次のようにも書ける
inner = ->(y) {
return x + y
}
こっちは無名関数みたい。
参考: Matzにっき(2010-06-16)
まとめ
ネストしたメソッドはRubyではあまり意味がない。代わりにブロックを使う。