TL;DR の応答は、ブロック スコープの外でアクセス可能な変数を定義する必要があるということです。
まず、API のドキュメントを確認してください。
http://rubydoc.info/gems/highline/HighLine#choose-instance_method
が表示def choose( *items, &details )
されるので、choose メソッドは任意の長さの引数とブロックを受け取ります。do ... end
ブロックは、choose 呼び出しに渡される場所です。
choose do |menu|
menu.choice(:meow) {|q| q = 'foo'}
end
わかりましたので、別のメソッドが表示されますchoice
: http://rubydoc.info/gems/highline/HighLine/Menu#choice-instance_method
# File 'lib/highline/menu.rb', line 136
def choice( name, help = nil, &action )
@items << [name, action]
@help[name.to_s.downcase] = help unless help.nil?
update_responses # rebuild responses based on our settings
end
.choice(:meow) {|q| q = 'foo'}
から見たものを使って分解してみましょうchoice
。それは name を期待し、(:meow)
何も提供されていない場合は help をデフォルトで nil にし (したがって、私の呼び出し例では nil です)、最後に別のブロックである{|q| q = 'foo'}
.
私の例は次のように評価されます。
1. meow
? 1
=> "foo"
q
=> NameError: undefined local variable or method `q' for main:Object
なんで?q は、渡されるブロックのスコープ内でのみ定義されているためです。そのプロシージャが評価されると、アクセスできません。だからあなたがする必要があるのはこれです:
1.9.3-p448 :015 > choose do |menu|
1.9.3-p448 :016 > menu.choice(:meow) { @foo = 'foo'}
1.9.3-p448 :017?> end
1. meow
? 1
=> "foo"
1.9.3-p448 :018 > @foo
=> "foo"