gpt4 book ai didi

ruby - instance_eval 的 block 参数 - 记录了吗?目的?

转载 作者:数据小太阳 更新时间:2023-10-29 07:00:17 24 4
gpt4 key购买 nike

刚刚意识到 instance_eval 产生 self 作为关联 block 的参数(除了 1.9.2 版本中的错误:http://www.ruby-forum.com/topic/189422)

1.9.3p194 :003 > class C;end
1.9.3p194 :004 > C.new.instance_eval {|*a| a}
=> [#<C:0x00000001f99dd0>]
1.9.3p194 :005 >

这是否在某处记录/规范?看着ruby-doc:BasicObject , 看不到提到的任何 block 参数。

除了一些纯粹的历史原因之外,是否还有其他原因明确地传递它,而它自己总是被定义?


我被这个击中的方式是:

l = lambda {  }
myobj.instance_eval(&l) # barks

这在 1.8.x 中运行良好(我猜是因为没有强制执行 block 数)。

然后升级到 1.9.2 - 它仍然有效!这是一个奇怪的巧合,因为即使严格执行 lambda block 参数(因此它会提示没有为 self 声明参数),但是由于上面链接的错误 - 这个版本实际上没有传递 self ..

然后升级到 1.9.3,该错误已得到修复,因此它开始抛出参数错误 - 对于次要版本更改恕我直言,这非常令人惊讶。

因此,一种解决方法是声明参数,或者将 lambda 改为 block :

 l = proc {  }
myobj.instance_eval(&l) # fine

只是想描述完整的故事,以帮助其他人避免像我那样浪费时间——直到这被适本地记录下来。

最佳答案

阅读Ruby的源代码,我能理解的是:

instance_eval 正在执行:

return specific_eval(argc, argv, klass, self)

依次运行:

 if (rb_block_given_p()) {
if (argc > 0) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
}
return yield_under(klass, self, Qundef);
}

您可以看到他们为 VALUES 参数传递了 Qundef

if (values == Qundef) {
return vm_yield_with_cref(th, 1, &self, cref);
}

在该特定代码行中,他们手动将 argc(参数计数)设置为 1,并将参数设置为“self”。稍后准备 block 的代码将 block 的参数设置为这些参数,因此第一个参数 = "self",其余参数为 nil。

设置 block 参数的代码正在做:

   arg0 = argv[0];

... bunch of code ...

else {
argv[0] = arg0;
}

for (i=argc; i<m; i++) {
argv[i] = Qnil;
}

导致:

1.9.3p194 :006 > instance_eval do |x, y, z, a, b, c, d| x.class end
=> Object
1.9.3p194 :008 > instance_eval do |x, y, z, a, b, c, d| y.class end
=> NilClass

为什么?我不知道,但代码似乎是故意的。很高兴向实现者提出问题,看看他们对此有何评论。

[编辑]

这可能是因为你传递给 instance_eval 的 block 可能是也可能不是为它制作的(代码取决于 self 被设置为你想要 block 修改的类),相反他们可能假设你要将您希望他们修改的实例作为参数传递给他们,这样他们也可以使用 instance_eval。

irb(main):001:0> blk = Proc.new do |x| x.class end
#<Proc:0x007fd2018447b8@(irb):1>
irb(main):002:0> blk.call
NilClass
irb(main):003:0> instance_eval &blk
Object

当然这只是一个理论,没有官方文档我只能猜测。

关于ruby - instance_eval 的 block 参数 - 记录了吗?目的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12648157/

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