けいじゅ@日本ラショナルソフトウェアです.

In [ruby-list:35630] the message: "[ruby-list:35630] Re: new mathn
[Re: Rational#to_int ← String#center]", on Jul/25 02:46(JST) Yukihiro
Matsumoto writes:

>まつもと ゆきひろです

>|静的スコープならselector name spaceではないかと思うのですが? 違うのか
>|な?
>
>たぶん。でも本当になにが必要とされているかは結論が出てないと
>思います。そもそもselector namespaceがどのようなものなのかさ
>え決まってない(決めていない)のが現実なので。

以前は, ruby-talkで議論があったんだよね?

>|静的スコープと動的スコープのどちらがよいかは, 使い方によるんでしょうね.
>
>ですね。静的なほうが嬉しいことが多いでしょうけど(影響範囲が
>限定されて挙動が予想しやすいので)。

静的のほうは見てわかりますからね. 

>|scope-in-stateの方は, 状態自身をスレッドに持たせその状態に応じて, クラ
>|スの定義を変えようってものになっています. ただ, 自由に変えるのは不可能
>|なんで, 見た感じとしては状態に応じてincludeされているモジュールを入れ
>|替えてそのモジュールで定義されているメソッドが有効になるようになってい
>|ます.
>
>これそのものは面白い考えですよね。整理して取り込みましょうよ。

では, 今の考え方を紹介します. 

まず, ベースのクラスを定義します:

class Foo
  def foo
    p "Foo"
  end
end

class Bar
  def bar
    p "Bar"
  end
end

さらに状態に応じて変更する部分を以下のように定義します.

module S
  module Foo
    def foo
      p "S"
    end
  end

  module Bar
    def foo
      p "S"
    end
  end
end

モジュールSは状態を表しているつもりです.  ここで, S::FooはFooに追加さ
れるモジュール, S::BarはBarに追加されるモジュールです. 一度に複数のク
ラスの振る舞いを変えることができないと意味がないので, こんな感じになり
ました. 上記の場合 S::Mod1::Mod2::Mod3は Sを取ったもの, つまり
Mod1::Mod2::Mod3に追加されます.

次に状態スコープを定義します.

ScopeS = ScopeInState.new(S)

定義はここまでです.

使い方は, 簡単:

通常は, ベースのクラスの振る舞いになります:
>> Foo.new.foo
"Foo"
>> Bar.new.foo
NameError: NameError: undefined local variable or method `foo' for #<Bar:0x401dd6fc>

で, ScopeSを指定すると, 以下のようにmodule Sで定義された振る舞いに変わ
ります.

# こっちは変更
>> ScopeS.scope_in do
?>  Foo.new.foo
>> end
"S"

# こっちは追加
>> ScopeS.scope_in do
?>  Bar.new.foo
>> end
"S"

だいたいこんな感じです. 気になる点としては,

1. 上記のような単純な場合はわかりやすいが, ベースのクラスが継承したり
   includeしていたりすると, どう動作するのか想像しがたい.
2. 状態スコープのネスティングができるようになっているが, そのため実装
   が複雑&&実行コストがかかっている
3. メソッドの追加はできるがundefができない.

1.は, 状態スコープで定義されたものが優先されるはずです. 概念的にはベー
スクラスで定義されたメソッドを状態に応じて変えるので, ベースクラスのメ
ソッドと同レベルと判断したからです.
2.は非常に気にはなっているのですが... 
3.は特別なメソッドを用意するしかないかなと思っています.

あ. あと, ソースはRAAに登録されています. まだ, エラー処理も何もないの
でいい加減ですが...

__
..............................石塚 圭樹@日本ラショナルソフトウェア...
----------------------------------->> e-mail: keiju / rational.com <<---