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