モジュールの特異メソッドを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"