🗂

Ruby でメソッドに &nil を渡すとどうなる?

2024/02/25に公開

Ruby では通常メソッドに &obj を渡すと内部で obj.to_proc が呼ばれ、その結果がメソッドのブロック引数として渡されます。

# :upcase.to_proc の結果が #map のブロック引数として渡される
pp %w(homu mami mado).map(&:upcase)
# => ["HOMU", "MAMI", "MADO"]

なので #to_proc が定義されていないオブジェクトを & 引数で渡そうとするとエラーになります。

# "upcase".to_proc というメソッドは定義されていないのでエラーになる
# error: wrong argument type String (expected Proc) (TypeError)
pp %w(homu mami mado).map(&"upcase")

&nil を渡すとどうなる?

ブロック引数として &nil を渡した場合はどうなるんでしょうか。
試してみました。

def func(&block)
  pp block          # => nil
  pp block_given?   # => false
end

func &nil

と、言う感じでブロック引数にはなにもわたってきてないような挙動になっています。
では nil.to_proc がそういう値を返しているのかというとそもそも #to_proc メソッド自体定義されていません。

# error: undefined method `to_proc' for nil:NilClass (NoMethodError)
nil.to_proc

まあこういう仕様になっているんですかねー。
なので、次のようにブロック引数を渡しているっぽいコードでも実は渡されておらずに Enumerator を返すことがあります。

block = nil

pp %w(homu mami mado).map(&block)
# => #<Enumerator: ...>
GitHubで編集を提案

Discussion