なかだです。

At Mon, 11 Aug 2003 14:46:00 +0900,
Takeshi Horinouchi wrote:
> 
> 堀之内と申します。
> 
> モジュールをネストして module_function を継承(のようなことを)
> することはできるでしょうか。具体的には、モジュールに入れたアルゴ
> リズム(メソッド群)を取り替えやすくするため、以下のようなことを
> したいのですが、うまくいきません。使用しているのは ruby 1.6.8 で
> す。同様のことをするのに別の方法があるよとか、1.6 ではだめだけど 
> 1.8 ならできるといった情報でも結構です。(まだしばらく1.6は切り
> 捨てたくないので困りはしますが。。。)

module_functionは、インスタンスメソッドをメタクラスにコピーして
元のインスタンスメソッドはprivateにします。

> module Foo
>   module_function
>   def hi;  "hi";  end
>   def there;  "there";   end
> end
> module Bar
>   module_function
>   extend Foo
>   def hi;  'HI';  end
> end

ここでextendは、Barのメタクラス(カッコをつけて(Bar)と表記)にモ
ジュールFooをincludeするので、(Bar)にインスタンスメソッドhiと
thereが追加されます。つまり、Bar自身の特異メソッドとして追加さ
れるのはprivateであるFoo#hiとFoo#thereであって、publicであるク
ラスメソッドFoo.hiやFoo.thereではありません。

ということで、extendしてからpublic_class_method :thereとすれば
アクセスできるようになります。

> プライベートメソッドというわりには、Bar.private_instance_methods
> の結果に含まれない(上記の実行結果1行目)のが腑に落ちません。

@@algorithm::thereというのは@@algorithmのクラスメソッドの呼び出
しですから、private_instance_methodsには含まれません。

> なお、module Bar において extend でなく include にしてもだめです。
> 
> /.../nested_modules2.rb:18:in `there': undefined method `there' 
> for Bar:Module (NameError)
>         from /.../nested_modules2.rb:26

スーパークラスのクラスメソッドが継承されるように、includeされた
モジュールのクラスメソッドも継承されるべき、ということでしょう
か。

-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦