From: nobu.nakada@... Date: 2001-12-19T14:27:47+09:00 Subject: [ruby-dev:15502] Re: define_method() does not properly set noex (PR#218) なかだです。 At Wed, 19 Dec 2001 14:13:53 +0900, matz@ruby-lang.org (Yukihiro Matsumoto) wrote: > |で、こんなのを考えたんですが、SCOPE_MODFUNCのときってクラスメソッ > |ドも定義するほうがいいんでしょうか。 > > まあ、似たような修正を手元でもしていたのですが、MODFUNCの場 > 合を忘れてました。そーですねえ、定義した方が良いかもですねえ。 > なんかすごくイヤだけど。 それと、define_methodではmethod_added, singleton_method_addedは 呼ばないんでしょうか。 > いっそ、module_functionには宣言形式はなくすか。 たしかにあんまり使ってる例は見たことないですねぇ。 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:49:24 @@ -6941,4 +6941,7 @@ rb_mod_define_method(argc, argv, mod) ID id; VALUE body; + VALUE singleton = 0; + NODE *node; + int mode; if (argc == 1) { @@ -6958,8 +6961,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 { @@ -6968,5 +6971,33 @@ rb_mod_define_method(argc, argv, mod) } + switch (scope_vmode) { + case SCOPE_PUBLIC: + mode = NOEX_PUBLIC; + break; + case SCOPE_MODFUNC: + singleton = rb_singleton_class(mod); + /* fall through */ + case SCOPE_PRIVATE: + mode = NOEX_PRIVATE; + break; + case SCOPE_PROTECTED: + mode = NOEX_PROTECTED; + break; + default: + rb_bug("unknown scope_vmode: %d", scope_vmode); + } + + rb_add_method(mod, id, node, mode); + if (singleton) { + rb_add_method(singleton, id, node, NOEX_PUBLIC); + } + rb_clear_cache_by_id(id); + + rb_funcall(mod, added, 1, ID2SYM(id)); + if (singleton) { + rb_funcall(singleton, singleton_added, 1, ID2SYM(id)); + } + return body; } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦