Ruby には、スクリプト スコープ、モジュール/クラス/メソッド定義スコープ、およびブロック スコープがあります。ブロックのみがネストされたスコープを作成します。したがって、ブロックを使用してメソッドを定義する必要があります。ありがたいことに、ブロックを取るメソッドを定義するメソッドがあります。
def f
v = 5
define_method :g do
v
end
g
end
f
# => 5
ただし、これはあなたが思っていることをしないことに注意してください (元のコードもそうではありません)。methodにネストされたメソッドを定義しません。Ruby にはネストされたメソッドがありません。メソッドは常にモジュールに属し (クラスはモジュールです)、メソッドに属することはできません。g
f
これが行うことは、メソッドをf
定義することです。これを実行すると、メソッドが定義され、g
そのメソッドが呼び出されます。
観察:
methods.include?(:g)
# => true
と呼ばれる新しいトップレベル メソッド (実際には のプライベート インスタンス メソッドObject
)g
を定義しましたf
。
おそらく必要なのはラムダです:
def f
v = 5
g = -> { v }
g.()
end
f
# => 5
あなたが書いた別の回答へのコメントで:
さて、私はラムダをいじっています.私がv
内部に行ったことは、一度返さg
れたものに反映されていないことに気付きました. 変更を固定する方法はありますか?v
g
v
def f
v = 5
g = -> { v = 'Hello' }
g.()
v
end
f
# => 'Hello'
ご覧のとおり、への変更v
は復帰後に「固着」しg
ます。