RubyのProcは「関数」としてブロックを取れるか?

結論。驚くべきことに、Procオブジェクトは「関数」と見做してブロックを取るような使い方ができる。

foo = ->(&bk){
  bk.call.upcase
}

puts foo.() { "nyao" }    #=>NYAO

 
さらに、enum_forto_enumを使ってメソッドを Enumerator化することができるように、ブロックを取る ProcオブジェクトもEnumerator::Yielder#to_procを使って Enumerator化することができる。

def foo
  (1..10).each { yield(_1) }
end

enum_for(:foo).map { _1 * 2 }
#=>[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

foo = ->(&bk){
  (1..10).each { bk.call(_1) }
}

Enumerator.new { |y| foo.(&y) }.map { _1 * 2 }
#=>[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]