Crystal はブロックがエラーになることがあってつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の23日目の記事です。

qiita.com

メソッドに渡されたブロックを実行するには次の2つの方法があります。

def hoge
  yield
end
hoge{ p 123 }
def hoge(&block)
  block.call
end
hoge{ p 123 }

ですが、引数があるブロックの場合は後者はエラーになります。

def hoge
  yield 123
end
hoge{ |x| p x }  # これはOK
def hoge(&block)
  block.call 123
end
hoge{ |x| p x }  #=> wrong number of block arguments (1 for 0)

次のように引数の型を指定すると動作します。

def hoge(&block : Int32 -> _)
  block.call 123
end
hoge{ |x| p x }

あと、block.call の場合はブロック内で break するとエラーになります。

def hoge(&block)
  block.call
end
hoge{ break }  #=> Invalid break

つらい…