I have a variable var = \"some_name\"
and I would like to create a new object and assign it to some_name
. How can I do it? E.g.
var
Speaking of ruby 2.2.x it is true that you can't create local variables programatically in current context/binding.. but you can set variables in some particular binding you have a handle of.
b = binding
b.local_variable_set :gaga, 5
b.eval "gaga"
=> 5
Interesting here is that calls to binding
give you a new binding each time. So you need to get a handle of the binding you are interested in and then eval in it's context once desired variables are set.
How is this useful? For example I want to evaluate ERB and writing ERB is much nicer if you can use <%= myvar %>
instead of <%= opts[:myvar] %>
or something like that.
To create a new binding I'm using a module class method (I'm sure somebody will correct me how to call this properly, in java I'd call it a static method) to get a clean binding with particular variables set:
module M
def self.clean_binding
binding
end
def self.binding_from_hash(**vars)
b = self.clean_binding
vars.each do |k, v|
b.local_variable_set k.to_sym, v
end
return b
end
end
my_nice_binding = M.binding_from_hash(a: 5, **other_opts)
Now you have a binding with only the desired variables. You can use it for nicer controlled evaluation of ERB or other (possibly third party) trusted code (this is not a sandbox of any kind). It's like defining an interface.
update: A few additional notes about bindings. Place you create them also affects the availability of methods and Constants resolution. In the above example I create a reasonably clean binding. But if I want to make available the instance methods of some object, I could create a binding by a similar method but within the class of that object. e.g.
module MyRooTModule
class Work
def my_instance_method
...
end
def not_so_clean_binding
binding
end
end
class SomeOtherClass
end
end
Now my my_object.not_so_clean_binding
will allow code to call #my_instance_method
on my_object
object. In the same way, you can call for example SomeOtherClass.new
in code using this binding instead of MyRootModule::SomeOtherClass.new
. So there is sometimes more consideration needed when creating a binding than just local variables. HTH