2010-11-28 2 views
8

Есть ли простой способ в Ruby создать копию Proc?Как я могу скопировать Proc в Ruby?

У меня есть Proc, называемый @foo. Я хочу, чтобы другой метод периодически дополнял @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.

Кроме того, стандартный рубиновый рубиновый рубинг с использованием маршала и без маршала также не работает на Procs. Есть ли способ сделать это?

ответ

7

Даже если clone будет работать на Proc с, это не поможет вам, потому что вы все еще называть clone на новое значение @foo, а не на предыдущий, как вы хотите.

Вместо этого вы можете сохранить старое значение @foo в локальной переменной, которую может закрыть лямбда.

Пример:

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

Таким образом old_foo будет ссылаться на значение, которое @foo было, когда augment_foo называли, и все будет работать, как вы хотите.

Смежные вопросы