From: EGUCHI Osamu Date: 1997-09-19T14:42:46+09:00 Subject: [ruby-list:4440] Re: invalid index of Array えぐち です。 > まつもと ゆきひろです > | + 配列の添字に負数を使ったとき > | 最大の添字を持つ要素を [-1] で参照できるんですが、 > | これで正しいのでしょうか? > > はい.添字が負の場合には後ろから数えた要素に参照できます. 面白い仕組みですね。 > | + 'Fixnum[添字]' はエラーでないんですか? > > obj[idx]は`[]'という名前のメソッドを起動しているのですが, > Fixnum#[]というメソッドも定義されていてn番目のbitがセットさ > れているかどうかを返します. なるほど なるほど、でも左辺値ではないんですね、 > | + 配列の要素に配列自身を代入すると、、 > | 代入式自体は実行できるようですが、そのオブジェクトに > | さわるとインタプリタが落ちます。 > > 再帰的な配列を作る事そのものには問題は無いのですが,現在の > to_sやinspectの実装では文字列化の時点で無限ループに落ちてし > まうので,出力できません.これを解決する(コストの安い)良い方 > 法があれば知りたいんですけど. > まつもと ゆきひろ /:|) + ソフトウェアスタックを作る。 or + オブジェクトに「マーク」する。 のような判別方法はとっさに考え付きました。 Array#inspect にパッチしてみました。マーク法です。 --- ../ruby-1.0-970911/array.c Wed Sep 3 17:32:12 1997 +++ array.c Fri Sep 19 14:31:01 1997 @@ -632,6 +632,8 @@ VALUE s, str; if (ary->len == 0) return str_new2("[]"); + if (FL_TEST(ary, FL_USER5)) return str_new2("{recursive}"); + FL_SET(ary, FL_USER5); str = str_new2("["); len = 1; @@ -643,6 +645,7 @@ } str_cat(str, "]", 1); + FL_UNSET(ary, FL_USER5); return str; } ---結果--- aptiva0.eguchi:41% cat p.rb a=[0,1] a[1]=a print "1\n"; b=a; print "2\n"; print a.inspect, "\n" b=[0,a] print b.inspect, "\n" print a, "\n" aptiva0.eguchi:42% ./ruby p.rb 1 2 [0, {recursive}] [0, [0, {recursive}]] p.rb:10:in `to_s': fatal: stack level too deep from p.rb:10:in `print' from p.rb:10 0aptiva0.eguchi:43% ---------- eval でもマークすればわかると思います。 コストが高いか低いかは意見の別れるところです。 また `{recursive}' は取ってつけたような表現ですね。 # [] != nil な理由がわかりました。 # 再帰的オブジェクトが参照されなくなってGCに掛かると 恐くないですか? 、、そもそも参照は0にならないか、、自分でしてるから