Zenn
👻

[Bug #20911] #max にブロック引数を渡したときに意図しない挙動になるバグ報告

2024/11/11に公開

[Bug #20911] Array#max doesn't take block if using &:

  • 次のように #max にブロックを渡すと数値に変換した値で比較した値が返ってきます
pp ["1", "2", "3"].max { |i| i.to_i }
# => "3"
  • これが & 渡しだとうまく動かない、というバグ報告になります
# error: no implicit conversion of String into Integer (TypeError)
pp ["1", "2", "3"].max(&:to_i)
  • これなんですが #max のブロックでは2つの引数を受け取り、それを #<=> で比較した値を返して並び替える、みたいな挙動になります
  • なので以下のように比較するのが正しいコードになります
# 正しく比較する場合はこう
pp ["111", "2", "13"].max { |a, b| a.to_i <=> b.to_i }
# => "111"

# i.to_i だけだとそもそもうまく並び替えできない
pp ["3", "2", "1"].max { |i| i.to_i }
# => "1"

pp ["111", "2", "13"].max { |i| i.to_i }
# => "3"
  • また単純に to_i の値だけで並び替えしたい、のであれば #max_by が利用できます
# ブロックの戻り値で並び替えを行う
pp ["111", "2", "13"].max_by { |i| i.to_i }
# => "111"
GitHubで編集を提案

Discussion

ログインするとコメントできます