I have an instance variable @foo
and I want to write some code so that I get string 'foo'
any hint?
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.
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.
Instance variables are not inherited.
instance_variable_get. Returns the value of the given instance variable in self , or nil if the instance variable is not set. instance_variable_set. Sets the value of the given instance variable in self to the given object.
If all you have is a reference to the object, you can't really do it cleanly.
def foo
bar @something
end
def bar(value)
value # no clean way to know this is @something
end
The only hack I can think of is to loop through ALL instance variables on self
, looking for matches. But its a very messy approach that's likely to be slow.
def bar(value)
instance_variables.each do |ivar_name|
if instance_variable_get(ivar_name) == value
return ivar_name.to_s.sub(/^@/, '') # change '@something' to 'something'
end
end
# return nil if no match was found
nil
end
@something = 'abc123'
bar @something # returns 'something'
# But passing the same value, will return a value it's equal to as well
bar 'abc123' # returns 'something'
This works because instance_variables
returns an array of symbols that are the names of instance variables.
instance_variables
#=> [:@something, :@whatever]
And instance_variable_get
allows you to fetch the value by it's name.
instance_variable_get :@something # note the @
#=> 'abc123'
Combine the two methods and you can get close to what you want.
Just use it wisely. Before using a solution based on this, see if you can refactor things a way so that it's not necessary. Meta-programming is like a martial art. You should know how it works, but have the discipline to avoid using it whenever possible.
In Ruby, you can only manipulate objects. Variables (including instance variables) aren't objects.
Besides, what do you want your magic method to return in this case:
foo = Object.new
bar = foo
@baz = bar
@qux = bar
magic_method(foo) # what should the return value be and how would it know?
You can call the method instance_variables
to get the name of all instance variables of an object. Caution though that instance variables are only included in that list after they have been initialized.
>> class A; attr_accessor :foo; end
=> nil
>> a = A.new
=> #<A:0x103b310b0>
>> a.instance_variables
=> []
>> a.foo = 42
=> 42
>> a.instance_variables
=> ["@foo"]
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