モジュールの特異メソッドをinclude先で再定義する
http://www.jitu.org/~tko/doc-jp/java-ruby/java-ruby-lang.html
モジュールで定義 された特異メソッド(クラスにおけるクラス・メソッドに相当するもの)は再定義できません。
eigenclassとmodule_evalとdefine_methodを使えばできないことはない…とつっこんでおく。
ただ、Ruby 1.8だとブロック付きのモジュールの特異メソッドは無理かも。define_methodのブロック引数に&引数を渡せないから。
RUBY_VERSION # => "1.9.0" module MyMod def self.mod_method true end def self.with_block yield*2 end def self.included(klass) (class << klass; self; end).module_eval do MyMod.methods(false).each do |meth| next if meth.to_s == 'included' define_method(meth){|*args,&block| MyMod.__send__(meth, *args, &block)} end end end end class MyClass1 include MyMod end class MyClass2 include MyMod def self.mod_method # !> method redefined; discarding old mod_method false end end MyClass1.mod_method # => true MyClass2.mod_method # => false MyMod.with_block{2} # => 4 MyClass1.with_block{2} # => 4
追記
def self.メソッド名 end
は「特異メソッド」というんだけど、まだ難しいと思うよ。クラスやモジュールやメソッドについてきちんと理解するのが先。特異メソッド…くだけて言うとオブジェクトに個性をつけるものだとイメージすればよい。枠にとらわれない人間がいるように、Rubyのオブジェクトでも枠にとらわれないオブジェクトがあるという話。
「true」は実行というか式。Rubyは最後に評価(実行)した式が返り値になるからこの場合は返り値になる。
追記
モジュールメソッドをクラスに継承させる, primeについて その2, MathMLライブラリ0.8.1を公開しました, お詫び - 忘れたときに備えた記録(2008-03-23)
トラックバックありがとう。実は上のコードは原文を元にしたやつなので煩雑(^^;
だったらいっそのことextend selfしようよ!
module Mod extend self def hoge "HOGE" end def self.included(klass) klass.extend(self) end end class C include Mod end Mod.hoge # => "HOGE" C.hoge # => "HOGE"