Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the value of an instance variable given its name

In general, how can I get a reference to an object whose name I have in a string?

More specifically, I have a list of the parameter names (the member variables - built dynamically so I can't refer to them directly).

Each parameter is an object that also has an from_s method.

I want to do something like the following (which of course doesn't work...):

define_method(:from_s) do | arg |     @ordered_parameter_names.each do | param |         instance_eval "field_ref = @#{param}"         field_ref.from_s(param)     end end 
like image 300
LK__ Avatar asked Jul 02 '09 14:07

LK__


People also ask

Which is used to get the value of the instance variables?

Values can be assigned during the declaration or within the constructor. Instance variables can be accessed directly by calling the variable name inside the class. However, within static methods (when instance variables are given accessibility), they should be called using the fully qualified name.

How do you access instance variables in Ruby?

The instance variables of an object can only be accessed by the instance methods of that object. The ruby instance variables do not need a declaration. This implies a flexible object structure. Every instance variable is dynamically appended to an object when it is first referenced.

How do you name an instance variable?

Instance variable names begin with an underscore ( _ ) followed by a camel case alphanumeric string. The first character following the underscore must be a lowercase letter; numerals are not permitted.

How do you know if a variable is an instance variable?

An instance variable is a variable which is declared in a class but outside of constructors, methods, or blocks. Instance variables are created when an object is instantiated, and are accessible to all the constructors, methods, or blocks in the class.


2 Answers

The most idiomatic way to achieve this is:

some_object.instance_variable_get("@#{name}") 

There is no need to use + or intern; Ruby will handle this just fine. However, if you find yourself reaching into another object and pulling out its ivar, there's a reasonably good chance that you have broken encapsulation.

If you explicitly want to access an ivar, the right thing to do is to make it an accessor. Consider the following:

class Computer   def new(cpus)     @cpus = cpus   end end 

In this case, if you did Computer.new, you would be forced to use instance_variable_get to get at @cpus. But if you're doing this, you probably mean for @cpus to be public. What you should do is:

class Computer   attr_reader :cpus end 

Now you can do Computer.new(4).cpus.

Note that you can reopen any existing class and make a private ivar into a reader. Since an accessor is just a method, you can do Computer.new(4).send(var_that_evaluates_to_cpus)

like image 59
Yehuda Katz Avatar answered Sep 27 '22 21:09

Yehuda Katz


To get an instance variable from the name of an instance variable do:

name = "paramName" instance_variable_get(("@" + name).intern) 

This will return the value of the instance variable @paramName

like image 33
Daniel Lucraft Avatar answered Sep 27 '22 19:09

Daniel Lucraft