Ruby 1.9无变量块

4
我正在将一个代码库从1.8升级到1.9。我在我的代码中遇到了几个问题(只有规范,不确定是否是巧合),其中有些块没有变量。为它们提供虚拟变量可以解决这个问题。下面是一个例子:
在工厂女孩的工厂中,这在1.8下可以正常工作:
Factory.define :thing do |t|
  t.price { 1 - 0.01*rand(10) }
end

在1.9版本下,rand(10)返回nil,非常奇怪。我一直在想为什么块内部的环境会不同。事实上,rand甚至不是来自标准库,而是来自核心语言!因此,环境并没有什么区别。
然后我想起来,我的一些规范中的其他地方也因为没有变量块而出现问题,所以我试着将一个变量块放进去,结果竟然成功了。
Factory.define :thing do |t|
  t.price { |dummy| 1 - 0.01*rand(10) }
end

这里发生了什么?

2
Lambdas、Procs和blocks在Ruby中的行为都不同,因此请务必指定正确的内容,不要混淆它们。我相信你在这里指的是blocks,而不是Procs/lambdas。 - Andrew Marshall
糟糕 - 是的,我知道,只是在阅读关于lambda的其他内容,脑子里还想着那个:D 现在已经修复了。 - John Bachir
1
这和FactoryGirl有关。例如,这在我的Ruby版本1.9.2的IRB中可以正常工作:5.times { puts rand(20) }。 - kclair
1
这里有一个关于类似你的话题的讨论:https://github.com/thoughtbot/factory_girl/issues/229你可以尝试调用Kernel.rand()而不是rand()吗? - Deradon
1个回答

2
在最近的factory_girl版本中,定义一个没有块参数的属性会使用instance_eval,并且它假设裸方法调用是在寻找之前的属性定义、模型上的方法或语法方法,例如“create”或“build”。
为了使像“open”或“file”这样的属性正常工作,代理对象undefines大多数私有方法,包括“rand”。这意味着您需要使用“Kernel.rand”而不是仅仅使用“rand”。
您可以在此处查看相关源代码:https://github.com/thoughtbot/factory_girl/blob/master/lib/factory_girl/evaluator.rb#L16

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接