Given some local variables, what would be the easiest way to compact
them in Ruby?
def foo
name = 'David'
age = 25
role = :director
...
# How would you build this:
# { :name => 'David', :age => 25, :role => :director }
# or
# { 'name' => 'David', 'age' => 25, 'role' => :director }
end
In PHP, I can simply do this:
$foo = compact('name', 'age', 'role');
I came up with a significant improvement on my original answer. It is cleaner if you inherit from Binding
itself. The to_sym
is there because older versions of ruby have local_variables
as strings.
instance method
class Binding
def compact( *args )
compacted = {}
locals = eval( "local_variables" ).map( &:to_sym )
args.each do |arg|
if locals.include? arg.to_sym
compacted[arg.to_sym] = eval( arg.to_s )
end
end
return compacted
end
end
usage
foo = "bar"
bar = "foo"
binding.compact( "foo" ) # => {:foo=>"bar"}
binding.compact( :bar ) # => {:bar=>"foo"}
Original answer
This is the nearest I could get to a method that behaves like Php's compact
-
method
def compact( *args, &prok )
compacted = {}
args.each do |arg|
if prok.binding.send( :eval, "local_variables" ).include? arg
compacted[arg.to_sym] = prok.binding.send( :eval, arg )
end
end
return compacted
end
example usage
foo = "bar"
compact( "foo" ){}
# or
compact( "foo", &proc{} )
Its not perfect though, because you have to pass a proc in. I am open to suggestions about how to improve this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With