如何确定proc呼叫是否仍然免费或绑定?

时间:2012-09-24 19:33:23

标签: ruby

我想看看每次使用相同参数的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+envx }

如何以编程方式确定被调用的proc或方法是否是空闲的,只是通过绑定必须传入的变量来定义?对绑定,局部变量等的任何解释都是受欢迎的。

2 个答案:

答案 0 :(得分:1)

可能你可以使用像sourcify这样的gem解析源代码,取出所有的令牌,并检查是否有任何变量。但请注意,这与proc / method调用的值为常量的概念不同。例如,如果您的代码中包含Time.nowRandom.new之类的内容,则不需要定义任何变量,但每次调用时仍会有所不同。此外,当proc有envx - envx时你想要的是什么?这将保持不变,但仍然会影响代码,除非定义envx,否则它将返回错误。

答案 1 :(得分:0)

嗯,很棘手。有parameters方法可以告诉你预期的参数(注意它们是如何选择的,因为你使用的是procs,而不是lambdas)。

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

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

总的问题是:如果你想确保某些东西是纯粹的,那么为什么不把它作为一个适当的方法,让你不首先关闭环境呢?