gpt4 book ai didi

ruby 在 instance_eval 中访问实例变量

转载 作者:行者123 更新时间:2023-12-04 18:04:23 25 4
gpt4 key购买 nike

我正在尝试一些 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 都可以在 block 中传递/修改,但我得到了

nil
"local_var"
"instance_var"
"local_var_in_obj"

因此我们可以在 instance_val 中共享(传递/修改)本地变量,但实例变量属于 self 无法共享。

关于instance_exec:

obj.instance_exec(@instance_var) {|instance_var| p instance_var; instance_var = @instance_var }
=> "instance_var"
@instance_var
=> "instance_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_evalinstance_exec

我错过了一些概念吗?

最佳答案

经过我 friend 的一些搜索和建议后,我想我找到了问题所在。在 ruby 中有两个 Context当你的代码运行 selfbinding , 当你使用 local varsmethod没有设置 self.xxx首先要检查它是否在您的 binding 中对象作为 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

这就是解释WHYinstance_eval正如其文件所述instance_eval刚改了 self在给定的 block 中,不要触摸 binding所以方法将在新的 self 上搜索, 本地 vals 仍然在同一个 binding对象。

关于instance_exec我对此不太确定,但似乎实例变量(带有前缀变量)将在 self 上搜索直接跳过binding , 所以出instance_exec你的@instance_arr属于旧selfinstance_exec阻止你得到它作为一个新的 local var在新binding block 的( block 有自己的范围)但它的值实际上是 @instance_arr 的引用所以在新的 local var 上调用方法比如push它会改变它们,因为它们共享相同的 Array instance , 但是当你分配一个新的 Array instance到新local var他们不再引用相同的Array instance那是第二个WHY .

关于ruby 在 instance_eval 中访问实例变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29598609/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com