2003-10-02 (Thu) [長年日記]
_ out/inout
引数のout/inoutモードを実装。 が、ここでやっかいな問題が。
Satherのout引数は、実引数の型が仮引数の型のスーパータイプである場合に適合する。 どういうことかというと、
abstract class $PERSON is ... end; class PROGRAMMER < $PERSON is ... end;
のようなクラスがあった場合、
set_shugo(out x: PROGRAMMER) is x := #PROGRAMMER("shugo"); end;
のようなメソッドを、
person: $PERSON; set_shugo(out person);
のように呼び出せるということだ。 (personの型がPROGRAMMERではなく$PERSONであることに注目)
問題なのは実引数がreference typeで仮引数がvalue typeであった場合だ。 たとえば、
set_one(i: INT) is i := 1; end; ... o: $OB; set_one(o);
のような場合、$OBはすべてのクラスのスーパータイプに相当するので、前述のルール で行けば、このコードに問題はない。
しかし、.NETではvalue typeをreference typeに変換するにはboxingという処理を 行う必要があり、set_one側では実引数がreference typeかどうかを知るすべがない ため、boxingすべきかどうかわからないのだ。
というわけで、とりあえずこういうケースはエラーにした。 (ちなみにC#ではoutパラメータの型は完全に一致しないとだめらしい。)
で、書いてて気付いたけど、set_fooの実装を二つ用意してoverloadを解決する時に 適切な方を選べば実現できるかもしれない。と思ったが、out引数が複数あったら 組み合わせが多くなって破綻するなあ。 まあ、どうせあんまり使わないだろうから、とりあえずこのままで行くか。
(あとで、呼び出し側でいったん別のローカル変数を渡しておいて、呼び出し後にboxing するだけでいいことに気付いた。アホすぎ。)
次はいよいよiteratorだ。
_ Subversion
Subversionを導入してみた。
<URL:http://svn.shugo.net/svn/repos/babel/>
何にも考えなくてもrepositoryをhttpで公開できるのはナイスだ。 しかし重いなあ。
そろそろちゃんとしたプロジェクト名も考えねば。