From: Hiroshi IGARASHI Date: 2000-09-17T21:27:19+09:00 Subject: [ruby-dev:10936] Re: Meta-Level API いがらしです。 At Sun, 17 Sep 2000 19:48:11 +0900, in [ruby-dev:10935] Re: Meta-Level API, Hiroshi IGARASHI wrote: > > いがらしです。 > > At Sun, 17 Sep 2000 01:25:32 +0900, > in [ruby-dev:10933] Meta-Level API, > Hiroshi IGARASHI wrote: > > > > Module#direct_included_modules > > 直接includeしているModuleだけ返す版。 > > 無理矢理ですがこんな感じで計算できます。 Cレベルでもうちょっとましに書いてみました。 Module#constants_at も入ってます。 -- 五十嵐 宏 (Hiroshi IGARASHI) Index: intern.h =================================================================== RCS file: /home/cvs/ruby/intern.h,v retrieving revision 1.27 diff -u -r1.27 intern.h --- intern.h 2000/09/15 06:00:24 1.27 +++ intern.h 2000/09/17 12:25:18 @@ -84,6 +84,7 @@ VALUE rb_module_new _((void)); VALUE rb_define_module_id _((ID)); VALUE rb_mod_included_modules _((VALUE)); +VALUE rb_mod_included_modules_at _((VALUE)); VALUE rb_mod_ancestors _((VALUE)); VALUE rb_class_instance_methods _((int, VALUE*, VALUE)); VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE)); @@ -355,6 +356,7 @@ VALUE rb_mod_const_at _((VALUE, VALUE)); VALUE rb_mod_constants _((VALUE)); VALUE rb_mod_const_of _((VALUE, VALUE)); +VALUE rb_mod_constants_at _((VALUE)); VALUE rb_mod_remove_const _((VALUE, VALUE)); int rb_const_defined_at _((VALUE, ID)); int rb_autoload_defined _((ID)); Index: object.c =================================================================== RCS file: /home/cvs/ruby/object.c,v retrieving revision 1.28 diff -u -r1.28 object.c --- object.c 2000/09/15 06:00:26 1.28 +++ object.c 2000/09/17 12:25:19 @@ -1155,6 +1155,7 @@ rb_define_method(rb_cModule, "clone", rb_mod_clone, 0); rb_define_method(rb_cModule, "to_s", rb_mod_to_s, 0); rb_define_method(rb_cModule, "included_modules", rb_mod_included_modules, 0); + rb_define_method(rb_cModule, "included_modules_at", rb_mod_included_modules_at, 0); rb_define_method(rb_cModule, "name", rb_mod_name, 0); rb_define_method(rb_cModule, "ancestors", rb_mod_ancestors, 0); @@ -1171,6 +1172,7 @@ rb_define_method(rb_cModule, "private_instance_methods", rb_class_private_instance_methods, -1); rb_define_method(rb_cModule, "constants", rb_mod_constants, 0); + rb_define_method(rb_cModule, "constants_at", rb_mod_constants_at, 0); rb_define_method(rb_cModule, "const_get", rb_mod_const_get, 1); rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2); rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, 1); Index: class.c =================================================================== RCS file: /home/cvs/ruby/class.c,v retrieving revision 1.12 diff -u -r1.12 class.c --- class.c 2000/07/27 09:49:14 1.12 +++ class.c 2000/09/17 12:25:19 @@ -265,6 +265,42 @@ } VALUE +rb_mod_included_modules_at(mod) + VALUE mod; +{ + VALUE ams = rb_mod_ancestors(mod); + int i; + + switch (RARRAY(ams)->len) { + case 1: + return rb_ary_new(); + case 2: + return rb_ary_new3(1, RARRAY(ams)->ptr[1]); + default: + { + VALUE ary = rb_obj_dup(ams); + for (i = 1; i < RARRAY(ams)->len; i++) { + VALUE m = RARRAY(ams)->ptr[i]; + if (BUILTIN_TYPE(m) == T_MODULE) { + VALUE m2 = RCLASS(m)->super; + if (m2) { + rb_ary_delete(ary, RBASIC(m2)->klass); + } + } else { + ams = rb_mod_ancestors(m); + for (i = 0; i < RARRAY(ams)->len; i++) { + rb_ary_delete(ary, RARRAY(ams)->ptr[i]); + } + break; + } + } + rb_ary_delete(ary, mod); + return ary; + } + } +} + +VALUE rb_mod_ancestors(mod) VALUE mod; { Index: variable.c =================================================================== RCS file: /home/cvs/ruby/variable.c,v retrieving revision 1.24 diff -u -r1.24 variable.c --- variable.c 2000/09/15 06:00:28 1.24 +++ variable.c 2000/09/17 12:25:20 @@ -1182,6 +1182,13 @@ return rb_mod_const_of(mod, rb_ary_new()); } +VALUE +rb_mod_constants_at(mod) + VALUE mod; +{ + return rb_mod_const_at(mod, rb_ary_new()); +} + int rb_const_defined_at(klass, id) VALUE klass;