实例_eval中的ruby access实例变量
我正在尝试一些ruby元编程,但对instance_eval()有些混淆 见下面的例子实例_eval中的ruby access实例变量,ruby,metaprogramming,instance-variables,instance-eval,Ruby,Metaprogramming,Instance Variables,Instance Eval,我正在尝试一些ruby元编程,但对instance_eval()有些混淆 见下面的例子 @instance_var = 'instance_var' local_var = 'local_var' obj = Object.new obj.instance_eval { p @instance_var; p local_var } obj.instance_eval { @instance_var = 'instance_var_in_obj'; local_var = 'local_var_
@instance_var = 'instance_var'
local_var = 'local_var'
obj = Object.new
obj.instance_eval { p @instance_var; p local_var }
obj.instance_eval { @instance_var = 'instance_var_in_obj'; local_var = 'local_var_in_obj' }
p @instance_var; p local_var
我希望@instance_var和local_var都可以在块中传递/修改,但我得到了
nil
"local_var"
"instance_var"
"local_var_in_obj"
因此,我们可以在instance_val
中共享(传递/修改)本地变量,但实例变量属于self
无法共享
关于实例执行
:
obj.instance_exec(@instance_var) {|instance_var| p instance_var; instance_var = @instance_var }
=> "instance_var"
@instance_var
=> "instance_var"
现在我可以传递我的外部实例var,但仍然不能修改它
@instance_arr = []
obj.instance_exec(@instance_arr) {|instance_arr| instance_arr << 'in_block' }
@instance_arr
=> ["in_block"]
obj.instance_exec(@instance_arr) {|instance_arr| instance_arr = [] }
@instance_arr
=> ["in_block"]
@instance\u arr=[]
obj.instance_exec(@instance_arr){| instance_arr | instance_arr[“in_block”]
obj.instance_exec(@instance_arr){| instance_arr | instance_arr=[]}
@实例_arr
=>[“在块中”]
使用数组的实例变量,我可以修改实例变量,但只能在当前数组对象中修改
总之,使用本地变量而不是实例变量播放instance\u eval
或instance\u exec
是否有一些概念我遗漏了?为了计算局部变量,需要传入字符串“local\u var”,它将返回局部变量的值。根据我对的解释,如果传入块,则无法传入参数 块形式中实例eval的行为是作为闭包访问调用所在对象的实例变量和私有方法
带有参数的instance eval的行为允许您计算该调用范围内的字符串。经过我朋友的搜索和建议,我想我已经解决了问题。 在ruby中,当您的代码运行
self
和binding
时,当您使用local vars
或method
而不设置self时,有两种上下文
。xxx
第一件事将检查它是否作为local var
对象在绑定
对象中,如果不是,ruby将认为它是一种方法搜索self
对象以查找其定义并调用它。
你可以这样想:
class A
def test
4
end
def use_variable
test = 5
test
end
def use_method
test = 5
self.test
end
end
a = A.new
a.use_variable # returns 5
a.use_method # returns 4
这就解释了实例评估的原因,因为它的文档说实例评估只是在给定的块中更改了self
,而没有触及绑定
,所以方法将在新的self
上搜索,本地VAL仍然在相同的绑定
对象中
关于instance\u exec
我对此不是很确定,但似乎是instance vars(带有at前缀vars)它将在self
上搜索,直接跳过binding
,因此在instance\u exec
之外,您的@instance\u arr
属于旧的self
,并且在instance\u exec
块中,您将其作为块的新binding
中的一个新的本地var
(块有自己的范围)但是它的值实际上是@instance\u arr
的引用,因此在新的本地var
上调用方法,例如push
,它将更改它们,因为它们共享相同的数组实例
,但是当您将新的数组实例
分配给新的本地var
时,它们将不再被引用相同的数组实例
这是第二个原因
我可以提供1/2的答案。您有两个名为@instance\u var的实例变量,一个用于我们称之为main
的对象的实例,另一个obj
。在obj.instance\u eval{p@instance\u var;p local\u var}的块中
,self
是obj
和@instance\u var
,因为该对象尚未初始化,所以在引用时返回nil
。我不完全理解为什么局部变量会被区别对待,但我怀疑这与引用初始化的局部变量会引发异常有关。不是吗谢谢你的回答,关于@instance\u var
这个@
说你属于某个人,我想我能理解这一部分,是的,我的问题的重点是为什么局部变量被不同地对待
或者局部变量
实际上属于怎样看待它的范围??谢谢你的回答,你的朋友解释是正确的我只是忘记了binding
概念它可以解释问题。:)