Jest to wariant odpowiedzi Bungus', ale tu jest jeden-liner, że jest zdecydowanie brzydsze, ale nie obejmuje oprawy lub cokolwiek:
foo = :bar
baz = :bin
hash = [:foo, :baz].inject({}) {|h, v| h[v] = eval(v.to_s); h }
# hash => {:baz=>:bin, :foo=>:bar}
Można również sprawić wrażenie kinda-coś w stylu wywołanie metody nadużywając blok wiążący - kolejny wariant na pierwotną odpowiedź Bungus': (. ja po prostu mówię sobie, że {[..]}
jest symbolem Zgniatarka śmieci)
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}
Jeśli używasz binding_of_caller
gem, można zrezygnować z proc i wyraźne wiązanie wszystko razem:
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}
Uważajcie, to powoli. W kodzie produkcyjnym prawdopodobnie nigdy nie powinieneś próbować tego robić, a zamiast tego po prostu zachować wartość hash, więc programista, który musi to utrzymywać, nie będzie cię ścigał i zabije cię we śnie.
http://stackoverflow.com/questions/6589894/access-local-variables- from-a-different-inding-in-ruby –
Jestem szczerze zaskoczony, że PHP pozwala na takie aberry ..., mmm, nieortodoksyjny kod . Czy 'compact' rzeczywiście pobiera zmienne lokalne według nazw i uzyskuje dostęp do nich z poziomu innej funkcji? – tokland