[#18151] Regexp.last_match — WATANABE Tetsuya <llama@...01.gate01.com>
渡辺哲也です。
[#18186] [req] Marshal — keiju@... (Keiju ISHITSUKA)
けいじゅ@日本ラショナルソフトウェアです.
まつもと ゆきひろです
新井です。
まつもと ゆきひろです
In article <1031498274.659939.18144.nullmailer@picachu.netlab.jp>,
まつもと ゆきひろです
In article <1032189662.175916.22019.nullmailer@picachu.netlab.jp>,
[#18208] Re: [ruby-list:35875] Unsecure world writeabledir の警告 — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
わたなべです。
[#18229] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
なかだです。
こんにちは、なかむら(う)です。
なかだです。
こんにちは、なかむら(う)です。
わたなべです。
わたなべです。
こんにちは、なかむら(う)です。
わたなべです。
こんにちは、なかむら(う)です。
なかだです。
こんにちは、なかむら(う)です。
こんにちは、なかむら(う)です。
わたなべです。
[#18246] Re: missing/vsnprintf.c: printf("%+f", -0.0) — WATANABE Hirofumi <eban@...>
わたなべです。
At Tue, 10 Sep 2002 12:21:10 +0900,
[#18262] mswin32: EINVAL on Process.kill — Minero Aoki <aamine@...>
あおきです。
[#18274] $0 handling on DOSISH — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
なかだです。
岩月と申します。
なかだです。
こんにちは、なかむら(う)です。
なかだです。
こんにちは、なかむら(う)です。
[#18285] rubicon on EWS4800 — Koji Arai <JCA02266@...>
新井です。
新井です。
まつもと ゆきひろです
新井です。
まつもと ゆきひろです
新井です。
なかだです。
In message <20020921.152641.11483667.JCA02266@nifty.ne.jp>
なかだです。
In article <200209211605.g8LG52p04564@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <200209211628.g8LGSxp04786@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <200209211739.g8LHdKp05495@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <200209220415.g8M4Fkp24392@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <200209260105.g8Q15PR08171@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <20020921.152641.11483667.JCA02266@nifty.ne.jp>,
なかだです。
In article <200209251737.g8PHbdR03024@sharui.nakada.kanuma.tochigi.jp>,
渡辺哲也です。
なかだです。
渡辺哲也です。
渡辺哲也です。
なかだです。
渡辺哲也です。
なかだです。
In article <200210020254.g922srH01700@sharui.nakada.kanuma.tochigi.jp>,
[#18314] class nest in module_eval — Minero Aoki <aamine@...>
あおきです。
[#18361] compile parse.y with -Wall — nobu.nakada@...
なかだです。
なかだです。
[#18371] Re: [ruby-cvs] ruby/lib/uri: * eval.c (ruby_run): should set toplevel visibility again here. — Kazuhiro NISHIYAMA <zn@...>
西山和広です。
[#18374] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here. — WATANABE Hirofumi <eban@...>
わたなべです。
まつもと ゆきひろです
なかだです。
わたなべです。
いがらしです。少し前の話ですが。
わたなべです。
なかだです。
まつもと ゆきひろです
なかだです。
まつもと ゆきひろです
[#18391] pstore.rb can make a broken store — YANAGAWA Kazuhisa <kjana@...4lab.to>
# お願いされたから書いてみよう :-)
In article <20020926134339.C8DAE1EE12@milestones.dm4lab.to>,
[ruby-dev:18314] class nest in module_eval
あおきです。
CVS 最新で次のような挙動が起こります。
[テスト1]
~/t/rhg % cat t
class A
class B
class T
puts "A::B::T = #{self.id}"
end
::A.module_eval {
class T # A::B::T を上書き定義する
puts "A::B/A::T = #{self.id}"
end
}
end
end
puts "A::B::T = #{A::B::T.name} (#{A::B::T.id})"
~/t/rhg % ruby t
A::B::T = 359000264
t:8: warning: already initialized constant T
A::B/A::T = 359000184
A::B::T = A::T (359000184)
# A::T は undefined const
[テスト2]
~/t/rhg % cat t2
class A
class T
puts "A::T = #{self.id}"
end
class B
class T
puts "A::B::T = #{self.id}"
end
::A.module_eval {
class T # こちらは A::T に追加定義する
puts "A::B/A::T = #{self.id}"
end
}
end
end
puts "A::T = #{A::T.name} (#{A::T.id})"
puts "A::B::T = #{A::B::T.name} (#{A::B::T.id})"
~/t/rhg % ruby t2
A::T = 358999854
A::B::T = 358999744
A::B/A::T = 358999854
A::T = A::T (358999854)
A::B::T = A::B::T (358999744)
つまり、
1. A::T が定義されているかどうかで module_eval 中に
定義したクラスのネスト先が変わる
2. 上書きするか追加定義するかの違いがある
3. テスト 1 で、実際には A::B::T であるクラスの名前
が A::T になる
というあたりが変なわけです。3. については純粋にバグだったよう
なので、残る 1. 2. がこれでいいのか、変えるとしたらどう変える
のか考えないといけません。
[考察]
そもそもこういう挙動になる原因は、rb_eval:NODE_CLASS で定義チェッ
クに ruby_class を使い、ruby_cbase に定義していることです。こ
の二つの意味の違いはこうです。
ruby_class .... メソッドを定義する対象のクラス
ruby_cbase .... 定数参照・代入の起点
この二つは通常は同じ値なのですが、module_eval 中では
ruby_class = module_eval のレシーバ
ruby_cbase = 変わらず
になります。それでこの二つが違う値になっていると変な動作になる
わけです。だからたぶん少なくとも ruby_class とruby_cbase、使う
のはどちらかにすべきなんだろうと思います。
あとはネスト先を ruby_class と ruby_cbase のどちらに統一
すべきか、という問題です。具体的に言うと、
module M
end
class C
M.module_eval {
class SomeClass
end
}
end
としたときに、SomeClass は C と M のどちらにネストして定義され
るべきなのか、ということです。M に定義されるなら ruby_class、
C に定義されるなら ruby_cbase を使うことになります。
ちなみに、1.6 までは M に定義されるようになっていました。
だからこんなこともできました。
# net/protocol.rb より
def net_private( &block )
::Net::NetPrivate.module_eval(&block)
end
net_private {
class SMTPCommand # Net::NetPrivate::SMTPCommand
end
}
しかし 1.7 になってからは「定数の挙動は静的であるべき」という
方針でこういうことはできないようにする方向に動いています。その
流れから言うと全部 ruby_cbase にするべきなんでしょう。
しかしクラス定義だけはちょっと違うのだ、というのもそれはそれで
納得できるものがあります。特にこの場合は module_eval したうえ
でのクラス定義文ですから、やや特殊な状況です。例えばなんらかの
コードの中で動的にクラスを定義しようとしたときに、ネストする先
が動的に変更できないと
M.const_set :ClassName, Class.new {.....}
などとするしか方法がなくなります。module_evalでネスト先を変え
られれば
M.module_eval {
class ClassName
....
end
}
で書けます。
個人的には、定数とクラス名の挙動は同じであるほうがいいと思うの
で、「定数に揃える」に一票入れます。
-------------------------------------------------------------------
青木峰郎