インスタンスが属するクラスをあとから変更する操作を Io で


動的なプロトタイプベース言語の特徴として、Io は他の言語の class スロットにあたる protos スロット(移譲先を収めた特殊なスロット)の内容を自由に変更可能なので、できて当たり前ですね。^^; ただここではその機能は使わずに、become を見つけたのが嬉しかったので、まずは Smalltalk の #become: を使うのと似た方法で書いてみました。

PI := 3.141592653589793

Cartesian := Object clone do(
  x := 0;
  y := 0;
  asPolar := method(
    newPol := Polar clone;
    newPol r = (x*x + y*y) sqrt;
    newPol theta = y atan2(x);
    newPol
  )
)

Polar := Object clone do(
  r := 0;
  theta := 0;
  asCartesian := method(
    newCart := Cartesian clone;
    newCart x := r * theta cos;
    newCart y = r * theta sin;
    newCart
  )
)

pos1 := pos2 := Polar clone do( r = 2 sqrt; theta = PI / 4 )
pos1 type   #=> Polar

pos1 become(pos1 asCartesian)
pos1 type   #=> Cartesian
pos1 x      #=> 1.0000000000000002
pos1 y      #=> 1
pos2 type   #=> Cartesian

pos1 become(pos1 asPolar)
pos1 type   #=> Polar
pos1 r      #=> 1.4142135623730951
pos1 theta / PI   #=> 0.25