1

我想看看具有相同参数的 proc 调用是否每次都会给出相同的结果。pureproc用参数调用是免费的,所以每次我调用时pureproc(1,1),我都会得到相同的结果。dirtyproc用参数调用是绑定在其环境中的,因此即使它具有与 相同的数量pureproc,它的输出也将取决于环境。

ruby-1.9.2-p136 :001 > envx = 1
=> 1
ruby-1.9.2-p136 :003 > pureproc = Proc.new{ |a,b| a+b }
 => #
ruby-1.9.2-p136 :004 >dirtyproc = Proc.new{ |a,b| a+b+环境 }

我如何以编程方式确定被调用的过程或方法是否是免费的,正如仅绑定在必须传入的变量上所定义的那样?也欢迎对绑定、局部变量等进行任何解释。

4

2 回答 2

1

可能您可以使用诸如 sourcify 之类的 gem 解析源,取出所有标记,并检查是否有任何变量。但请注意,这与 proc/method 调用的值是常量不同的概念。例如,如果您的代码中有类似Time.noworRandom.new的内容,则不需要定义任何变量,但每次调用时仍会有所不同。另外,当 proc 有 时,您希望是什么情况envx - envx?这将保持不变,但仍会影响代码,因为除非envx定义,否则它将返回错误。

于 2012-09-25T06:20:47.000 回答
0

嗯,棘手。有parameters一种方法可以告诉您预期的参数(请注意它们是可选的,因为您使用的是 procs,而不是 lambdas)。

pureproc.parameters
=> [[:opt, :a], [:opt, :b]] 
dirtyproc.parameters
=> [[:opt, :a], [:opt, :b]]

至于确定是否实际使用封闭变量之一来计算 proc 的返回值,我想到了走 AST(有宝石),但似乎很麻烦。我的第一个想法是这样的dirtyproc.instance_eval { local_variables },但由于两个闭包都关闭在同一个环境中,这显然不会让你走得太远......

但总体问题是:如果您想确保某些东西是纯净的,为什么不首先将其作为一种不关闭环境的适当方法呢?

于 2012-09-24T19:44:03.863 回答