All is stated in the question. Both of these methods can access (read/write) instance variables by using their code name :
__send__
instance_variable_set
instance_variable_get
Could someone explain it by examples ?
Metaprogramming is sometimes melting our brain when we explore it with abstraction.
=== EDIT ===
Ok I make a resume of the answers as an example for later use if my brain is melting again.
Class declaration :
class Person
attr_accessor :first_name, :last_name
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
def full_name
@first_name + ' ' + @last_name
end
end
Initialization :
actor = Person.new('Donald', "Duck")
=> #<Person:0xa245554 @first_name="Donald", @last_name="Duck">
usage of send (read) :
actor.send('first_name')
=> "Donald"
actor.send(:first_name)
=> "Donald"
actor.send("last_name")
=> "Duck"
actor.send(:last_name)
=> "Duck"
actor.send('full_name')
=> "Donald Duck"
actor.send(:full_name)
=> "Donald Duck"
usage of instance_variable_get (read)
actor.instance_variable_get('@first_name')
=> "Donald"
actor.instance_variable_get(:@first_name)
=> "Donald"
actor.instance_variable_get('@last_name')
=> "Duck"
actor.instance_variable_get(:@last_name)
=> "Duck"
usage of send (write) :
actor.send('first_name=', 'Daisy')
actor.send('full_name')
=> "Daisy Duck"
actor.send(:first_name=, "Fifi")
actor.send("full_name")
=> "Fifi Duck"
usage of instance_variable_set (write)
actor.instance_variable_set('@first_name', 'Pluto')
actor.send("full_name")
=> "Pluto Duck"
actor.instance_variable_set(:@last_name, 'Dog')
actor.send(:full_name)
=> "Pluto Dog"
INCORRECT usage of instance_variable_get (read)
actor.instance_variable_get('full_name')
#NameError: `full_name' is not allowed as an instance variable name
actor.instance_variable_get('last_name')
#NameError: `last_name' is not allowed as an instance variable name
I was geting confuse with Rails ActiveRecord and its Associations.
Thanks for the answers !
__send__ methods invokes method which are defined in your class, if the method is not defined then you cannot use send method, but instance_variable_get and set methods changes the value of the instance variable without the need for any encapsulating methods (like getters or setters).
__send__ is used if you want to invoke a method identified by the symbol and passing any argument if needed.
e.g.
class Test
def sayHello(*args)
"Hello " + args.join(' ')
end
end
k = Test.new
k.send :sayHello, "readers" #=> "Hello readers"
instance_variable_get Returns the value of the given instance variable, or nil if the instance variable is not set. Use this method without the need for encapsulation
e.g
class Test
def initialize(p1)
@a = p1
end
end
test = Test.new('animal')
test.instance_variable_get(:@a) #=> "animal"
instance_variable_set used to set the value for an instance variable without the need for encapsulating methods.
e.g
class Test
def initialize(p1)
@a = p1
end
end
test = Test.new('animal')
test.instance_variable_set(:@a, 'animal')
__send__ allows you to call a method by name/symbol,
instance_variable_* allows you to set/get instance variables.
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