ruby でクラスメソッドを委譲する方法
方法
SingleForwardable を使う
require 'forwardable' class MyFile extend SingleForwardable def_delegator File, :join end MyFile.join('hoge', 'fuga') #=> "hoge/fuga"
MyFile のクラスメソッドとして File#join っぽい挙動をするメソッドを委譲
別のやり方
クラスメソッドを委譲する方法をもう一つ。 なんと1行で書けます。(require 入れて2行だけど)
require 'delegate' SimpleDelegator.new(File).class_eval { class MyFile2 < self; end } MyFile2.join('hoge', 'fuga') #=> "hoge/fuga"
ここまで書いておいてアレだけど、クラスメソッドは特異メソッドなので、それを委譲してしまうのは、きっと良くない兆候。
どうしてかというと「特異メソッド」というのは、そのオブジェクト固有のメソッドを意味するので、委譲して他のクラスでも使えてしまう、というのは如何なものか、と思うわけですよ。
それって特異じゃないやん!っと。
ちょっと黒魔術っぽいですが、色々できますねーというお話。
おまけ
インスタンスメソッドを委譲したいとき
完全に別の話題だけども、クラスメソッドじゃなくて、インスタンスメソッドを委譲したい場合は以下の3パターンを使い分けると良い。
- extend Forwardable
- def_delegator, def_delegators で委譲したいものを必要なだけ定義する
- DelegateClass(klass) を継承させる
- 全部のインスタンスメソッドが委譲されて、不要なものは undef や オーバーライドで消していく
- SimpleDelegate で必要な変数だけピンポイントで委譲させる