Syntax class and instance variables

Why does the instance_variables method not show @var_one for variable a ?

 a = Object.new def a.my_eval; yield end a.my_eval { @var_one = 1 } a.instance_variables # => [] instance_variables # => [@var_one] 
+6
source share
3 answers

You should use instance_eval :

 a.instance_eval { @var_one = 1 } => 1 a.instance_variables => [:@var_one] 

When you use regular eval , you define your instance variable in the context of the current self , if you do this in irb, this is the main object:

 a.eval { self } => main 

So, you can change your a.eval method by executing a block in the instance context:

 def a.eval(&block) instance_eval &block end a.eval { @a = 1 } => 1 a.instance_variables => [:@a] 
+9
source

If your goal is to set the instance variable programmatically, you can use:

 a.instance_variable_set(:@var_one, 1) 
+2
source

You should know the difference between eval and instance eval :

Kernel.eval evaluates the string in the current context or the context of this binding. This is the method used by the IRB to process your input. It allows you to define new variables and methods for the current context.

Object.instance_eval evaluates a string (or a given block) in the context of a specific instance of the class and thus allows direct access to the class properties without attr or attr_accessor . It allows you to define new methods for an instance.

So:

 a.instance_eval { @var_one = 1 } a.instance_variables # => [:@var_one] 
0
source

All Articles