What is the difference between the "__send__" and "instance_variable_get / instance_variable_set" methods?

Everything is indicated in the question. Both of these methods can access instance variables (read / write) using their codename:

__send__


instance_variable_set
instance_variable_get

      

Can anyone explain this with examples?

Metaprogramming sometimes melts out of our brains when we examine it in abstraction.

=== EDIT ===

Good. I am making a summary of the answers as an example for later reference if my brain melts 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">

      

using 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"

      

using 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"

      

using send (write):

actor.send('first_name=', 'Daisy')

actor.send('full_name')
=> "Daisy Duck"

actor.send(:first_name=, "Fifi")

actor.send("full_name")
=> "Fifi Duck"

      

using 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 use 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 confused with Rails ActiveRecord and its associations.

Thanks for answers!

+3


source to share


2 answers


__send__

methods call a method that is defined in your class, if the method is not defined then you cannot use the method send

, but methods instance_variable_get

and set

change the value of the instance variable unnecessarily for any encapsulation methods (like getters or setters).

__send__

used when you want to call a method identified by a symbol and pass any argument as needed.

eg.

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 this instance variable, or nil if no instance variable is set. Use this method without the need for encapsulation



eg

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 a value for an instance variable without the need for encapsulation techniques. eg

class Test
  def initialize(p1)
    @a = p1
  end
end
test = Test.new('animal')
test.instance_variable_set(:@a, 'animal')

      

+2


source


__send__

allows you to call a method by name / symbol,
instance_variable_*

allows you to set / get instance variables.



+2


source







All Articles