[Gauche-devel-jp] Re: [Q] gauche.array

アーカイブの一覧に戻る

Shiro Kawai shiro****@lava*****
2004年 11月 22日 (月) 19:31:11 JST


わかりました。これは結構深い問題で、根本的に直すにはwrite-objectの
プロトコルを変えないとだめです。(もともとやばいことはわかっていたので、
いずれ直さないとならないんですが)。

とりあえず、今回の問題だけ対症的にfixするのは以下のパッチでOKです。

diff -u -r1.13 array.scm
--- ext/uvector/array.scm	13 Sep 2004 20:22:50 -0000	1.13
+++ ext/uvector/array.scm	22 Nov 2004 10:18:11 -0000
@@ -76,7 +76,7 @@
       (define-method write-object ((self class) port)
         (format port "#,(~A ~S" name (array->list (array-shape self)))
         (array-for-each (cut format port " ~S" <>) self)
-        (display ")" port))
+        (format port ")"))
       (define-reader-ctor name
         (lambda (sh . inits)
           (list-fill-array! (make-array-internal class (apply shape sh)) inits))))))


根本的な問題は、shared structureを表示するためにwrite/ssが2回
ツリーをたどらなければならないところにあります。1回目で共有構造を
見つけて、2回目で実際に書き出します。

ところが、ユーザ定義のwrite-objectメソッドがある場合、オブジェクト
のどの構造がwrite時に辿られるかがわかりません。そこで、write/ssは
まずダミーのportを作成してwrite-objectを呼びます。このダミーの
ポートは実際の出力は行わず、そこに出力されたオブジェクトの共有構造の
チェックだけを行います。で、2パス目に本当の出力ポートを使って
write-objectを再び呼び出します。

今回問題が発生したのは、閉じ括弧を出力する (display ")" port) でした。
1パス目のダミーポートから見ると、これは毎回同一の(eq?な)文字列 ")" が
出力されてくることになるので、それを共有構造と考えてしまったのです。
write-object中で同じようなコードを使っているところはどこでも同じ
問題が発生します。

今のところ考えている解決策は、ユーザ定義のwrite-objectに余分な引数
contextを渡して行くようにして、write-object側でそれが1パス目なのか
2パス目なのかを判断するようにする、というものです。多分互換性を保つ
ためにメソッド名もobject-writeかなんかに変えるでしょう。

--shiro




Gauche-devel-jp メーリングリストの案内
アーカイブの一覧に戻る