kubo39's blog

ただの雑記です。

Crystalでクロージャを呼ぶ

CrystalのProcは関数ポインタとクロージャに対する参照の組になっている。

クロージャへの参照はCallableなので、

def closure(x : ( -> Nil))
  fp = pointerof(x)
  p "fp: #{fp}"  # pointer to function

  clsr = fp + sizeof(Pointer(Int8))  # See Internal
  p "closure: #{clsr}"               # pointer to closure
  p "closure.value: #{clsr.value}"   # inside of closure

  p fp.class
  p fp.value.class

  p clsr.class 
  p clsr.value.class

  fp.value.call
  clsr.value.call
end

closure(-> { puts "Hello" })
  • 実行結果:
$ crystal -v
Crystal 0.7.7 [170f859] (Sat Sep  5 02:53:51 UTC 2015)
$ crystal closure.cr 
"fp: Pointer(( -> Nil))@0x7ffe4d54d2c8"
"closure: Pointer(( -> Nil))@0x7ffe4d54d348"
"closure.value: #<( -> Nil):0xffffffffffffffff:closure>"
Pointer(( -> Nil))
( -> Nil)
Pointer(( -> Nil))
( -> Nil)
Hello
Program exited because of a segmentation fault: 11