ブログ記事からの転載です。
Method#=== が定義されていなくてつらい問題です。
Proc#===
Proc オブジェクトでは #call で評価することが出来ますが、そのエイリアスとして #=== が存在します。
upcase = proc { |a| a.upcase }
upcase.call "homu"
# => "HOMU"
upcase === "mami"
# => "MAMI"
これは次のように when で使用出来るようにするためです。
def sign n
case n
when proc { |n| 0 < n }
1
when proc { |n| 0 > n }
-1
else
0
end
end
sign -4 # => -1
sign 0 # => 0
sign 7 # => 1
ここで、Ruby に精通してる人なら気づくと思いますが、#method を使って proc { |n| 0 < n } を 0.method(:<) と書き直したくなります。
def sign n
case n
# #method はレシーバのメソッドをブロックオブジェクトとして返す
when 0.method(:<)
1
when 0.method(:>)
-1
else
0
end
end
しかし、これは上手く動作しません。
なぜなら #method が返す Method クラスでは #=== が定義されていないからです。
Method#=== を定義する gem をつくった
と、いうことで Method#=== を使うことが出来る gem をつくりました。
$ gem install procedureable_method
で、インストールすることが出来ます。
使い方
使い方は
require "procedureable_method"
using ProcedureableMethod
という風に refinements として使用するか
require "procedureable_method/core_ext"
として直接モンキーパッチを適用されるかします。
これで Method#=== を使用する事が出来ます。
require "procedureable_method"
using ProcedureableMethod
def sign n
case n
when 0.method(:<)
1
when 0.method(:>)
-1
else
0
end
end
sign -4 # => -1
sign 0 # => 0
sign 7 # => 1
これで無事に when に Method を渡して評価する事が出来ました。
関係ないですが when の場合はちゃんと refinements で定義したメソッドが呼ばれるんですね。
本体にも Method#=== が追加されてほしい。