【问题标题】:How do I deep copy a Proc in Ruby?如何在 Ruby 中深度复制 Proc?
【发布时间】:2010-11-28 19:42:09
【问题描述】:

在 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 深拷贝 hack 也不适用于 Procs。有没有办法做到这一点?

【问题讨论】:

    标签: ruby functional-programming


    【解决方案1】:

    即使clone 可以在Procs 上工作,它也无济于事,因为你仍然会在@foo 的新值上调用clone,而不是像你想要的那样调用前一个值.

    您可以做的只是将 @foo 的旧值存储在 lambda 可以关闭的局部变量中。

    例子:

    def augment_foo()
      old_foo = @foo
      @foo = lambda { |x| x > 1 ? x*x : old_foo[x] }
    end
    

    这样old_foo 将引用@foo 在调用augment_foo 时所具有的值,并且一切都会按您的意愿工作。

    【讨论】:

      猜你喜欢
      • 2014-08-14
      • 2012-12-15
      • 2018-01-28
      • 2011-07-25
      • 1970-01-01
      • 2011-03-23
      • 2013-05-14
      • 2017-04-15
      • 2014-09-05
      相关资源
      最近更新 更多