ブログ記事からの転載です。
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#===
が追加されてほしい。