演算代入演算子の再定義
a += b;
とは
a = a.op_add_assign(b);
のシンタックスシュガーです。よって、 += 演算子をオーバーロードしたいクラスにop_add_assignメソッドを定義すれぱOKとなります。
aがimmutableなオブジェクトの場合、op_add_assignはop_addと同じ関数となるでしょう。
しかし、aがmutableなオブジェクトであるなら、実行効率のために、それを直接変更する実装である可能性があります。
たとえば、配列の連結代入演算子 (~=) は左辺のオブジェクトに直接連結します。
i: 0; j: i; i += 10; i.p; //=> 10 j.p; //=> 0 a: []; b: a; a ~= [10]; a.p; //=> [10] b.p; //=> [10]
2次元のベクトルクラスの簡単なサンプル
Vec2D: class{ + _x; + _y; initialize: method(_x: 0, _y: 0){} length: method(){ return math::sqrt(_x*_x + _y*_y); } normalize: method(){ op_div_assign(length()); } op_add: method(v){ return Vec2D(_x+v.x, _y+v.y); } op_sub: method(v){ return Vec2D(_x-v.x, _y-v.y); } op_mul: method(v){ return Vec2D(_x*v, _y*v); } op_div: method(v){ return Vec2D(_x/v, _y/v); } op_add_assign: method(v){ _x += v.x; _y += v.y; return this; } op_sub_assign: method(v){ _x -= v.x; _y -= v.y; return this; } op_mul_assign: method(v){ _x *= v; _y *= v; return this; } op_div_assign: method(v){ _x /= v; _y /= v; return this; } to_s: method(){ return %f(Vec2D(x: %g, y: %g))(_x, _y); } } v: Vec2D(x: 5, y: 10); u: v; v = v + Vec2D(7, 9); v.p; //=> Vec2D(x: 12, y: 19) u.p; //=> Vec2D(x: 5, y: 10) u = v; v *= 5; v.p; //=> Vec2D(x: 60, y: 95) u.p; //=> Vec2D(x: 60, y: 95)