Skip to content

Instantly share code, notes, and snippets.

@umegaya
Created March 22, 2013 05:46
Show Gist options
  • Save umegaya/5219228 to your computer and use it in GitHub Desktop.
Save umegaya/5219228 to your computer and use it in GitHub Desktop.
問題:
traitクラスはmixedを継承したいが、propertyはクラス名をキーとして与えられている。
propertyを取得するのに親クラスの名前をキーとして取得しても、そのクラスは(サブクラスの名前をキーとしてプロパティを保持しているので)
正しくpropertyを取得できない。どうする?
これはもう一つの問題と関連している:
クラスのインスタンスを作る場合に、base classのtraitはそれをoverrideするtraitがクラスにmixされている場合でもmixedが呼ばれてしまうのが無駄である。
とはいえ、overrideされていないtraitが存在する場合、そのtraitのmixedは呼ばれるべきだし、うーん
アイデア:
mixする際に、mixされるクラスがそのサブクラスであるようなクラスがすでに親クラスにmixされていないかを調べる
すでにmixされていれば、そのクラスはlookupに加わる必要もないし(実際間違いなくそのクラスのメソッドがlookupされることはない)、
mixedも呼ばれないだろう
つまり、有効なmixinのリストを作り、コンストラクタ呼び出しも、lookupもそれだけを呼ぶようにできればいいかもしれない。
ただ、class.Klass.constructで親クラス分を初期化するのができなくなるのがめんどい。
classのpropertyを外から渡すのはどうか
どうやって渡すか?そもそもpropertyが必須なのはclassの実装としては美しくない
Traitの直近の子供をaspectと呼ぶことにして、クラスのmixinはaspectベースで行うようにしたらどうか。
Trait => XAspect => XTrait => XChildTrait
この場合、XTraitもXChildTraitもクラスにmixinされる場合にはXTraitというaspectを表現するものとして扱われる。つまり
class.Y.extend.Z.with.XTrait.with.XChildTrait {}
とかなった場合、YのmixinはXTrait aspectだけをもち、実装はXGrandchildTraitとなる。(XChildTraitはoverrideされて消える)
extendした場合、親クラスのmixinテーブルを継承して、さらにwithで必要なmixinを置き換えていく感じになる。
Aspectを継承しているtraitはtrait:aspect()で所属しているaspectを取得できる
なので、propertyの問題は、aspectベースでclass.__propertiesにアクセス(set/get)することで解決できそう(ここはOOPの仕様とは関係ないmrogueの実装の話)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment