• Main Page
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

class.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   class.c -
00004 
00005   $Author: yugui $
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 "vm_core.h"
00030 #include <ctype.h>
00031 
00032 extern st_table *rb_class_tbl;
00033 static ID id_attached;
00034 
00047 static VALUE
00048 class_alloc(VALUE flags, VALUE klass)
00049 {
00050     rb_classext_t *ext = ALLOC(rb_classext_t);
00051     NEWOBJ(obj, struct RClass);
00052     OBJSETUP(obj, klass, flags);
00053     obj->ptr = ext;
00054     RCLASS_IV_TBL(obj) = 0;
00055     RCLASS_M_TBL(obj) = 0;
00056     RCLASS_SUPER(obj) = 0;
00057     RCLASS_IV_INDEX_TBL(obj) = 0;
00058     return (VALUE)obj;
00059 }
00060 
00061 
00071 VALUE
00072 rb_class_boot(VALUE super)
00073 {
00074     VALUE klass = class_alloc(T_CLASS, rb_cClass);
00075 
00076     RCLASS_SUPER(klass) = super;
00077     RCLASS_M_TBL(klass) = st_init_numtable();
00078 
00079     OBJ_INFECT(klass, super);
00080     return (VALUE)klass;
00081 }
00082 
00083 
00090 void
00091 rb_check_inheritable(VALUE super)
00092 {
00093     if (TYPE(super) != T_CLASS) {
00094         rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
00095                  rb_obj_classname(super));
00096     }
00097     if (RBASIC(super)->flags & FL_SINGLETON) {
00098         rb_raise(rb_eTypeError, "can't make subclass of singleton class");
00099     }
00100     if (super == rb_cClass) {
00101         rb_raise(rb_eTypeError, "can't make subclass of Class");
00102     }
00103 }
00104 
00105 
00112 VALUE
00113 rb_class_new(VALUE super)
00114 {
00115     Check_Type(super, T_CLASS);
00116     rb_check_inheritable(super);
00117     return rb_class_boot(super);
00118 }
00119 
00120 struct clone_method_data {
00121     st_table *tbl;
00122     VALUE klass;
00123 };
00124 
00125 VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase);
00126 
00127 static int
00128 clone_method(ID mid, const rb_method_entry_t *me, struct clone_method_data *data)
00129 {
00130     VALUE newiseqval;
00131     if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) {
00132         rb_iseq_t *iseq;
00133         newiseqval = rb_iseq_clone(me->def->body.iseq->self, data->klass);
00134         GetISeqPtr(newiseqval, iseq);
00135         rb_add_method(data->klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
00136         RB_GC_GUARD(newiseqval);
00137     }
00138     else {
00139         rb_method_entry_set(data->klass, mid, me, me->flag);
00140     }
00141     return ST_CONTINUE;
00142 }
00143 
00144 /* :nodoc: */
00145 VALUE
00146 rb_mod_init_copy(VALUE clone, VALUE orig)
00147 {
00148     rb_obj_init_copy(clone, orig);
00149     if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
00150         RBASIC(clone)->klass = rb_singleton_class_clone(orig);
00151         rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
00152     }
00153     RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
00154     if (RCLASS_IV_TBL(orig)) {
00155         ID id;
00156 
00157         if (RCLASS_IV_TBL(clone)) {
00158             st_free_table(RCLASS_IV_TBL(clone));
00159         }
00160         RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
00161         CONST_ID(id, "__classpath__");
00162         st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
00163         CONST_ID(id, "__classid__");
00164         st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
00165     }
00166     if (RCLASS_M_TBL(orig)) {
00167         struct clone_method_data data;
00168 
00169         if (RCLASS_M_TBL(clone)) {
00170             extern void rb_free_m_table(st_table *tbl);
00171             rb_free_m_table(RCLASS_M_TBL(clone));
00172         }
00173         data.tbl = RCLASS_M_TBL(clone) = st_init_numtable();
00174         data.klass = clone;
00175         st_foreach(RCLASS_M_TBL(orig), clone_method,
00176                    (st_data_t)&data);
00177     }
00178 
00179     return clone;
00180 }
00181 
00182 /* :nodoc: */
00183 VALUE
00184 rb_class_init_copy(VALUE clone, VALUE orig)
00185 {
00186     if (orig == rb_cBasicObject) {
00187         rb_raise(rb_eTypeError, "can't copy the root class");
00188     }
00189     if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) {
00190         rb_raise(rb_eTypeError, "already initialized class");
00191     }
00192     if (FL_TEST(orig, FL_SINGLETON)) {
00193         rb_raise(rb_eTypeError, "can't copy singleton class");
00194     }
00195     return rb_mod_init_copy(clone, orig);
00196 }
00197 
00198 VALUE
00199 rb_singleton_class_clone(VALUE obj)
00200 {
00201     VALUE klass = RBASIC(obj)->klass;
00202 
00203     if (!FL_TEST(klass, FL_SINGLETON))
00204         return klass;
00205     else {
00206         struct clone_method_data data;
00207         /* copy singleton(unnamed) class */
00208         VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
00209 
00210         if (BUILTIN_TYPE(obj) == T_CLASS) {
00211             RBASIC(clone)->klass = (VALUE)clone;
00212         }
00213         else {
00214             RBASIC(clone)->klass = rb_singleton_class_clone(klass);
00215         }
00216 
00217         RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
00218         if (RCLASS_IV_TBL(klass)) {
00219             RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
00220         }
00221         RCLASS_M_TBL(clone) = st_init_numtable();
00222         data.tbl = RCLASS_M_TBL(clone);
00223         data.klass = (VALUE)clone;
00224         st_foreach(RCLASS_M_TBL(klass), clone_method,
00225                    (st_data_t)&data);
00226         rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
00227         FL_SET(clone, FL_SINGLETON);
00228         return (VALUE)clone;
00229     }
00230 }
00231 
00236 void
00237 rb_singleton_class_attached(VALUE klass, VALUE obj)
00238 {
00239     if (FL_TEST(klass, FL_SINGLETON)) {
00240         if (!RCLASS_IV_TBL(klass)) {
00241             RCLASS_IV_TBL(klass) = st_init_numtable();
00242         }
00243         st_insert(RCLASS_IV_TBL(klass), id_attached, obj);
00244     }
00245 }
00246 
00247 
00248 
00249 #define METACLASS_OF(k) RBASIC(k)->klass
00250 
00256 #define META_CLASS_OF_CLASS_CLASS_P(k)  (METACLASS_OF(k) == k)
00257 
00258 
00266 #define ENSURE_EIGENCLASS(klass) \
00267  (rb_ivar_get(METACLASS_OF(klass), id_attached) == klass ? METACLASS_OF(klass) : make_metaclass(klass))
00268 
00269 
00279 static inline VALUE
00280 make_metaclass(VALUE klass)
00281 {
00282     VALUE super;
00283     VALUE metaclass = rb_class_boot(Qundef);
00284 
00285     FL_SET(metaclass, FL_SINGLETON);
00286     rb_singleton_class_attached(metaclass, klass);
00287 
00288     if (META_CLASS_OF_CLASS_CLASS_P(klass)) {
00289         METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass;
00290     }
00291     else {
00292         VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */
00293         METACLASS_OF(klass) = metaclass;
00294         METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp);
00295     }
00296 
00297     super = RCLASS_SUPER(klass);
00298     while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
00299     RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass;
00300 
00301     OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass));
00302 
00303     return metaclass;
00304 }
00305 
00312 static inline VALUE
00313 make_singleton_class(VALUE obj)
00314 {
00315     VALUE orig_class = RBASIC(obj)->klass;
00316     VALUE klass = rb_class_boot(orig_class);
00317 
00318     FL_SET(klass, FL_SINGLETON);
00319     RBASIC(obj)->klass = klass;
00320     rb_singleton_class_attached(klass, obj);
00321 
00322     METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class));
00323     return klass;
00324 }
00325 
00326 
00327 static VALUE
00328 boot_defclass(const char *name, VALUE super)
00329 {
00330     extern st_table *rb_class_tbl;
00331     VALUE obj = rb_class_boot(super);
00332     ID id = rb_intern(name);
00333 
00334     rb_name_class(obj, id);
00335     st_add_direct(rb_class_tbl, id, obj);
00336     rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
00337     return obj;
00338 }
00339 
00340 void
00341 Init_class_hierarchy(void)
00342 {
00343     id_attached = rb_intern("__attached__");
00344 
00345     rb_cBasicObject = boot_defclass("BasicObject", 0);
00346     rb_cObject = boot_defclass("Object", rb_cBasicObject);
00347     rb_cModule = boot_defclass("Module", rb_cObject);
00348     rb_cClass =  boot_defclass("Class",  rb_cModule);
00349 
00350     rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject);
00351     RBASIC(rb_cClass)->klass
00352         = RBASIC(rb_cModule)->klass
00353         = RBASIC(rb_cObject)->klass
00354         = RBASIC(rb_cBasicObject)->klass
00355         = rb_cClass;
00356 }
00357 
00358 
00369 VALUE
00370 rb_make_metaclass(VALUE obj, VALUE unused)
00371 {
00372     if (BUILTIN_TYPE(obj) == T_CLASS) {
00373         return make_metaclass(obj);
00374     }
00375     else {
00376         return make_singleton_class(obj);
00377     }
00378 }
00379 
00380 
00391 VALUE
00392 rb_define_class_id(ID id, VALUE super)
00393 {
00394     VALUE klass;
00395 
00396     if (!super) super = rb_cObject;
00397     klass = rb_class_new(super);
00398     rb_make_metaclass(klass, RBASIC(super)->klass);
00399 
00400     return klass;
00401 }
00402 
00403 
00412 VALUE
00413 rb_class_inherited(VALUE super, VALUE klass)
00414 {
00415     ID inherited;
00416     if (!super) super = rb_cObject;
00417     CONST_ID(inherited, "inherited");
00418     return rb_funcall(super, inherited, 1, klass);
00419 }
00420 
00421 
00422 
00438 VALUE
00439 rb_define_class(const char *name, VALUE super)
00440 {
00441     VALUE klass;
00442     ID id;
00443 
00444     id = rb_intern(name);
00445     if (rb_const_defined(rb_cObject, id)) {
00446         klass = rb_const_get(rb_cObject, id);
00447         if (TYPE(klass) != T_CLASS) {
00448             rb_raise(rb_eTypeError, "%s is not a class", name);
00449         }
00450         if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00451             rb_raise(rb_eTypeError, "superclass mismatch for class %s", name);
00452         }
00453         return klass;
00454     }
00455     if (!super) {
00456         rb_warn("no super class for `%s', Object assumed", name);
00457     }
00458     klass = rb_define_class_id(id, super);
00459     st_add_direct(rb_class_tbl, id, klass);
00460     rb_name_class(klass, id);
00461     rb_const_set(rb_cObject, id, klass);
00462     rb_class_inherited(super, klass);
00463 
00464     return klass;
00465 }
00466 
00467 
00484 VALUE
00485 rb_define_class_under(VALUE outer, const char *name, VALUE super)
00486 {
00487     return rb_define_class_id_under(outer, rb_intern(name), super);
00488 }
00489 
00490 
00507 VALUE
00508 rb_define_class_id_under(VALUE outer, ID id, VALUE super)
00509 {
00510     VALUE klass;
00511 
00512     if (rb_const_defined_at(outer, id)) {
00513         klass = rb_const_get_at(outer, id);
00514         if (TYPE(klass) != T_CLASS) {
00515             rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
00516         }
00517         if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00518             rb_name_error(id, "%s is already defined", rb_id2name(id));
00519         }
00520         return klass;
00521     }
00522     if (!super) {
00523         rb_warn("no super class for `%s::%s', Object assumed",
00524                 rb_class2name(outer), rb_id2name(id));
00525     }
00526     klass = rb_define_class_id(id, super);
00527     rb_set_class_path_string(klass, outer, rb_id2str(id));
00528     rb_const_set(outer, id, klass);
00529     rb_class_inherited(super, klass);
00530     rb_gc_register_mark_object(klass);
00531 
00532     return klass;
00533 }
00534 
00535 VALUE
00536 rb_module_new(void)
00537 {
00538     VALUE mdl = class_alloc(T_MODULE, rb_cModule);
00539 
00540     RCLASS_M_TBL(mdl) = st_init_numtable();
00541 
00542     return (VALUE)mdl;
00543 }
00544 
00545 VALUE
00546 rb_define_module_id(ID id)
00547 {
00548     VALUE mdl;
00549 
00550     mdl = rb_module_new();
00551     rb_name_class(mdl, id);
00552 
00553     return mdl;
00554 }
00555 
00556 VALUE
00557 rb_define_module(const char *name)
00558 {
00559     VALUE module;
00560     ID id;
00561 
00562     id = rb_intern(name);
00563     if (rb_const_defined(rb_cObject, id)) {
00564         module = rb_const_get(rb_cObject, id);
00565         if (TYPE(module) == T_MODULE)
00566             return module;
00567         rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
00568     }
00569     module = rb_define_module_id(id);
00570     st_add_direct(rb_class_tbl, id, module);
00571     rb_const_set(rb_cObject, id, module);
00572 
00573     return module;
00574 }
00575 
00576 VALUE
00577 rb_define_module_under(VALUE outer, const char *name)
00578 {
00579     return rb_define_module_id_under(outer, rb_intern(name));
00580 }
00581 
00582 VALUE
00583 rb_define_module_id_under(VALUE outer, ID id)
00584 {
00585     VALUE module;
00586 
00587     if (rb_const_defined_at(outer, id)) {
00588         module = rb_const_get_at(outer, id);
00589         if (TYPE(module) == T_MODULE)
00590             return module;
00591         rb_raise(rb_eTypeError, "%s::%s is not a module",
00592                  rb_class2name(outer), rb_obj_classname(module));
00593     }
00594     module = rb_define_module_id(id);
00595     rb_const_set(outer, id, module);
00596     rb_set_class_path_string(module, outer, rb_id2str(id));
00597     rb_gc_register_mark_object(module);
00598 
00599     return module;
00600 }
00601 
00602 static VALUE
00603 include_class_new(VALUE module, VALUE super)
00604 {
00605     VALUE klass = class_alloc(T_ICLASS, rb_cClass);
00606 
00607     if (BUILTIN_TYPE(module) == T_ICLASS) {
00608         module = RBASIC(module)->klass;
00609     }
00610     if (!RCLASS_IV_TBL(module)) {
00611         RCLASS_IV_TBL(module) = st_init_numtable();
00612     }
00613     RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
00614     RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
00615     RCLASS_SUPER(klass) = super;
00616     if (TYPE(module) == T_ICLASS) {
00617         RBASIC(klass)->klass = RBASIC(module)->klass;
00618     }
00619     else {
00620         RBASIC(klass)->klass = module;
00621     }
00622     OBJ_INFECT(klass, module);
00623     OBJ_INFECT(klass, super);
00624 
00625     return (VALUE)klass;
00626 }
00627 
00628 void
00629 rb_include_module(VALUE klass, VALUE module)
00630 {
00631     VALUE p, c;
00632     int changed = 0;
00633 
00634     rb_frozen_class_p(klass);
00635     if (!OBJ_UNTRUSTED(klass)) {
00636         rb_secure(4);
00637     }
00638 
00639     if (TYPE(module) != T_MODULE) {
00640         Check_Type(module, T_MODULE);
00641     }
00642 
00643     OBJ_INFECT(klass, module);
00644     c = klass;
00645     while (module) {
00646         int superclass_seen = FALSE;
00647 
00648         if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
00649             rb_raise(rb_eArgError, "cyclic include detected");
00650         /* ignore if the module included already in superclasses */
00651         for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
00652             switch (BUILTIN_TYPE(p)) {
00653               case T_ICLASS:
00654                 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
00655                     if (!superclass_seen) {
00656                         c = p;  /* move insertion point */
00657                     }
00658                     goto skip;
00659                 }
00660                 break;
00661               case T_CLASS:
00662                 superclass_seen = TRUE;
00663                 break;
00664             }
00665         }
00666         c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
00667         changed = 1;
00668       skip:
00669         module = RCLASS_SUPER(module);
00670     }
00671     if (changed) rb_clear_cache();
00672 }
00673 
00674 /*
00675  *  call-seq:
00676  *     mod.included_modules -> array
00677  *
00678  *  Returns the list of modules included in <i>mod</i>.
00679  *
00680  *     module Mixin
00681  *     end
00682  *
00683  *     module Outer
00684  *       include Mixin
00685  *     end
00686  *
00687  *     Mixin.included_modules   #=> []
00688  *     Outer.included_modules   #=> [Mixin]
00689  */
00690 
00691 VALUE
00692 rb_mod_included_modules(VALUE mod)
00693 {
00694     VALUE ary = rb_ary_new();
00695     VALUE p;
00696 
00697     for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00698         if (BUILTIN_TYPE(p) == T_ICLASS) {
00699             rb_ary_push(ary, RBASIC(p)->klass);
00700         }
00701     }
00702     return ary;
00703 }
00704 
00705 /*
00706  *  call-seq:
00707  *     mod.include?(module)    -> true or false
00708  *
00709  *  Returns <code>true</code> if <i>module</i> is included in
00710  *  <i>mod</i> or one of <i>mod</i>'s ancestors.
00711  *
00712  *     module A
00713  *     end
00714  *     class B
00715  *       include A
00716  *     end
00717  *     class C < B
00718  *     end
00719  *     B.include?(A)   #=> true
00720  *     C.include?(A)   #=> true
00721  *     A.include?(A)   #=> false
00722  */
00723 
00724 VALUE
00725 rb_mod_include_p(VALUE mod, VALUE mod2)
00726 {
00727     VALUE p;
00728 
00729     Check_Type(mod2, T_MODULE);
00730     for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00731         if (BUILTIN_TYPE(p) == T_ICLASS) {
00732             if (RBASIC(p)->klass == mod2) return Qtrue;
00733         }
00734     }
00735     return Qfalse;
00736 }
00737 
00738 /*
00739  *  call-seq:
00740  *     mod.ancestors -> array
00741  *
00742  *  Returns a list of modules included in <i>mod</i> (including
00743  *  <i>mod</i> itself).
00744  *
00745  *     module Mod
00746  *       include Math
00747  *       include Comparable
00748  *     end
00749  *
00750  *     Mod.ancestors    #=> [Mod, Comparable, Math]
00751  *     Math.ancestors   #=> [Math]
00752  */
00753 
00754 VALUE
00755 rb_mod_ancestors(VALUE mod)
00756 {
00757     VALUE p, ary = rb_ary_new();
00758 
00759     for (p = mod; p; p = RCLASS_SUPER(p)) {
00760         if (FL_TEST(p, FL_SINGLETON))
00761             continue;
00762         if (BUILTIN_TYPE(p) == T_ICLASS) {
00763             rb_ary_push(ary, RBASIC(p)->klass);
00764         }
00765         else {
00766             rb_ary_push(ary, p);
00767         }
00768     }
00769     return ary;
00770 }
00771 
00772 #define VISI(x) ((x)&NOEX_MASK)
00773 #define VISI_CHECK(x,f) (VISI(x) == (f))
00774 
00775 static int
00776 ins_methods_push(ID name, long type, VALUE ary, long visi)
00777 {
00778     if (type == -1) return ST_CONTINUE;
00779 
00780     switch (visi) {
00781       case NOEX_PRIVATE:
00782       case NOEX_PROTECTED:
00783       case NOEX_PUBLIC:
00784         visi = (type == visi);
00785         break;
00786       default:
00787         visi = (type != NOEX_PRIVATE);
00788         break;
00789     }
00790     if (visi) {
00791         rb_ary_push(ary, ID2SYM(name));
00792     }
00793     return ST_CONTINUE;
00794 }
00795 
00796 static int
00797 ins_methods_i(ID name, long type, VALUE ary)
00798 {
00799     return ins_methods_push(name, type, ary, -1); /* everything but private */
00800 }
00801 
00802 static int
00803 ins_methods_prot_i(ID name, long type, VALUE ary)
00804 {
00805     return ins_methods_push(name, type, ary, NOEX_PROTECTED);
00806 }
00807 
00808 static int
00809 ins_methods_priv_i(ID name, long type, VALUE ary)
00810 {
00811     return ins_methods_push(name, type, ary, NOEX_PRIVATE);
00812 }
00813 
00814 static int
00815 ins_methods_pub_i(ID name, long type, VALUE ary)
00816 {
00817     return ins_methods_push(name, type, ary, NOEX_PUBLIC);
00818 }
00819 
00820 static int
00821 method_entry(ID key, const rb_method_entry_t *me, st_table *list)
00822 {
00823     long type;
00824 
00825     if (key == ID_ALLOCATOR) {
00826         return ST_CONTINUE;
00827     }
00828 
00829     if (!st_lookup(list, key, 0)) {
00830         if (UNDEFINED_METHOD_ENTRY_P(me)) {
00831             type = -1; /* none */
00832         }
00833         else {
00834             type = VISI(me->flag);
00835         }
00836         st_add_direct(list, key, type);
00837     }
00838     return ST_CONTINUE;
00839 }
00840 
00841 static VALUE
00842 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (ID, long, VALUE))
00843 {
00844     VALUE ary;
00845     int recur;
00846     st_table *list;
00847 
00848     if (argc == 0) {
00849         recur = TRUE;
00850     }
00851     else {
00852         VALUE r;
00853         rb_scan_args(argc, argv, "01", &r);
00854         recur = RTEST(r);
00855     }
00856 
00857     list = st_init_numtable();
00858     for (; mod; mod = RCLASS_SUPER(mod)) {
00859         st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
00860         if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
00861         if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
00862         if (!recur) break;
00863     }
00864     ary = rb_ary_new();
00865     st_foreach(list, func, ary);
00866     st_free_table(list);
00867 
00868     return ary;
00869 }
00870 
00871 /*
00872  *  call-seq:
00873  *     mod.instance_methods(include_super=true)   -> array
00874  *
00875  *  Returns an array containing the names of the public and protected instance
00876  *  methods in the receiver. For a module, these are the public and protected methods;
00877  *  for a class, they are the instance (not singleton) methods. With no
00878  *  argument, or with an argument that is <code>false</code>, the
00879  *  instance methods in <i>mod</i> are returned, otherwise the methods
00880  *  in <i>mod</i> and <i>mod</i>'s superclasses are returned.
00881  *
00882  *     module A
00883  *       def method1()  end
00884  *     end
00885  *     class B
00886  *       def method2()  end
00887  *     end
00888  *     class C < B
00889  *       def method3()  end
00890  *     end
00891  *
00892  *     A.instance_methods                #=> [:method1]
00893  *     B.instance_methods(false)         #=> [:method2]
00894  *     C.instance_methods(false)         #=> [:method3]
00895  *     C.instance_methods(true).length   #=> 43
00896  */
00897 
00898 VALUE
00899 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod)
00900 {
00901     return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
00902 }
00903 
00904 /*
00905  *  call-seq:
00906  *     mod.protected_instance_methods(include_super=true)   -> array
00907  *
00908  *  Returns a list of the protected instance methods defined in
00909  *  <i>mod</i>. If the optional parameter is not <code>false</code>, the
00910  *  methods of any ancestors are included.
00911  */
00912 
00913 VALUE
00914 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod)
00915 {
00916     return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
00917 }
00918 
00919 /*
00920  *  call-seq:
00921  *     mod.private_instance_methods(include_super=true)    -> array
00922  *
00923  *  Returns a list of the private instance methods defined in
00924  *  <i>mod</i>. If the optional parameter is not <code>false</code>, the
00925  *  methods of any ancestors are included.
00926  *
00927  *     module Mod
00928  *       def method1()  end
00929  *       private :method1
00930  *       def method2()  end
00931  *     end
00932  *     Mod.instance_methods           #=> [:method2]
00933  *     Mod.private_instance_methods   #=> [:method1]
00934  */
00935 
00936 VALUE
00937 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod)
00938 {
00939     return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
00940 }
00941 
00942 /*
00943  *  call-seq:
00944  *     mod.public_instance_methods(include_super=true)   -> array
00945  *
00946  *  Returns a list of the public instance methods defined in <i>mod</i>.
00947  *  If the optional parameter is not <code>false</code>, the methods of
00948  *  any ancestors are included.
00949  */
00950 
00951 VALUE
00952 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
00953 {
00954     return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
00955 }
00956 
00957 /*
00958  *  call-seq:
00959  *     obj.methods    -> array
00960  *
00961  *  Returns a list of the names of methods publicly accessible in
00962  *  <i>obj</i>. This will include all the methods accessible in
00963  *  <i>obj</i>'s ancestors.
00964  *
00965  *     class Klass
00966  *       def kMethod()
00967  *       end
00968  *     end
00969  *     k = Klass.new
00970  *     k.methods[0..9]    #=> [:kMethod, :freeze, :nil?, :is_a?,
00971  *                        #    :class, :instance_variable_set,
00972  *                        #    :methods, :extend, :__send__, :instance_eval]
00973  *     k.methods.length   #=> 42
00974  */
00975 
00976 VALUE
00977 rb_obj_methods(int argc, VALUE *argv, VALUE obj)
00978 {
00979   retry:
00980     if (argc == 0) {
00981         VALUE args[1];
00982 
00983         args[0] = Qtrue;
00984         return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
00985     }
00986     else {
00987         VALUE recur;
00988 
00989         rb_scan_args(argc, argv, "1", &recur);
00990         if (RTEST(recur)) {
00991             argc = 0;
00992             goto retry;
00993         }
00994         return rb_obj_singleton_methods(argc, argv, obj);
00995     }
00996 }
00997 
00998 /*
00999  *  call-seq:
01000  *     obj.protected_methods(all=true)   -> array
01001  *
01002  *  Returns the list of protected methods accessible to <i>obj</i>. If
01003  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
01004  *  in the receiver will be listed.
01005  */
01006 
01007 VALUE
01008 rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj)
01009 {
01010     return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
01011 }
01012 
01013 /*
01014  *  call-seq:
01015  *     obj.private_methods(all=true)   -> array
01016  *
01017  *  Returns the list of private methods accessible to <i>obj</i>. If
01018  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
01019  *  in the receiver will be listed.
01020  */
01021 
01022 VALUE
01023 rb_obj_private_methods(int argc, VALUE *argv, VALUE obj)
01024 {
01025     return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
01026 }
01027 
01028 /*
01029  *  call-seq:
01030  *     obj.public_methods(all=true)   -> array
01031  *
01032  *  Returns the list of public methods accessible to <i>obj</i>. If
01033  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
01034  *  in the receiver will be listed.
01035  */
01036 
01037 VALUE
01038 rb_obj_public_methods(int argc, VALUE *argv, VALUE obj)
01039 {
01040     return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
01041 }
01042 
01043 /*
01044  *  call-seq:
01045  *     obj.singleton_methods(all=true)    -> array
01046  *
01047  *  Returns an array of the names of singleton methods for <i>obj</i>.
01048  *  If the optional <i>all</i> parameter is true, the list will include
01049  *  methods in modules included in <i>obj</i>.
01050  *  Only public and protected singleton methods are returned.
01051  *
01052  *     module Other
01053  *       def three() end
01054  *     end
01055  *
01056  *     class Single
01057  *       def Single.four() end
01058  *     end
01059  *
01060  *     a = Single.new
01061  *
01062  *     def a.one()
01063  *     end
01064  *
01065  *     class << a
01066  *       include Other
01067  *       def two()
01068  *       end
01069  *     end
01070  *
01071  *     Single.singleton_methods    #=> [:four]
01072  *     a.singleton_methods(false)  #=> [:two, :one]
01073  *     a.singleton_methods         #=> [:two, :one, :three]
01074  */
01075 
01076 VALUE
01077 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
01078 {
01079     VALUE recur, ary, klass;
01080     st_table *list;
01081 
01082     if (argc == 0) {
01083         recur = Qtrue;
01084     }
01085     else {
01086         rb_scan_args(argc, argv, "01", &recur);
01087     }
01088     klass = CLASS_OF(obj);
01089     list = st_init_numtable();
01090     if (klass && FL_TEST(klass, FL_SINGLETON)) {
01091         st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
01092         klass = RCLASS_SUPER(klass);
01093     }
01094     if (RTEST(recur)) {
01095         while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
01096             st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
01097             klass = RCLASS_SUPER(klass);
01098         }
01099     }
01100     ary = rb_ary_new();
01101     st_foreach(list, ins_methods_i, ary);
01102     st_free_table(list);
01103 
01104     return ary;
01105 }
01106 
01164 void
01165 rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
01166 {
01167     rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC);
01168 }
01169 
01170 void
01171 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01172 {
01173     rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC);
01174 }
01175 
01176 void
01177 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01178 {
01179     rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED);
01180 }
01181 
01182 void
01183 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01184 {
01185     rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE);
01186 }
01187 
01188 void
01189 rb_undef_method(VALUE klass, const char *name)
01190 {
01191     rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF);
01192 }
01193 
01202 #define SPECIAL_SINGLETON(x,c) do {\
01203     if (obj == (x)) {\
01204         return c;\
01205     }\
01206 } while (0)
01207 
01208 
01218 static VALUE
01219 singleton_class_of(VALUE obj)
01220 {
01221     VALUE klass;
01222 
01223     if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
01224         rb_raise(rb_eTypeError, "can't define singleton");
01225     }
01226     if (rb_special_const_p(obj)) {
01227         SPECIAL_SINGLETON(Qnil, rb_cNilClass);
01228         SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
01229         SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
01230         rb_bug("unknown immediate %ld", obj);
01231     }
01232 
01233     if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
01234         rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) {
01235         klass = RBASIC(obj)->klass;
01236     }
01237     else {
01238         klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
01239     }
01240 
01241     if (OBJ_TAINTED(obj)) {
01242         OBJ_TAINT(klass);
01243     }
01244     else {
01245         FL_UNSET(klass, FL_TAINT);
01246     }
01247     if (OBJ_UNTRUSTED(obj)) {
01248         OBJ_UNTRUST(klass);
01249     }
01250     else {
01251         FL_UNSET(klass, FL_UNTRUSTED);
01252     }
01253     if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
01254 
01255     return klass;
01256 }
01257 
01258 
01276 VALUE
01277 rb_singleton_class(VALUE obj)
01278 {
01279     VALUE klass = singleton_class_of(obj);
01280 
01281     /* ensures an exposed class belongs to its own eigenclass */
01282     if (TYPE(obj) == T_CLASS) ENSURE_EIGENCLASS(klass);
01283 
01284     return klass;
01285 }
01286 
01303 void
01304 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
01305 {
01306     rb_define_method(singleton_class_of(obj), name, func, argc);
01307 }
01308 
01309 
01310 
01318 void
01319 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
01320 {
01321     rb_define_private_method(module, name, func, argc);
01322     rb_define_singleton_method(module, name, func, argc);
01323 }
01324 
01325 
01332 void
01333 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
01334 {
01335     rb_define_module_function(rb_mKernel, name, func, argc);
01336 }
01337 
01338 
01345 void
01346 rb_define_alias(VALUE klass, const char *name1, const char *name2)
01347 {
01348     rb_alias(klass, rb_intern(name1), rb_intern(name2));
01349 }
01350 
01358 void
01359 rb_define_attr(VALUE klass, const char *name, int read, int write)
01360 {
01361     rb_attr(klass, rb_intern(name), read, write, FALSE);
01362 }
01363 
01364 int
01365 rb_obj_basic_to_s_p(VALUE obj)
01366 {
01367     const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s"));
01368     if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
01369         me->def->body.cfunc.func == rb_any_to_s)
01370         return 1;
01371     return 0;
01372 }
01373 
01374 #include <stdarg.h>
01375 
01376 int
01377 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
01378 {
01379     int i;
01380     const char *p = fmt;
01381     VALUE *var;
01382     va_list vargs;
01383     int f_var = 0, f_block = 0;
01384     int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
01385     int argi = 0;
01386 
01387     if (ISDIGIT(*p)) {
01388         n_lead = *p - '0';
01389         p++;
01390         if (ISDIGIT(*p)) {
01391             n_opt = *p - '0';
01392             p++;
01393             if (ISDIGIT(*p)) {
01394                 n_trail = *p - '0';
01395                 p++;
01396                 goto block_arg;
01397             }
01398         }
01399     }
01400     if (*p == '*') {
01401         f_var = 1;
01402         p++;
01403         if (ISDIGIT(*p)) {
01404             n_trail = *p - '0';
01405             p++;
01406         }
01407     }
01408   block_arg:
01409     if (*p == '&') {
01410         f_block = 1;
01411         p++;
01412     }
01413     if (*p != '\0') {
01414         rb_fatal("bad scan arg format: %s", fmt);
01415     }
01416     n_mand = n_lead + n_trail;
01417 
01418     if (argc < n_mand)
01419         goto argc_error;
01420 
01421     va_start(vargs, fmt);
01422 
01423     /* capture leading mandatory arguments */
01424     for (i = n_lead; i-- > 0; ) {
01425         var = va_arg(vargs, VALUE *);
01426         if (var) *var = argv[argi];
01427         argi++;
01428     }
01429     /* capture optional arguments */
01430     for (i = n_opt; i-- > 0; ) {
01431         var = va_arg(vargs, VALUE *);
01432         if (argi < argc - n_trail) {
01433             if (var) *var = argv[argi];
01434             argi++;
01435         }
01436         else {
01437             if (var) *var = Qnil;
01438         }
01439     }
01440     /* capture variable length arguments */
01441     if (f_var) {
01442         int n_var = argc - argi - n_trail;
01443 
01444         var = va_arg(vargs, VALUE *);
01445         if (0 < n_var) {
01446             if (var) *var = rb_ary_new4(n_var, &argv[argi]);
01447             argi += n_var;
01448         }
01449         else {
01450             if (var) *var = rb_ary_new();
01451         }
01452     }
01453     /* capture trailing mandatory arguments */
01454     for (i = n_trail; i-- > 0; ) {
01455         var = va_arg(vargs, VALUE *);
01456         if (var) *var = argv[argi];
01457         argi++;
01458     }
01459     /* capture iterator block */
01460     if (f_block) {
01461         var = va_arg(vargs, VALUE *);
01462         if (rb_block_given_p()) {
01463             *var = rb_block_proc();
01464         }
01465         else {
01466             *var = Qnil;
01467         }
01468     }
01469     va_end(vargs);
01470 
01471     if (argi < argc)
01472         goto argc_error;
01473 
01474     return argc;
01475 
01476   argc_error:
01477     if (0 < n_opt)
01478         rb_raise(rb_eArgError, "wrong number of arguments (%d for %d..%d%s)",
01479                  argc, n_mand, n_mand + n_opt, f_var ? "+" : "");
01480     else
01481         rb_raise(rb_eArgError, "wrong number of arguments (%d for %d%s)",
01482                  argc, n_mand, f_var ? "+" : "");
01483 }
01484 

Generated on Sat Jul 7 2012 15:26:29 for Ruby by  doxygen 1.7.1