[#18186] [req] Marshal — keiju@... (Keiju ISHITSUKA)

けいじゅ@日本ラショナルソフトウェアです.

14 messages 2002/09/05
[#18190] Re: [req] Marshal — matz@... (Yukihiro Matsumoto) 2002/09/05

まつもと ゆきひろです

[#18229] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

22 messages 2002/09/09
[#18230] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — nobu.nakada@... 2002/09/09

なかだです。

[#18231] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...> 2002/09/09

こんにちは、なかむら(う)です。

[#18232] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — nobu.nakada@... 2002/09/09

なかだです。

[#18233] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...> 2002/09/09

こんにちは、なかむら(う)です。

[#18234] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — WATANABE Hirofumi <eban@...> 2002/09/09

わたなべです。

[#18236] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...> 2002/09/09

こんにちは、なかむら(う)です。

[#18238] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — WATANABE Hirofumi <eban@...> 2002/09/09

わたなべです。

[#18241] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...> 2002/09/09

こんにちは、なかむら(う)です。

[#18285] rubicon on EWS4800 — Koji Arai <JCA02266@...>

新井です。

59 messages 2002/09/13
[#18322] Re: rubicon on EWS4800 — Koji Arai <JCA02266@...> 2002/09/21

新井です。

[#18333] Re: rubicon on EWS4800 — kjana@...4lab.to (YANAGAWA Kazuhisa) 2002/09/21

In message <20020921.152641.11483667.JCA02266@nifty.ne.jp>

[#18336] Re: rubicon on EWS4800 — nobu.nakada@... 2002/09/21

なかだです。

[#18337] Re: rubicon on EWS4800 — Tanaka Akira <akr@...17n.org> 2002/09/21

In article <200209211605.g8LG52p04564@sharui.nakada.kanuma.tochigi.jp>,

[#18338] Re: rubicon on EWS4800 — nobu.nakada@... 2002/09/21

なかだです。

[#18341] Re: rubicon on EWS4800 — Tanaka Akira <akr@...17n.org> 2002/09/21

In article <200209211628.g8LGSxp04786@sharui.nakada.kanuma.tochigi.jp>,

[#18342] Re: rubicon on EWS4800 — nobu.nakada@... 2002/09/21

なかだです。

[#18343] Re: rubicon on EWS4800 — Tanaka Akira <akr@...17n.org> 2002/09/21

In article <200209211739.g8LHdKp05495@sharui.nakada.kanuma.tochigi.jp>,

[#18345] Re: rubicon on EWS4800 — nobu.nakada@... 2002/09/22

なかだです。

[#18349] Re: rubicon on EWS4800 — Tanaka Akira <akr@...17n.org> 2002/09/22

In article <200209220415.g8M4Fkp24392@sharui.nakada.kanuma.tochigi.jp>,

[#18374] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here. — WATANABE Hirofumi <eban@...>

わたなべです。

20 messages 2002/09/25
[#18376] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here. — matz@... (Yukihiro Matsumoto) 2002/09/25

まつもと ゆきひろです

[#18377] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here. — nobu.nakada@... 2002/09/25

なかだです。

[#18378] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here. — WATANABE Hirofumi <eban@...> 2002/09/25

わたなべです。

[ruby-dev:18314] class nest in module_eval

From: Minero Aoki <aamine@...>
Date: 2002-09-18 08:03:28 UTC
List: ruby-dev #18314
あおきです。

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
  }

で書けます。


個人的には、定数とクラス名の挙動は同じであるほうがいいと思うの
で、「定数に揃える」に一票入れます。
-------------------------------------------------------------------
青木峰郎

In This Thread

Prev Next