Io で Mixin

私は継承モデルに関しては Ruby の解決が今のところ一番好みです。単一継承 + Mixin。まあ別に私は多重継承で困ったことは無いので C++ でも良いんですけど。

さて、Io の継承構造だと二つまでは簡単だけど三つも四つも Mixin したいときにややこしいなあ…と思いました。で、ちょっと考えたらこの機能を簡単にライブラリ化できるこに気付き、ああいい機構だなあと感心しました。こんな感じ。

# mixiner.io

# define Mixiner

Mixiner = Object clone
Mixiner classes = List clone
Mixiner add = method(Class,
  classes add(Class)
)
Mixiner mixed = method(
  now = Object clone
  classes foreach(i, Class,
    next = Object clone
    next parent = Class clone
    next parent parent = now
    now = next
  )
  now
)

# using Mixiner

A = Object clone
A func = method(
  "A.func\n" print
)
A funcA = method(
  "funcA\n" print
)

B = Object clone
B func = method(
  "B.func\n" print
)
B funcB = method(
  "funcB\n" print
)

C = Object clone
C func = method(
  "C.func\n" print
)
C funcC = method(
  "funcC\n" print
)
C funcCD = method(
  "C.funcCD\n" print
)

D = Object clone
D funcCD = method(
  "D.funcCD\n" print
)

# D から継承
ABCD = D clone
# A, B, C を Mix するよ
abcMixiner = Mixiner clone
abcMixiner add(A)
abcMixiner add(B)
abcMixiner add(C)
ABCD parent = abcMixiner mixed

# D が直系の継承で A, B, C は Mixin
# 優先順位は D, C, B, A のはず
abcd = ABCD clone

# funcA は A にしか無い
abcd funcA
# funcB は B にしか無い
abcd funcB
# funcC は C にしか無い
abcd funcC
# func は A, B, C にあるので C が優先
abcd func
# funcCD は C, D にあるので D が優先
abcd funcCD

# おまけ。親を付け変える
# よって D が直系、A が傍系
abcd parent = A
# func は A しか無い
abcd func

まあ、variable arguments を使えばもっと短く書けるでしょうけど、とりあえずわかりやすく書いてみました。

あと言語機能は Concurrency がそれなりのサイズがあって、それと Preset Locals, Introspection (要は Reflection) なんかの細々とした便利機能を覚えればだいたい終わり…なのかな。あと例外か。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h