Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
实例_eval中的ruby access实例变量_Ruby_Metaprogramming_Instance Variables_Instance Eval - Fatal编程技术网

实例_eval中的ruby access实例变量

实例_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_

我正在尝试一些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_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
概念它可以解释问题。:)