Действительно ли возможно преобразовать proc-приправленный Proc в Proc вкусом лямбдой?
Бит удивил это, это не работает, по крайней мере, в 1.9.2:
my_proc = proc {|x| x}
my_lambda = lambda &p
my_lambda.lambda? # => false!
Этот вопрос было немного сложно отследить. Если посмотреть документацию по Proc#lambda?
для 1.9, то там есть довольно длинное обсуждение разницы между proc
s и lamdba
s.
Все сводится к тому, что lambda
обеспечивает правильное количество аргументов, а proc
- нет. Из этой документации следует, что единственный способ преобразовать proc в лямбду показан в этом примере:
define_method
всегда определяет метод без ухищрений, даже если дан объект Proc, не являющийся лямбдой. Это единственное исключение, в котором трюки не сохраняются.класс C define_method(:e, &proc {}) end C.new.e(1,2) => ArgumentError C.new.method(:e).to_proc.lambda? => true
Если вы хотите избежать загрязнения какого-либо класса, вы можете просто определить метод singleton на анонимном объекте, чтобы принудительно преобразовать proc
в lambda
:
def convert_to_lambda &block
obj = Object.new
obj.define_singleton_method(:_, &block)
return obj.method(:_).to_proc
end
p = Proc.new {}
puts p.lambda? # false
puts(convert_to_lambda(&p).lambda?) # true
puts(convert_to_lambda(&(lambda {})).lambda?) # true