单例 class 和实例变量

Singleton class and instance variables

为什么 instance_variables 方法不针对变量 a 显示 @var_one

a = Object.new

def a.my_eval; yield end

a.my_eval { @var_one = 1 }
a.instance_variables
# => []
instance_variables
# => [@var_one]

你应该使用 instance_eval:

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

当你使用普通eval时,你在当前self的上下文中定义你的实例变量,如果你在irb中这样做,它是main对象:

a.eval { self }
=> main

因此,您可以通过在实例上下文中执行块来修改 a.eval 方法:

def a.eval(&block)
  instance_eval &block  
end

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

如果您的目标是以编程方式设置实例变量,您可以使用:

a.instance_variable_set(:@var_one, 1)

你应该知道evalinstance eval的区别:

Kernel.eval 在当前上下文或给定绑定的上下文中评估字符串。这是 IRB 用来处理您的输入的方法。它允许您为当前上下文定义新的变量和方法。

Object.instance_eval 在某个 class 实例的上下文中评估字符串(或给定的块),因此允许直接访问 class 属性而无需 attrattr_accessor。它允许您为实例定义新方法。

所以 :

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