2013-10-01 2 views
7

Мне интересно, можно ли передать блок в Proc. Просто проходя блок Proc.call не работает:Могу ли я передать блок Proc?

foo = Proc.new { 
    yield 
} 

foo.call { 
    puts "test" 
} 

Результаты в:

LocalJumpError: no block given (yield)

То же самое происходит с лямбды. Однако это делает работу с объектами метод:

class Foo 
    def bar 
    yield 
    end 
end 

bar = Foo.new.method :bar 

bar.call { puts "Success!" } 

Результаты в:

Success!

Странным является то, что она все еще работает после преобразования объекта метода в процедурный:

bar.to_proc.call { puts "Success!" } 

Результаты:

Success!

Так почему же Proc, который был сделан из блока, не принимает блоки, но Proc, который изначально был методом? Можно ли создавать Procs из блоков, которые принимают блоки?

+1

Возможный дубликат [Можно ли оценить блок внутри Proc?] (Http://stackoverflow.com/questions/17818160/can-i-evaluate-a-block-inside-a-proc) –

+0

Все еще открыт связанный с этим вопрос: могут ли методы, которые создаются из блоков, которые дают? –

ответ

5

Procs не может принимать блоки как неявные аргументы (формат, который вы пытаетесь). A proc может принимать другие объекты proc как аргументы, явно или используя аргументы &. Пример:

a = Proc.new do |&block| 
    block.call 
end 

a.call() {puts "hi"} 

yield это немного laguage магии уровня, который работает только в контексте метода.

+2

Вы имеете в виду, что * blocks * не может принимать другие блоки как неявные аргументы? Потому что, как я показал в своем вопросе, procs * может *, если они были преобразованы в procs из методов. – Hubro

+0

@Codemonkey: Я уверен, что слишком proc создает аргумент &. – Linuxios

+0

Хмм интересно. Очень полезно, спасибо! –

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