Ruby

Method#===に引っかかった

More than 3 years have passed since last update.

caseの条件にProcを渡すのが格好いいと思い、次のようなコードを書いた。

x = 0.9

case x
when 1.method(:>) then "less than 1"
when 1...10 then "more than 1 and less than 10"
when 10.method(:<=) then "more than 10"
end

"less than 1"が返ってくることを期待していたが、実際にはnilが返る。

何故か。

caseが条件を判定するときは、条件に渡されたオブジェクトの===メソッドにxが渡されて判定される。

Proc#===Proc#callのエイリアスなので、真偽を返すProcを条件に渡すというのはよく利用されている。

で、同じノリで1.method(:>)を渡したらいいかんじじゃね?と思ったけれど、Object#methodで返ってくるのはProcではなくMethod

そしてMethod#===Procとは違い、Method#callのエイリアスではない。

(Method#===は定義されておらず、Object#===が呼び出される。)

よって上記のコード場合は#<Method: Fixnum#>>0.9が比較されているだけで、当然ながら結果はfalse

これを踏まえて上記のコードを修正すると

x = 0.9

case x
when 1.method(:>).to_proc then "less than 1"
when :<.to_proc.curry(2)[1] then "カレーは飲み物"
when 1...10 then "more than 1 and less than 10"
when 10.method(:<=).to_proc then "more than 10"
end

めっちゃ冗長 :<