Ruby中是否有直接的方法来生成Proc的副本?
我有一个叫做@foo
的Proc。我想要另一种方法来定期用额外的逻辑来增加@foo。例如:
# create initial Proc
@foo = lambda { |x| x }
# augment with more logic
@foo = lambda { |x| x > 1 ? x*x : @foo[x] }
我不希望第二行进行扩充以产生递归函数。相反,我希望@foo被值绑定到新的@foo定义的词法范围,产生一个看起来更像这样的函数:
@foo = lambda { |x| x > 1 ? x*x : lambda{ |x| x }[x] }
我得到一个无限递归和最终的堆栈溢出,因为结果函数看起来像这样:
@foo = lambda { |x| x > 1 ? x*x : lambda { |x| x > 1 ? x*x : { lambda |x| # etc...
我希望代码是这样的:
# augment with more logic
@foo = lambda { |x| x > 1 ? x*x : (@foo.clone)[x] }
但是克隆在Procs上不起作用。
此外,使用marshal和unmarshal的标准Ruby深拷贝黑客也无法在Procs上运行。有没有办法做到这一点?
答案 0 :(得分:7)
即使clone
适用于Proc
,也无济于事,因为您仍然会在clone
的新值上调用@foo
,不像你想要的那样。
您可以做的只是将@foo
的旧值存储在lambda可以关闭的局部变量中。
示例:
def augment_foo()
old_foo = @foo
@foo = lambda { |x| x > 1 ? x*x : old_foo[x] }
end
这种方式old_foo
将引用@foo
在调用augment_foo
时所拥有的值,并且所有内容都可以按您的意愿运行。