From: keiju@... (=?ISO-2022-JP?B?GyRCQFBETTc9PHkbKEI=?= ) Date: 1997-07-29T16:15:54+09:00 Subject: [ruby-dev:15] Re: [Problem] for local class けいじゅ@今はフリー(^^;;;です. In [ruby-dev :00012 ] the message: "[ruby-dev:12] Re: [Problem] for local class ", on Jul/29 11:49(JST) matz@netlab.co.jp (Yukihiro Matsumoto) writes: >|# そういえば松本氏もだね. >厳密にいうと私は今月フリーだったわけではなくて有給使って休ん >でいただけです.長い休みが今週で終ってしまうのは事実ですけど. そうかぁ... いいなあ... ># で,引っ越しの荷物はまだ片付いていないのだ. # 私のところも, 引っ越して1年以上になるのにまだ完全には片付いていない... >|# ただ, Subjectが... Re:がいっぱい(;_; >[ruby-list:xxxx]を削ってくれないからですね.両方にまたがる時 >には手動で削るしかないですね. ですね. >|さらに, rubyの場合は, トーカルクラスコンテキストとサブクラスコンテクス >|トが両方ともこういう感じになっていますよね. つまり: > >トーカルってなに? ローカルの間違いでした. class Foo Baz = "baz" class Bar Baz = "baz" end end みたいな感じ. >rubyの定数スコープのルールは結構変わっていて, > > * 自クラスで定義された定数があればそれ > * 外のスコープ(自分を囲むmoduleまたはclass)で定義された定 > 数があればそれ > * 自分の先祖(またはincludeされたモジュール)を優先順位順に > 検索して,どこかで定義されていればそれ > * いずれにしても値はできるだけ静的に決定する > >という風になっています. 2番めと3番めとで2重になっているところがミソですね. >既に書きましたが, > > * サブクラスでスーパークラスの定数を置き換えることを認める > かどうか > >ということをまず決めたいです.現状では(-wオプションが指定さ >れている時には)警告を発生するものの置き換えは出来るようになっ >ています.今回,つらつらと考える限り,置き換えることに対する >不都合はあまりないようなので,警告も発しなくてよい(正当な操 >作と認める)で,よいように思えて来ました. 静的に決定するようになっているところが味噌ですね. class Foo GV = "Foo" def foo print GV end end class Bar < Foo GV = "Bar" end Foo.new.foo Bar.new.foo ================== FooFoo となり, サブクラスで値が変えたとしても動作は変わらない. ですし, 逆にも し動的にしたければ: class Foo GV = "Foo" def foo print eval(self.type)::GV # もうすぐ, print self.type::GV end end class Bar < Foo GV = "Bar" end Foo.new.foo Bar.new.foo ================== FooBar で, できますしね. 良くできていると思った覚えがあります. >次に,クラスの再定義の挙動を定義する必要があります.これも石 >塚さんのおっしゃるように定数の挙動に合わせても良いような気が >して来ています. 一応定数ですしね. >それは別に > > * なんらかの方法で定数の値が動的に変更された時(eval/定数定 > 義API/includeなど),どのように挙動すべきか > >という点を定義する必要があります.実は現在のrubyは定数の値は >変更されないものと思って,一度評価するとその定数値を構文木に >取り込んでしまいます.つまり,現在の実装では定数の値が動的に >変更されてしまうと,実行順によって定数の値が異なってしまう場 >合があるというわけですね.これは多分まずい挙動なので,適切な >動作をきちんと定義しないといけないでしょう. ん? そうすると, class Foo GV = "Foo" end class Bar < Foo def foo print GV end def bar print GV end end Bar.new.foo class Bar GV = "Bar" end Bar.new.foo Bar.new.bar ================== FooFooBar になるんだ... # どれどれ, 確かめてみる... たしかになる... おおおお, 動作が変だ... # Foo#foo, Foo#barは同じコードだけど結果が違ってくる... 定数の値の決定(構文木への埋め込み)はdefの時に行われているんではなくて, 最初に実行した時に行われているんですね? 定数の値の決定法としては: 1. def時に静的に決定してしまう 2. 最初の実行時に決定する. 3. 関数を呼び出す度に値を決定する. の3種類があると思いますが, どれがいいんでしょうかね?? (3)だとオブジェ クトが毎回変わる可能性があって, 定数というイメージからずれているし... (1)はある意味ではっきりしているからいいんだけど, 使いづらくなるし... (2)は, 上記の例のように変なことが出てくるし... # この問題って意外と面倒だったんですね... >|>Object::Fooじゃだめ? >|# ただ, (同名ローカルクラスが許されたとして)ローカルクラスでObjectがあ >|# ると困るかな... Objectだけは, 再定義しちゃ駄目といえば済むかな... >それは自業自得ということで. (^^;;; __ .........................................石塚 圭樹@今はフリー(^^;;... ------->>また, アドレス変わりました!! e-mail: keiju@bc.mbn.or.jp <<---