单例 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)
你应该知道eval
和instance eval
的区别:
Kernel.eval
在当前上下文或给定绑定的上下文中评估字符串。这是 IRB 用来处理您的输入的方法。它允许您为当前上下文定义新的变量和方法。
Object.instance_eval
在某个 class 实例的上下文中评估字符串(或给定的块),因此允许直接访问 class 属性而无需 attr
或 attr_accessor
。它允许您为实例定义新方法。
所以 :
a.instance_eval { @var_one = 1 }
a.instance_variables
# => [:@var_one]
为什么 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)
你应该知道eval
和instance eval
的区别:
Kernel.eval
在当前上下文或给定绑定的上下文中评估字符串。这是 IRB 用来处理您的输入的方法。它允许您为当前上下文定义新的变量和方法。
Object.instance_eval
在某个 class 实例的上下文中评估字符串(或给定的块),因此允许直接访问 class 属性而无需 attr
或 attr_accessor
。它允许您为实例定义新方法。
所以 :
a.instance_eval { @var_one = 1 }
a.instance_variables
# => [:@var_one]