From: nobu.nakada@... Date: 2001-12-19T13:38:34+09:00 Subject: [ruby-dev:15500] Re: define_method() does not properly set noex (PR#218) なかだです。 At Wed, 19 Dec 2001 12:47:04 +0900 (JST), pbranna@clemson.edu wrote: > If I write this: > > class Foo > private > define_method :foo, proc { } > def bar; end > end > > f = Foo.new > f.foo > f.bar > > Then I get this (Ruby 1.6.5): > > defmeth.rb:9: private method `bar' called for # (NameError) > > However, I would expect to get this: > > defmeth.rb:8: private method `foo' called for # (NameError) > > The problem seems to be in rb_mod_define_method: > > if (RDATA(body)->dmark == (RUBY_DATA_FUNC)bm_mark) { > rb_add_method(mod, id, NEW_DMETHOD(method_unbind(body)), NOEX_PUBLIC); > } > else if (RDATA(body)->dmark == (RUBY_DATA_FUNC)blk_mark) { > rb_add_method(mod, id, NEW_BMETHOD(body), NOEX_PUBLIC); > } > > Ruby should check scope_vmode and set the noex argument based on that. で、こんなのを考えたんですが、SCOPE_MODFUNCのときってクラスメソッ ドも定義するほうがいいんでしょうか。 Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.235 diff -u -2 -p -r1.235 eval.c --- eval.c 2001/12/18 08:46:56 1.235 +++ eval.c 2001/12/19 04:07:20 @@ -6941,4 +6941,6 @@ rb_mod_define_method(argc, argv, mod) ID id; VALUE body; + NODE *node; + int mode; if (argc == 1) { @@ -6958,8 +6960,8 @@ rb_mod_define_method(argc, argv, mod) } if (RDATA(body)->dmark == (RUBY_DATA_FUNC)bm_mark) { - rb_add_method(mod, id, NEW_DMETHOD(method_unbind(body)), NOEX_PUBLIC); + node = NEW_DMETHOD(method_unbind(body)); } else if (RDATA(body)->dmark == (RUBY_DATA_FUNC)blk_mark) { - rb_add_method(mod, id, NEW_BMETHOD(body), NOEX_PUBLIC); + node = NEW_BMETHOD(body); } else { @@ -6967,4 +6969,18 @@ rb_mod_define_method(argc, argv, mod) rb_raise(rb_eTypeError, "wrong argument type (expected Proc)"); } + + switch (scope_vmode & SCOPE_MASK) { + case SCOPE_PRIVATE: + case SCOPE_MODFUNC: + mode = NOEX_PRIVATE; + break; + case SCOPE_PROTECTED: + mode = NOEX_PROTECTED; + break; + default: + mode = NOEX_PUBLIC; + break; + } + rb_add_method(mod, id, node, mode); rb_clear_cache_by_id(id); -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦