Ruby の Method#=== が定義されていないのでつらい問題
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#===
が追加されてほしい。