|
Ruby
1.9.3p448(2013-06-27revision41675)
|
00001 /********************************************************************** 00002 00003 class.c - 00004 00005 $Author: usa $ 00006 created at: Tue Aug 10 15:05:44 JST 1993 00007 00008 Copyright (C) 1993-2007 Yukihiro Matsumoto 00009 00010 **********************************************************************/ 00011 00026 #include "ruby/ruby.h" 00027 #include "ruby/st.h" 00028 #include "method.h" 00029 #include "constant.h" 00030 #include "vm_core.h" 00031 #include "internal.h" 00032 #include <ctype.h> 00033 00034 extern st_table *rb_class_tbl; 00035 static ID id_attached; 00036 00049 static VALUE 00050 class_alloc(VALUE flags, VALUE klass) 00051 { 00052 rb_classext_t *ext = ALLOC(rb_classext_t); 00053 NEWOBJ(obj, struct RClass); 00054 OBJSETUP(obj, klass, flags); 00055 obj->ptr = ext; 00056 RCLASS_IV_TBL(obj) = 0; 00057 RCLASS_CONST_TBL(obj) = 0; 00058 RCLASS_M_TBL(obj) = 0; 00059 RCLASS_SUPER(obj) = 0; 00060 RCLASS_IV_INDEX_TBL(obj) = 0; 00061 return (VALUE)obj; 00062 } 00063 00064 00074 VALUE 00075 rb_class_boot(VALUE super) 00076 { 00077 VALUE klass = class_alloc(T_CLASS, rb_cClass); 00078 00079 RCLASS_SUPER(klass) = super; 00080 RCLASS_M_TBL(klass) = st_init_numtable(); 00081 00082 OBJ_INFECT(klass, super); 00083 return (VALUE)klass; 00084 } 00085 00086 00093 void 00094 rb_check_inheritable(VALUE super) 00095 { 00096 if (TYPE(super) != T_CLASS) { 00097 rb_raise(rb_eTypeError, "superclass must be a Class (%s given)", 00098 rb_obj_classname(super)); 00099 } 00100 if (RBASIC(super)->flags & FL_SINGLETON) { 00101 rb_raise(rb_eTypeError, "can't make subclass of singleton class"); 00102 } 00103 if (super == rb_cClass) { 00104 rb_raise(rb_eTypeError, "can't make subclass of Class"); 00105 } 00106 } 00107 00108 00115 VALUE 00116 rb_class_new(VALUE super) 00117 { 00118 Check_Type(super, T_CLASS); 00119 rb_check_inheritable(super); 00120 return rb_class_boot(super); 00121 } 00122 00123 struct clone_method_data { 00124 st_table *tbl; 00125 VALUE klass; 00126 }; 00127 00128 VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase); 00129 00130 static int 00131 clone_method(ID mid, const rb_method_entry_t *me, struct clone_method_data *data) 00132 { 00133 VALUE newiseqval; 00134 if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) { 00135 rb_iseq_t *iseq; 00136 newiseqval = rb_iseq_clone(me->def->body.iseq->self, data->klass); 00137 GetISeqPtr(newiseqval, iseq); 00138 rb_add_method(data->klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); 00139 RB_GC_GUARD(newiseqval); 00140 } 00141 else { 00142 rb_method_entry_set(data->klass, mid, me, me->flag); 00143 } 00144 return ST_CONTINUE; 00145 } 00146 00147 static int 00148 clone_const(ID key, const rb_const_entry_t *ce, st_table *tbl) 00149 { 00150 rb_const_entry_t *nce = ALLOC(rb_const_entry_t); 00151 *nce = *ce; 00152 st_insert(tbl, key, (st_data_t)nce); 00153 return ST_CONTINUE; 00154 } 00155 00156 static int 00157 clone_const_i(st_data_t key, st_data_t value, st_data_t data) 00158 { 00159 return clone_const((ID)key, (const rb_const_entry_t *)value, (st_table *)data); 00160 } 00161 00162 static void 00163 class_init_copy_check(VALUE clone, VALUE orig) 00164 { 00165 if (orig == rb_cBasicObject) { 00166 rb_raise(rb_eTypeError, "can't copy the root class"); 00167 } 00168 if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) { 00169 rb_raise(rb_eTypeError, "already initialized class"); 00170 } 00171 if (FL_TEST(orig, FL_SINGLETON)) { 00172 rb_raise(rb_eTypeError, "can't copy singleton class"); 00173 } 00174 } 00175 00176 /* :nodoc: */ 00177 VALUE 00178 rb_mod_init_copy(VALUE clone, VALUE orig) 00179 { 00180 if (RB_TYPE_P(clone, T_CLASS)) { 00181 class_init_copy_check(clone, orig); 00182 } 00183 rb_obj_init_copy(clone, orig); 00184 if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) { 00185 RBASIC(clone)->klass = rb_singleton_class_clone(orig); 00186 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); 00187 } 00188 RCLASS_SUPER(clone) = RCLASS_SUPER(orig); 00189 if (RCLASS_IV_TBL(orig)) { 00190 st_data_t id; 00191 00192 if (RCLASS_IV_TBL(clone)) { 00193 st_free_table(RCLASS_IV_TBL(clone)); 00194 } 00195 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig)); 00196 CONST_ID(id, "__classpath__"); 00197 st_delete(RCLASS_IV_TBL(clone), &id, 0); 00198 CONST_ID(id, "__classid__"); 00199 st_delete(RCLASS_IV_TBL(clone), &id, 0); 00200 } 00201 if (RCLASS_CONST_TBL(orig)) { 00202 if (RCLASS_CONST_TBL(clone)) { 00203 rb_free_const_table(RCLASS_CONST_TBL(clone)); 00204 } 00205 RCLASS_CONST_TBL(clone) = st_init_numtable(); 00206 st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone)); 00207 } 00208 if (RCLASS_M_TBL(orig)) { 00209 struct clone_method_data data; 00210 00211 if (RCLASS_M_TBL(clone)) { 00212 rb_free_m_table(RCLASS_M_TBL(clone)); 00213 } 00214 data.tbl = RCLASS_M_TBL(clone) = st_init_numtable(); 00215 data.klass = clone; 00216 st_foreach(RCLASS_M_TBL(orig), clone_method, 00217 (st_data_t)&data); 00218 } 00219 00220 return clone; 00221 } 00222 00223 VALUE 00224 rb_singleton_class_clone(VALUE obj) 00225 { 00226 VALUE klass = RBASIC(obj)->klass; 00227 00228 if (!FL_TEST(klass, FL_SINGLETON)) 00229 return klass; 00230 else { 00231 struct clone_method_data data; 00232 /* copy singleton(unnamed) class */ 00233 VALUE clone = class_alloc((RBASIC(klass)->flags & ~(FL_MARK)), 0); 00234 00235 if (BUILTIN_TYPE(obj) == T_CLASS) { 00236 RBASIC(clone)->klass = (VALUE)clone; 00237 } 00238 else { 00239 RBASIC(clone)->klass = rb_singleton_class_clone(klass); 00240 } 00241 00242 RCLASS_SUPER(clone) = RCLASS_SUPER(klass); 00243 if (RCLASS_IV_TBL(klass)) { 00244 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass)); 00245 } 00246 if (RCLASS_CONST_TBL(klass)) { 00247 RCLASS_CONST_TBL(clone) = st_init_numtable(); 00248 st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone)); 00249 } 00250 RCLASS_M_TBL(clone) = st_init_numtable(); 00251 data.tbl = RCLASS_M_TBL(clone); 00252 data.klass = (VALUE)clone; 00253 st_foreach(RCLASS_M_TBL(klass), clone_method, 00254 (st_data_t)&data); 00255 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); 00256 FL_SET(clone, FL_SINGLETON); 00257 return (VALUE)clone; 00258 } 00259 } 00260 00265 void 00266 rb_singleton_class_attached(VALUE klass, VALUE obj) 00267 { 00268 if (FL_TEST(klass, FL_SINGLETON)) { 00269 if (!RCLASS_IV_TBL(klass)) { 00270 RCLASS_IV_TBL(klass) = st_init_numtable(); 00271 } 00272 st_insert(RCLASS_IV_TBL(klass), id_attached, obj); 00273 } 00274 } 00275 00276 00277 00278 #define METACLASS_OF(k) RBASIC(k)->klass 00279 00285 #define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k)) 00286 00287 00295 #define ENSURE_EIGENCLASS(klass) \ 00296 (rb_ivar_get(METACLASS_OF(klass), id_attached) == (klass) ? METACLASS_OF(klass) : make_metaclass(klass)) 00297 00298 00308 static inline VALUE 00309 make_metaclass(VALUE klass) 00310 { 00311 VALUE super; 00312 VALUE metaclass = rb_class_boot(Qundef); 00313 00314 FL_SET(metaclass, FL_SINGLETON); 00315 rb_singleton_class_attached(metaclass, klass); 00316 00317 if (META_CLASS_OF_CLASS_CLASS_P(klass)) { 00318 METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass; 00319 } 00320 else { 00321 VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */ 00322 METACLASS_OF(klass) = metaclass; 00323 METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp); 00324 } 00325 00326 super = RCLASS_SUPER(klass); 00327 while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super); 00328 RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass; 00329 00330 OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass)); 00331 00332 return metaclass; 00333 } 00334 00341 static inline VALUE 00342 make_singleton_class(VALUE obj) 00343 { 00344 VALUE orig_class = RBASIC(obj)->klass; 00345 VALUE klass = rb_class_boot(orig_class); 00346 00347 FL_SET(klass, FL_SINGLETON); 00348 RBASIC(obj)->klass = klass; 00349 rb_singleton_class_attached(klass, obj); 00350 00351 METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class)); 00352 return klass; 00353 } 00354 00355 00356 static VALUE 00357 boot_defclass(const char *name, VALUE super) 00358 { 00359 extern st_table *rb_class_tbl; 00360 VALUE obj = rb_class_boot(super); 00361 ID id = rb_intern(name); 00362 00363 rb_name_class(obj, id); 00364 st_add_direct(rb_class_tbl, id, obj); 00365 rb_const_set((rb_cObject ? rb_cObject : obj), id, obj); 00366 return obj; 00367 } 00368 00369 void 00370 Init_class_hierarchy(void) 00371 { 00372 id_attached = rb_intern("__attached__"); 00373 00374 rb_cBasicObject = boot_defclass("BasicObject", 0); 00375 rb_cObject = boot_defclass("Object", rb_cBasicObject); 00376 rb_cModule = boot_defclass("Module", rb_cObject); 00377 rb_cClass = boot_defclass("Class", rb_cModule); 00378 00379 rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject); 00380 RBASIC(rb_cClass)->klass 00381 = RBASIC(rb_cModule)->klass 00382 = RBASIC(rb_cObject)->klass 00383 = RBASIC(rb_cBasicObject)->klass 00384 = rb_cClass; 00385 } 00386 00387 00398 VALUE 00399 rb_make_metaclass(VALUE obj, VALUE unused) 00400 { 00401 if (BUILTIN_TYPE(obj) == T_CLASS) { 00402 return make_metaclass(obj); 00403 } 00404 else { 00405 return make_singleton_class(obj); 00406 } 00407 } 00408 00409 00420 VALUE 00421 rb_define_class_id(ID id, VALUE super) 00422 { 00423 VALUE klass; 00424 00425 if (!super) super = rb_cObject; 00426 klass = rb_class_new(super); 00427 rb_make_metaclass(klass, RBASIC(super)->klass); 00428 00429 return klass; 00430 } 00431 00432 00441 VALUE 00442 rb_class_inherited(VALUE super, VALUE klass) 00443 { 00444 ID inherited; 00445 if (!super) super = rb_cObject; 00446 CONST_ID(inherited, "inherited"); 00447 return rb_funcall(super, inherited, 1, klass); 00448 } 00449 00450 00451 00467 VALUE 00468 rb_define_class(const char *name, VALUE super) 00469 { 00470 VALUE klass; 00471 ID id; 00472 00473 id = rb_intern(name); 00474 if (rb_const_defined(rb_cObject, id)) { 00475 klass = rb_const_get(rb_cObject, id); 00476 if (TYPE(klass) != T_CLASS) { 00477 rb_raise(rb_eTypeError, "%s is not a class", name); 00478 } 00479 if (rb_class_real(RCLASS_SUPER(klass)) != super) { 00480 rb_raise(rb_eTypeError, "superclass mismatch for class %s", name); 00481 } 00482 return klass; 00483 } 00484 if (!super) { 00485 rb_warn("no super class for `%s', Object assumed", name); 00486 } 00487 klass = rb_define_class_id(id, super); 00488 st_add_direct(rb_class_tbl, id, klass); 00489 rb_name_class(klass, id); 00490 rb_const_set(rb_cObject, id, klass); 00491 rb_class_inherited(super, klass); 00492 00493 return klass; 00494 } 00495 00496 00513 VALUE 00514 rb_define_class_under(VALUE outer, const char *name, VALUE super) 00515 { 00516 return rb_define_class_id_under(outer, rb_intern(name), super); 00517 } 00518 00519 00536 VALUE 00537 rb_define_class_id_under(VALUE outer, ID id, VALUE super) 00538 { 00539 VALUE klass; 00540 00541 if (rb_const_defined_at(outer, id)) { 00542 klass = rb_const_get_at(outer, id); 00543 if (TYPE(klass) != T_CLASS) { 00544 rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id)); 00545 } 00546 if (rb_class_real(RCLASS_SUPER(klass)) != super) { 00547 rb_name_error(id, "%s is already defined", rb_id2name(id)); 00548 } 00549 return klass; 00550 } 00551 if (!super) { 00552 rb_warn("no super class for `%s::%s', Object assumed", 00553 rb_class2name(outer), rb_id2name(id)); 00554 } 00555 klass = rb_define_class_id(id, super); 00556 rb_set_class_path_string(klass, outer, rb_id2str(id)); 00557 rb_const_set(outer, id, klass); 00558 rb_class_inherited(super, klass); 00559 rb_gc_register_mark_object(klass); 00560 00561 return klass; 00562 } 00563 00564 VALUE 00565 rb_module_new(void) 00566 { 00567 VALUE mdl = class_alloc(T_MODULE, rb_cModule); 00568 00569 RCLASS_M_TBL(mdl) = st_init_numtable(); 00570 00571 return (VALUE)mdl; 00572 } 00573 00574 VALUE 00575 rb_define_module_id(ID id) 00576 { 00577 VALUE mdl; 00578 00579 mdl = rb_module_new(); 00580 rb_name_class(mdl, id); 00581 00582 return mdl; 00583 } 00584 00585 VALUE 00586 rb_define_module(const char *name) 00587 { 00588 VALUE module; 00589 ID id; 00590 00591 id = rb_intern(name); 00592 if (rb_const_defined(rb_cObject, id)) { 00593 module = rb_const_get(rb_cObject, id); 00594 if (TYPE(module) == T_MODULE) 00595 return module; 00596 rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module)); 00597 } 00598 module = rb_define_module_id(id); 00599 st_add_direct(rb_class_tbl, id, module); 00600 rb_const_set(rb_cObject, id, module); 00601 00602 return module; 00603 } 00604 00605 VALUE 00606 rb_define_module_under(VALUE outer, const char *name) 00607 { 00608 return rb_define_module_id_under(outer, rb_intern(name)); 00609 } 00610 00611 VALUE 00612 rb_define_module_id_under(VALUE outer, ID id) 00613 { 00614 VALUE module; 00615 00616 if (rb_const_defined_at(outer, id)) { 00617 module = rb_const_get_at(outer, id); 00618 if (TYPE(module) == T_MODULE) 00619 return module; 00620 rb_raise(rb_eTypeError, "%s::%s is not a module", 00621 rb_class2name(outer), rb_obj_classname(module)); 00622 } 00623 module = rb_define_module_id(id); 00624 rb_const_set(outer, id, module); 00625 rb_set_class_path_string(module, outer, rb_id2str(id)); 00626 rb_gc_register_mark_object(module); 00627 00628 return module; 00629 } 00630 00631 static VALUE 00632 include_class_new(VALUE module, VALUE super) 00633 { 00634 VALUE klass = class_alloc(T_ICLASS, rb_cClass); 00635 00636 if (BUILTIN_TYPE(module) == T_ICLASS) { 00637 module = RBASIC(module)->klass; 00638 } 00639 if (!RCLASS_IV_TBL(module)) { 00640 RCLASS_IV_TBL(module) = st_init_numtable(); 00641 } 00642 if (!RCLASS_CONST_TBL(module)) { 00643 RCLASS_CONST_TBL(module) = st_init_numtable(); 00644 } 00645 RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module); 00646 RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module); 00647 RCLASS_M_TBL(klass) = RCLASS_M_TBL(module); 00648 RCLASS_SUPER(klass) = super; 00649 if (TYPE(module) == T_ICLASS) { 00650 RBASIC(klass)->klass = RBASIC(module)->klass; 00651 } 00652 else { 00653 RBASIC(klass)->klass = module; 00654 } 00655 OBJ_INFECT(klass, module); 00656 OBJ_INFECT(klass, super); 00657 00658 return (VALUE)klass; 00659 } 00660 00661 void 00662 rb_include_module(VALUE klass, VALUE module) 00663 { 00664 VALUE p, c; 00665 int changed = 0; 00666 00667 rb_frozen_class_p(klass); 00668 if (!OBJ_UNTRUSTED(klass)) { 00669 rb_secure(4); 00670 } 00671 00672 if (TYPE(module) != T_MODULE) { 00673 Check_Type(module, T_MODULE); 00674 } 00675 00676 OBJ_INFECT(klass, module); 00677 c = klass; 00678 while (module) { 00679 int superclass_seen = FALSE; 00680 00681 if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module)) 00682 rb_raise(rb_eArgError, "cyclic include detected"); 00683 /* ignore if the module included already in superclasses */ 00684 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) { 00685 switch (BUILTIN_TYPE(p)) { 00686 case T_ICLASS: 00687 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) { 00688 if (!superclass_seen) { 00689 c = p; /* move insertion point */ 00690 } 00691 goto skip; 00692 } 00693 break; 00694 case T_CLASS: 00695 superclass_seen = TRUE; 00696 break; 00697 } 00698 } 00699 c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c)); 00700 if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries) 00701 changed = 1; 00702 if (RMODULE_CONST_TBL(module) && RMODULE_CONST_TBL(module)->num_entries) 00703 changed = 1; 00704 skip: 00705 module = RCLASS_SUPER(module); 00706 } 00707 if (changed) rb_clear_cache(); 00708 } 00709 00710 /* 00711 * call-seq: 00712 * mod.included_modules -> array 00713 * 00714 * Returns the list of modules included in <i>mod</i>. 00715 * 00716 * module Mixin 00717 * end 00718 * 00719 * module Outer 00720 * include Mixin 00721 * end 00722 * 00723 * Mixin.included_modules #=> [] 00724 * Outer.included_modules #=> [Mixin] 00725 */ 00726 00727 VALUE 00728 rb_mod_included_modules(VALUE mod) 00729 { 00730 VALUE ary = rb_ary_new(); 00731 VALUE p; 00732 00733 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) { 00734 if (BUILTIN_TYPE(p) == T_ICLASS) { 00735 rb_ary_push(ary, RBASIC(p)->klass); 00736 } 00737 } 00738 return ary; 00739 } 00740 00741 /* 00742 * call-seq: 00743 * mod.include?(module) -> true or false 00744 * 00745 * Returns <code>true</code> if <i>module</i> is included in 00746 * <i>mod</i> or one of <i>mod</i>'s ancestors. 00747 * 00748 * module A 00749 * end 00750 * class B 00751 * include A 00752 * end 00753 * class C < B 00754 * end 00755 * B.include?(A) #=> true 00756 * C.include?(A) #=> true 00757 * A.include?(A) #=> false 00758 */ 00759 00760 VALUE 00761 rb_mod_include_p(VALUE mod, VALUE mod2) 00762 { 00763 VALUE p; 00764 00765 Check_Type(mod2, T_MODULE); 00766 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) { 00767 if (BUILTIN_TYPE(p) == T_ICLASS) { 00768 if (RBASIC(p)->klass == mod2) return Qtrue; 00769 } 00770 } 00771 return Qfalse; 00772 } 00773 00774 /* 00775 * call-seq: 00776 * mod.ancestors -> array 00777 * 00778 * Returns a list of modules included in <i>mod</i> (including 00779 * <i>mod</i> itself). 00780 * 00781 * module Mod 00782 * include Math 00783 * include Comparable 00784 * end 00785 * 00786 * Mod.ancestors #=> [Mod, Comparable, Math] 00787 * Math.ancestors #=> [Math] 00788 */ 00789 00790 VALUE 00791 rb_mod_ancestors(VALUE mod) 00792 { 00793 VALUE p, ary = rb_ary_new(); 00794 00795 for (p = mod; p; p = RCLASS_SUPER(p)) { 00796 if (FL_TEST(p, FL_SINGLETON)) 00797 continue; 00798 if (BUILTIN_TYPE(p) == T_ICLASS) { 00799 rb_ary_push(ary, RBASIC(p)->klass); 00800 } 00801 else { 00802 rb_ary_push(ary, p); 00803 } 00804 } 00805 return ary; 00806 } 00807 00808 #define VISI(x) ((x)&NOEX_MASK) 00809 #define VISI_CHECK(x,f) (VISI(x) == (f)) 00810 00811 static int 00812 ins_methods_push(ID name, long type, VALUE ary, long visi) 00813 { 00814 if (type == -1) return ST_CONTINUE; 00815 00816 switch (visi) { 00817 case NOEX_PRIVATE: 00818 case NOEX_PROTECTED: 00819 case NOEX_PUBLIC: 00820 visi = (type == visi); 00821 break; 00822 default: 00823 visi = (type != NOEX_PRIVATE); 00824 break; 00825 } 00826 if (visi) { 00827 rb_ary_push(ary, ID2SYM(name)); 00828 } 00829 return ST_CONTINUE; 00830 } 00831 00832 static int 00833 ins_methods_i(st_data_t name, st_data_t type, st_data_t ary) 00834 { 00835 return ins_methods_push((ID)name, (long)type, (VALUE)ary, -1); /* everything but private */ 00836 } 00837 00838 static int 00839 ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary) 00840 { 00841 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PROTECTED); 00842 } 00843 00844 static int 00845 ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary) 00846 { 00847 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PRIVATE); 00848 } 00849 00850 static int 00851 ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary) 00852 { 00853 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC); 00854 } 00855 00856 static int 00857 method_entry_i(st_data_t key, st_data_t value, st_data_t data) 00858 { 00859 const rb_method_entry_t *me = (const rb_method_entry_t *)value; 00860 st_table *list = (st_table *)data; 00861 long type; 00862 00863 if ((ID)key == ID_ALLOCATOR) { 00864 return ST_CONTINUE; 00865 } 00866 00867 if (!st_lookup(list, key, 0)) { 00868 if (UNDEFINED_METHOD_ENTRY_P(me)) { 00869 type = -1; /* none */ 00870 } 00871 else { 00872 type = VISI(me->flag); 00873 } 00874 st_add_direct(list, key, type); 00875 } 00876 return ST_CONTINUE; 00877 } 00878 00879 static VALUE 00880 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t)) 00881 { 00882 VALUE ary; 00883 int recur; 00884 st_table *list; 00885 00886 if (argc == 0) { 00887 recur = TRUE; 00888 } 00889 else { 00890 VALUE r; 00891 rb_scan_args(argc, argv, "01", &r); 00892 recur = RTEST(r); 00893 } 00894 00895 list = st_init_numtable(); 00896 for (; mod; mod = RCLASS_SUPER(mod)) { 00897 st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list); 00898 if (BUILTIN_TYPE(mod) == T_ICLASS) continue; 00899 if (obj && FL_TEST(mod, FL_SINGLETON)) continue; 00900 if (!recur) break; 00901 } 00902 ary = rb_ary_new(); 00903 st_foreach(list, func, ary); 00904 st_free_table(list); 00905 00906 return ary; 00907 } 00908 00909 /* 00910 * call-seq: 00911 * mod.instance_methods(include_super=true) -> array 00912 * 00913 * Returns an array containing the names of the public and protected instance 00914 * methods in the receiver. For a module, these are the public and protected methods; 00915 * for a class, they are the instance (not singleton) methods. With no 00916 * argument, or with an argument that is <code>false</code>, the 00917 * instance methods in <i>mod</i> are returned, otherwise the methods 00918 * in <i>mod</i> and <i>mod</i>'s superclasses are returned. 00919 * 00920 * module A 00921 * def method1() end 00922 * end 00923 * class B 00924 * def method2() end 00925 * end 00926 * class C < B 00927 * def method3() end 00928 * end 00929 * 00930 * A.instance_methods #=> [:method1] 00931 * B.instance_methods(false) #=> [:method2] 00932 * C.instance_methods(false) #=> [:method3] 00933 * C.instance_methods(true).length #=> 43 00934 */ 00935 00936 VALUE 00937 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod) 00938 { 00939 return class_instance_method_list(argc, argv, mod, 0, ins_methods_i); 00940 } 00941 00942 /* 00943 * call-seq: 00944 * mod.protected_instance_methods(include_super=true) -> array 00945 * 00946 * Returns a list of the protected instance methods defined in 00947 * <i>mod</i>. If the optional parameter is not <code>false</code>, the 00948 * methods of any ancestors are included. 00949 */ 00950 00951 VALUE 00952 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod) 00953 { 00954 return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i); 00955 } 00956 00957 /* 00958 * call-seq: 00959 * mod.private_instance_methods(include_super=true) -> array 00960 * 00961 * Returns a list of the private instance methods defined in 00962 * <i>mod</i>. If the optional parameter is not <code>false</code>, the 00963 * methods of any ancestors are included. 00964 * 00965 * module Mod 00966 * def method1() end 00967 * private :method1 00968 * def method2() end 00969 * end 00970 * Mod.instance_methods #=> [:method2] 00971 * Mod.private_instance_methods #=> [:method1] 00972 */ 00973 00974 VALUE 00975 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod) 00976 { 00977 return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i); 00978 } 00979 00980 /* 00981 * call-seq: 00982 * mod.public_instance_methods(include_super=true) -> array 00983 * 00984 * Returns a list of the public instance methods defined in <i>mod</i>. 00985 * If the optional parameter is not <code>false</code>, the methods of 00986 * any ancestors are included. 00987 */ 00988 00989 VALUE 00990 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod) 00991 { 00992 return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i); 00993 } 00994 00995 /* 00996 * call-seq: 00997 * obj.methods -> array 00998 * 00999 * Returns a list of the names of public and protected methods of 01000 * <i>obj</i>. This will include all the methods accessible in 01001 * <i>obj</i>'s ancestors. 01002 * 01003 * class Klass 01004 * def klass_method() 01005 * end 01006 * end 01007 * k = Klass.new 01008 * k.methods[0..9] #=> [:klass_method, :nil?, :===, 01009 * # :==~, :!, :eql? 01010 * # :hash, :<=>, :class, :singleton_class] 01011 * k.methods.length #=> 57 01012 */ 01013 01014 VALUE 01015 rb_obj_methods(int argc, VALUE *argv, VALUE obj) 01016 { 01017 retry: 01018 if (argc == 0) { 01019 VALUE args[1]; 01020 01021 args[0] = Qtrue; 01022 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i); 01023 } 01024 else { 01025 VALUE recur; 01026 01027 rb_scan_args(argc, argv, "1", &recur); 01028 if (RTEST(recur)) { 01029 argc = 0; 01030 goto retry; 01031 } 01032 return rb_obj_singleton_methods(argc, argv, obj); 01033 } 01034 } 01035 01036 /* 01037 * call-seq: 01038 * obj.protected_methods(all=true) -> array 01039 * 01040 * Returns the list of protected methods accessible to <i>obj</i>. If 01041 * the <i>all</i> parameter is set to <code>false</code>, only those methods 01042 * in the receiver will be listed. 01043 */ 01044 01045 VALUE 01046 rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj) 01047 { 01048 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i); 01049 } 01050 01051 /* 01052 * call-seq: 01053 * obj.private_methods(all=true) -> array 01054 * 01055 * Returns the list of private methods accessible to <i>obj</i>. If 01056 * the <i>all</i> parameter is set to <code>false</code>, only those methods 01057 * in the receiver will be listed. 01058 */ 01059 01060 VALUE 01061 rb_obj_private_methods(int argc, VALUE *argv, VALUE obj) 01062 { 01063 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i); 01064 } 01065 01066 /* 01067 * call-seq: 01068 * obj.public_methods(all=true) -> array 01069 * 01070 * Returns the list of public methods accessible to <i>obj</i>. If 01071 * the <i>all</i> parameter is set to <code>false</code>, only those methods 01072 * in the receiver will be listed. 01073 */ 01074 01075 VALUE 01076 rb_obj_public_methods(int argc, VALUE *argv, VALUE obj) 01077 { 01078 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i); 01079 } 01080 01081 /* 01082 * call-seq: 01083 * obj.singleton_methods(all=true) -> array 01084 * 01085 * Returns an array of the names of singleton methods for <i>obj</i>. 01086 * If the optional <i>all</i> parameter is true, the list will include 01087 * methods in modules included in <i>obj</i>. 01088 * Only public and protected singleton methods are returned. 01089 * 01090 * module Other 01091 * def three() end 01092 * end 01093 * 01094 * class Single 01095 * def Single.four() end 01096 * end 01097 * 01098 * a = Single.new 01099 * 01100 * def a.one() 01101 * end 01102 * 01103 * class << a 01104 * include Other 01105 * def two() 01106 * end 01107 * end 01108 * 01109 * Single.singleton_methods #=> [:four] 01110 * a.singleton_methods(false) #=> [:two, :one] 01111 * a.singleton_methods #=> [:two, :one, :three] 01112 */ 01113 01114 VALUE 01115 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj) 01116 { 01117 VALUE recur, ary, klass; 01118 st_table *list; 01119 01120 if (argc == 0) { 01121 recur = Qtrue; 01122 } 01123 else { 01124 rb_scan_args(argc, argv, "01", &recur); 01125 } 01126 klass = CLASS_OF(obj); 01127 list = st_init_numtable(); 01128 if (klass && FL_TEST(klass, FL_SINGLETON)) { 01129 st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list); 01130 klass = RCLASS_SUPER(klass); 01131 } 01132 if (RTEST(recur)) { 01133 while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) { 01134 st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list); 01135 klass = RCLASS_SUPER(klass); 01136 } 01137 } 01138 ary = rb_ary_new(); 01139 st_foreach(list, ins_methods_i, ary); 01140 st_free_table(list); 01141 01142 return ary; 01143 } 01144 01202 void 01203 rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc) 01204 { 01205 rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC); 01206 } 01207 01208 void 01209 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) 01210 { 01211 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC); 01212 } 01213 01214 void 01215 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) 01216 { 01217 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED); 01218 } 01219 01220 void 01221 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) 01222 { 01223 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE); 01224 } 01225 01226 void 01227 rb_undef_method(VALUE klass, const char *name) 01228 { 01229 rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF); 01230 } 01231 01240 #define SPECIAL_SINGLETON(x,c) do {\ 01241 if (obj == (x)) {\ 01242 return (c);\ 01243 }\ 01244 } while (0) 01245 01246 01256 static VALUE 01257 singleton_class_of(VALUE obj) 01258 { 01259 VALUE klass; 01260 01261 if (FIXNUM_P(obj) || SYMBOL_P(obj)) { 01262 rb_raise(rb_eTypeError, "can't define singleton"); 01263 } 01264 if (rb_special_const_p(obj)) { 01265 SPECIAL_SINGLETON(Qnil, rb_cNilClass); 01266 SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); 01267 SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); 01268 rb_bug("unknown immediate %p", (void *)obj); 01269 } 01270 01271 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && 01272 rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) { 01273 klass = RBASIC(obj)->klass; 01274 } 01275 else { 01276 klass = rb_make_metaclass(obj, RBASIC(obj)->klass); 01277 } 01278 01279 if (OBJ_TAINTED(obj)) { 01280 OBJ_TAINT(klass); 01281 } 01282 else { 01283 FL_UNSET(klass, FL_TAINT); 01284 } 01285 if (OBJ_UNTRUSTED(obj)) { 01286 OBJ_UNTRUST(klass); 01287 } 01288 else { 01289 FL_UNSET(klass, FL_UNTRUSTED); 01290 } 01291 if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); 01292 01293 return klass; 01294 } 01295 01296 01314 VALUE 01315 rb_singleton_class(VALUE obj) 01316 { 01317 VALUE klass = singleton_class_of(obj); 01318 01319 /* ensures an exposed class belongs to its own eigenclass */ 01320 if (TYPE(obj) == T_CLASS) (void)ENSURE_EIGENCLASS(klass); 01321 01322 return klass; 01323 } 01324 01341 void 01342 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc) 01343 { 01344 rb_define_method(singleton_class_of(obj), name, func, argc); 01345 } 01346 01347 01348 01356 void 01357 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc) 01358 { 01359 rb_define_private_method(module, name, func, argc); 01360 rb_define_singleton_method(module, name, func, argc); 01361 } 01362 01363 01370 void 01371 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc) 01372 { 01373 rb_define_module_function(rb_mKernel, name, func, argc); 01374 } 01375 01376 01383 void 01384 rb_define_alias(VALUE klass, const char *name1, const char *name2) 01385 { 01386 rb_alias(klass, rb_intern(name1), rb_intern(name2)); 01387 } 01388 01396 void 01397 rb_define_attr(VALUE klass, const char *name, int read, int write) 01398 { 01399 rb_attr(klass, rb_intern(name), read, write, FALSE); 01400 } 01401 01402 int 01403 rb_obj_basic_to_s_p(VALUE obj) 01404 { 01405 const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s")); 01406 if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC && 01407 me->def->body.cfunc.func == rb_any_to_s) 01408 return 1; 01409 return 0; 01410 } 01411 01412 #include <stdarg.h> 01413 01414 int 01415 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) 01416 { 01417 int i; 01418 const char *p = fmt; 01419 VALUE *var; 01420 va_list vargs; 01421 int f_var = 0, f_hash = 0, f_block = 0; 01422 int n_lead = 0, n_opt = 0, n_trail = 0, n_mand; 01423 int argi = 0; 01424 VALUE hash = Qnil; 01425 01426 if (ISDIGIT(*p)) { 01427 n_lead = *p - '0'; 01428 p++; 01429 if (ISDIGIT(*p)) { 01430 n_opt = *p - '0'; 01431 p++; 01432 if (ISDIGIT(*p)) { 01433 n_trail = *p - '0'; 01434 p++; 01435 goto block_arg; 01436 } 01437 } 01438 } 01439 if (*p == '*') { 01440 f_var = 1; 01441 p++; 01442 if (ISDIGIT(*p)) { 01443 n_trail = *p - '0'; 01444 p++; 01445 } 01446 } 01447 block_arg: 01448 if (*p == ':') { 01449 f_hash = 1; 01450 p++; 01451 } 01452 if (*p == '&') { 01453 f_block = 1; 01454 p++; 01455 } 01456 if (*p != '\0') { 01457 rb_fatal("bad scan arg format: %s", fmt); 01458 } 01459 n_mand = n_lead + n_trail; 01460 01461 if (argc < n_mand) 01462 goto argc_error; 01463 01464 va_start(vargs, fmt); 01465 01466 /* capture an option hash - phase 1: pop */ 01467 if (f_hash && n_mand < argc) { 01468 VALUE last = argv[argc - 1]; 01469 01470 if (NIL_P(last)) { 01471 /* nil is taken as an empty option hash only if it is not 01472 ambiguous; i.e. '*' is not specified and arguments are 01473 given more than sufficient */ 01474 if (!f_var && n_mand + n_opt < argc) 01475 argc--; 01476 } 01477 else { 01478 hash = rb_check_convert_type(last, T_HASH, "Hash", "to_hash"); 01479 if (!NIL_P(hash)) 01480 argc--; 01481 } 01482 } 01483 /* capture leading mandatory arguments */ 01484 for (i = n_lead; i-- > 0; ) { 01485 var = va_arg(vargs, VALUE *); 01486 if (var) *var = argv[argi]; 01487 argi++; 01488 } 01489 /* capture optional arguments */ 01490 for (i = n_opt; i-- > 0; ) { 01491 var = va_arg(vargs, VALUE *); 01492 if (argi < argc - n_trail) { 01493 if (var) *var = argv[argi]; 01494 argi++; 01495 } 01496 else { 01497 if (var) *var = Qnil; 01498 } 01499 } 01500 /* capture variable length arguments */ 01501 if (f_var) { 01502 int n_var = argc - argi - n_trail; 01503 01504 var = va_arg(vargs, VALUE *); 01505 if (0 < n_var) { 01506 if (var) *var = rb_ary_new4(n_var, &argv[argi]); 01507 argi += n_var; 01508 } 01509 else { 01510 if (var) *var = rb_ary_new(); 01511 } 01512 } 01513 /* capture trailing mandatory arguments */ 01514 for (i = n_trail; i-- > 0; ) { 01515 var = va_arg(vargs, VALUE *); 01516 if (var) *var = argv[argi]; 01517 argi++; 01518 } 01519 /* capture an option hash - phase 2: assignment */ 01520 if (f_hash) { 01521 var = va_arg(vargs, VALUE *); 01522 if (var) *var = hash; 01523 } 01524 /* capture iterator block */ 01525 if (f_block) { 01526 var = va_arg(vargs, VALUE *); 01527 if (rb_block_given_p()) { 01528 *var = rb_block_proc(); 01529 } 01530 else { 01531 *var = Qnil; 01532 } 01533 } 01534 va_end(vargs); 01535 01536 if (argi < argc) 01537 goto argc_error; 01538 01539 return argc; 01540 01541 argc_error: 01542 if (0 < n_opt) 01543 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d..%d%s)", 01544 argc, n_mand, n_mand + n_opt, f_var ? "+" : ""); 01545 else 01546 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d%s)", 01547 argc, n_mand, f_var ? "+" : ""); 01548 } 01549
1.7.6.1