這是Bungus'回答一個變種,但這裏有一個一行是斷然醜陋,但不延長綁定或任何東西:
foo = :bar
baz = :bin
hash = [:foo, :baz].inject({}) {|h, v| h[v] = eval(v.to_s); h }
# hash => {:baz=>:bin, :foo=>:bar}
您也可以使它看起來勝負的樣濫用塊結合的方法調用 - 再次,在Bungus'原來的答覆變體:(我就告訴自己,{[..]}
是垃圾壓實符號)
module Kernel
def compact(&block)
args = block.call.map &:to_sym
lvars = block.binding.send(:eval, "local_variables").map &:to_sym
(args & lvars).inject({}) do |h, v|
h[v] = block.binding.send(:eval, v.to_s); h
end
end
end
foo = :bar
baz = :bin
compact {[ :foo, :bar, :baz ]}
# {:foo=>:bar, :baz=>:bin}
如果使用binding_of_caller
寶石,你可以放棄PROC 和顯式綁定一起:
require 'binding_of_caller'
module Kernel
def compact(*args)
lvars = binding.of_caller(1).send(:eval, "local_variables").map &:to_sym
(args.map(&:to_sym) & lvars).inject({}) do |h, v|
h[v] = binding.of_caller(2).send(:eval, v.to_s); h
end
end
end
foo = :bar
baz = :bin
compact :foo, :bar, :baz
# {:foo=>:bar, :baz=>:bin}
被警告,它的速度慢。在生產代碼中,你應該永遠不要試圖去做這件事,而應該保留一個值的散列值,這樣程序員在你之後不得不維持這個值,並不會在你的睡眠中追捕你並殺死你。
http://stackoverflow.com/questions/6589894/access-local-variables-from-a-different-binding-in-ruby –
我真的很困惑PHP允許這種異常...,嗯,非傳統的代碼。 'compact'真的是通過名稱獲取本地變量並從另一個函數中訪問它們嗎? – tokland