• 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     RBASIC(rb_cClass)->klass
00351         = RBASIC(rb_cModule)->klass
00352         = RBASIC(rb_cObject)->klass
00353         = RBASIC(rb_cBasicObject)->klass
00354         = rb_cClass;
00355 }
00356 
00357 
00368 VALUE
00369 rb_make_metaclass(VALUE obj, VALUE unused)
00370 {
00371     if (BUILTIN_TYPE(obj) == T_CLASS) {
00372         return make_metaclass(obj);
00373     }
00374     else {
00375         return make_singleton_class(obj);
00376     }
00377 }
00378 
00379 
00390 VALUE
00391 rb_define_class_id(ID id, VALUE super)
00392 {
00393     VALUE klass;
00394 
00395     if (!super) super = rb_cObject;
00396     klass = rb_class_new(super);
00397     rb_make_metaclass(klass, RBASIC(super)->klass);
00398 
00399     return klass;
00400 }
00401 
00402 
00411 VALUE
00412 rb_class_inherited(VALUE super, VALUE klass)
00413 {
00414     ID inherited;
00415     if (!super) super = rb_cObject;
00416     CONST_ID(inherited, "inherited");
00417     return rb_funcall(super, inherited, 1, klass);
00418 }
00419 
00420 
00421 
00437 VALUE
00438 rb_define_class(const char *name, VALUE super)
00439 {
00440     VALUE klass;
00441     ID id;
00442 
00443     id = rb_intern(name);
00444     if (rb_const_defined(rb_cObject, id)) {
00445         klass = rb_const_get(rb_cObject, id);
00446         if (TYPE(klass) != T_CLASS) {
00447             rb_raise(rb_eTypeError, "%s is not a class", name);
00448         }
00449         if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00450             rb_raise(rb_eTypeError, "superclass mismatch for class %s", name);
00451         }
00452         return klass;
00453     }
00454     if (!super) {
00455         rb_warn("no super class for `%s', Object assumed", name);
00456     }
00457     klass = rb_define_class_id(id, super);
00458     st_add_direct(rb_class_tbl, id, klass);
00459     rb_name_class(klass, id);
00460     rb_const_set(rb_cObject, id, klass);
00461     rb_class_inherited(super, klass);
00462 
00463     return klass;
00464 }
00465 
00466 
00483 VALUE
00484 rb_define_class_under(VALUE outer, const char *name, VALUE super)
00485 {
00486     return rb_define_class_id_under(outer, rb_intern(name), super);
00487 }
00488 
00489 
00506 VALUE
00507 rb_define_class_id_under(VALUE outer, ID id, VALUE super)
00508 {
00509     VALUE klass;
00510 
00511     if (rb_const_defined_at(outer, id)) {
00512         klass = rb_const_get_at(outer, id);
00513         if (TYPE(klass) != T_CLASS) {
00514             rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
00515         }
00516         if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00517             rb_name_error(id, "%s is already defined", rb_id2name(id));
00518         }
00519         return klass;
00520     }
00521     if (!super) {
00522         rb_warn("no super class for `%s::%s', Object assumed",
00523                 rb_class2name(outer), rb_id2name(id));
00524     }
00525     klass = rb_define_class_id(id, super);
00526     rb_set_class_path_string(klass, outer, rb_id2str(id));
00527     rb_const_set(outer, id, klass);
00528     rb_class_inherited(super, klass);
00529     rb_gc_register_mark_object(klass);
00530 
00531     return klass;
00532 }
00533 
00534 VALUE
00535 rb_module_new(void)
00536 {
00537     VALUE mdl = class_alloc(T_MODULE, rb_cModule);
00538 
00539     RCLASS_M_TBL(mdl) = st_init_numtable();
00540 
00541     return (VALUE)mdl;
00542 }
00543 
00544 VALUE
00545 rb_define_module_id(ID id)
00546 {
00547     VALUE mdl;
00548 
00549     mdl = rb_module_new();
00550     rb_name_class(mdl, id);
00551 
00552     return mdl;
00553 }
00554 
00555 VALUE
00556 rb_define_module(const char *name)
00557 {
00558     VALUE module;
00559     ID id;
00560 
00561     id = rb_intern(name);
00562     if (rb_const_defined(rb_cObject, id)) {
00563         module = rb_const_get(rb_cObject, id);
00564         if (TYPE(module) == T_MODULE)
00565             return module;
00566         rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
00567     }
00568     module = rb_define_module_id(id);
00569     st_add_direct(rb_class_tbl, id, module);
00570     rb_const_set(rb_cObject, id, module);
00571 
00572     return module;
00573 }
00574 
00575 VALUE
00576 rb_define_module_under(VALUE outer, const char *name)
00577 {
00578     return rb_define_module_id_under(outer, rb_intern(name));
00579 }
00580 
00581 VALUE
00582 rb_define_module_id_under(VALUE outer, ID id)
00583 {
00584     VALUE module;
00585 
00586     if (rb_const_defined_at(outer, id)) {
00587         module = rb_const_get_at(outer, id);
00588         if (TYPE(module) == T_MODULE)
00589             return module;
00590         rb_raise(rb_eTypeError, "%s::%s is not a module",
00591                  rb_class2name(outer), rb_obj_classname(module));
00592     }
00593     module = rb_define_module_id(id);
00594     rb_const_set(outer, id, module);
00595     rb_set_class_path_string(module, outer, rb_id2str(id));
00596     rb_gc_register_mark_object(module);
00597 
00598     return module;
00599 }
00600 
00601 static VALUE
00602 include_class_new(VALUE module, VALUE super)
00603 {
00604     VALUE klass = class_alloc(T_ICLASS, rb_cClass);
00605 
00606     if (BUILTIN_TYPE(module) == T_ICLASS) {
00607         module = RBASIC(module)->klass;
00608     }
00609     if (!RCLASS_IV_TBL(module)) {
00610         RCLASS_IV_TBL(module) = st_init_numtable();
00611     }
00612     RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
00613     RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
00614     RCLASS_SUPER(klass) = super;
00615     if (TYPE(module) == T_ICLASS) {
00616         RBASIC(klass)->klass = RBASIC(module)->klass;
00617     }
00618     else {
00619         RBASIC(klass)->klass = module;
00620     }
00621     OBJ_INFECT(klass, module);
00622     OBJ_INFECT(klass, super);
00623 
00624     return (VALUE)klass;
00625 }
00626 
00627 void
00628 rb_include_module(VALUE klass, VALUE module)
00629 {
00630     VALUE p, c;
00631     int changed = 0;
00632 
00633     rb_frozen_class_p(klass);
00634     if (!OBJ_UNTRUSTED(klass)) {
00635         rb_secure(4);
00636     }
00637 
00638     if (TYPE(module) != T_MODULE) {
00639         Check_Type(module, T_MODULE);
00640     }
00641 
00642     OBJ_INFECT(klass, module);
00643     c = klass;
00644     while (module) {
00645         int superclass_seen = FALSE;
00646 
00647         if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
00648             rb_raise(rb_eArgError, "cyclic include detected");
00649         /* ignore if the module included already in superclasses */
00650         for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
00651             switch (BUILTIN_TYPE(p)) {
00652               case T_ICLASS:
00653                 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
00654                     if (!superclass_seen) {
00655                         c = p;  /* move insertion point */
00656                     }
00657                     goto skip;
00658                 }
00659                 break;
00660               case T_CLASS:
00661                 superclass_seen = TRUE;
00662                 break;
00663             }
00664         }
00665         c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
00666         changed = 1;
00667       skip:
00668         module = RCLASS_SUPER(module);
00669     }
00670     if (changed) rb_clear_cache();
00671 }
00672 
00673 /*
00674  *  call-seq:
00675  *     mod.included_modules -> array
00676  *
00677  *  Returns the list of modules included in <i>mod</i>.
00678  *
00679  *     module Mixin
00680  *     end
00681  *
00682  *     module Outer
00683  *       include Mixin
00684  *     end
00685  *
00686  *     Mixin.included_modules   #=> []
00687  *     Outer.included_modules   #=> [Mixin]
00688  */
00689 
00690 VALUE
00691 rb_mod_included_modules(VALUE mod)
00692 {
00693     VALUE ary = rb_ary_new();
00694     VALUE p;
00695 
00696     for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00697         if (BUILTIN_TYPE(p) == T_ICLASS) {
00698             rb_ary_push(ary, RBASIC(p)->klass);
00699         }
00700     }
00701     return ary;
00702 }
00703 
00704 /*
00705  *  call-seq:
00706  *     mod.include?(module)    -> true or false
00707  *
00708  *  Returns <code>true</code> if <i>module</i> is included in
00709  *  <i>mod</i> or one of <i>mod</i>'s ancestors.
00710  *
00711  *     module A
00712  *     end
00713  *     class B
00714  *       include A
00715  *     end
00716  *     class C < B
00717  *     end
00718  *     B.include?(A)   #=> true
00719  *     C.include?(A)   #=> true
00720  *     A.include?(A)   #=> false
00721  */
00722 
00723 VALUE
00724 rb_mod_include_p(VALUE mod, VALUE mod2)
00725 {
00726     VALUE p;
00727 
00728     Check_Type(mod2, T_MODULE);
00729     for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00730         if (BUILTIN_TYPE(p) == T_ICLASS) {
00731             if (RBASIC(p)->klass == mod2) return Qtrue;
00732         }
00733     }
00734     return Qfalse;
00735 }
00736 
00737 /*
00738  *  call-seq:
00739  *     mod.ancestors -> array
00740  *
00741  *  Returns a list of modules included in <i>mod</i> (including
00742  *  <i>mod</i> itself).
00743  *
00744  *     module Mod
00745  *       include Math
00746  *       include Comparable
00747  *     end
00748  *
00749  *     Mod.ancestors    #=> [Mod, Comparable, Math]
00750  *     Math.ancestors   #=> [Math]
00751  */
00752 
00753 VALUE
00754 rb_mod_ancestors(VALUE mod)
00755 {
00756     VALUE p, ary = rb_ary_new();
00757 
00758     for (p = mod; p; p = RCLASS_SUPER(p)) {
00759         if (FL_TEST(p, FL_SINGLETON))
00760             continue;
00761         if (BUILTIN_TYPE(p) == T_ICLASS) {
00762             rb_ary_push(ary, RBASIC(p)->klass);
00763         }
00764         else {
00765             rb_ary_push(ary, p);
00766         }
00767     }
00768     return ary;
00769 }
00770 
00771 #define VISI(x) ((x)&NOEX_MASK)
00772 #define VISI_CHECK(x,f) (VISI(x) == (f))
00773 
00774 static int
00775 ins_methods_push(ID name, long type, VALUE ary, long visi)
00776 {
00777     if (type == -1) return ST_CONTINUE;
00778 
00779     switch (visi) {
00780       case NOEX_PRIVATE:
00781       case NOEX_PROTECTED:
00782       case NOEX_PUBLIC:
00783         visi = (type == visi);
00784         break;
00785       default:
00786         visi = (type != NOEX_PRIVATE);
00787         break;
00788     }
00789     if (visi) {
00790         rb_ary_push(ary, ID2SYM(name));
00791     }
00792     return ST_CONTINUE;
00793 }
00794 
00795 static int
00796 ins_methods_i(ID name, long type, VALUE ary)
00797 {
00798     return ins_methods_push(name, type, ary, -1); /* everything but private */
00799 }
00800 
00801 static int
00802 ins_methods_prot_i(ID name, long type, VALUE ary)
00803 {
00804     return ins_methods_push(name, type, ary, NOEX_PROTECTED);
00805 }
00806 
00807 static int
00808 ins_methods_priv_i(ID name, long type, VALUE ary)
00809 {
00810     return ins_methods_push(name, type, ary, NOEX_PRIVATE);
00811 }
00812 
00813 static int
00814 ins_methods_pub_i(ID name, long type, VALUE ary)
00815 {
00816     return ins_methods_push(name, type, ary, NOEX_PUBLIC);
00817 }
00818 
00819 static int
00820 method_entry(ID key, const rb_method_entry_t *me, st_table *list)
00821 {
00822     long type;
00823 
00824     if (key == ID_ALLOCATOR) {
00825         return ST_CONTINUE;
00826     }
00827 
00828     if (!st_lookup(list, key, 0)) {
00829         if (UNDEFINED_METHOD_ENTRY_P(me)) {
00830             type = -1; /* none */
00831         }
00832         else {
00833             type = VISI(me->flag);
00834         }
00835         st_add_direct(list, key, type);
00836     }
00837     return ST_CONTINUE;
00838 }
00839 
00840 static VALUE
00841 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (ID, long, VALUE))
00842 {
00843     VALUE ary;
00844     int recur;
00845     st_table *list;
00846 
00847     if (argc == 0) {
00848         recur = TRUE;
00849     }
00850     else {
00851         VALUE r;
00852         rb_scan_args(argc, argv, "01", &r);
00853         recur = RTEST(r);
00854     }
00855 
00856     list = st_init_numtable();
00857     for (; mod; mod = RCLASS_SUPER(mod)) {
00858         st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
00859         if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
00860         if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
00861         if (!recur) break;
00862     }
00863     ary = rb_ary_new();
00864     st_foreach(list, func, ary);
00865     st_free_table(list);
00866 
00867     return ary;
00868 }
00869 
00870 /*
00871  *  call-seq:
00872  *     mod.instance_methods(include_super=true)   -> array
00873  *
00874  *  Returns an array containing the names of the public and protected instance
00875  *  methods in the receiver. For a module, these are the public and protected methods;
00876  *  for a class, they are the instance (not singleton) methods. With no
00877  *  argument, or with an argument that is <code>false</code>, the
00878  *  instance methods in <i>mod</i> are returned, otherwise the methods
00879  *  in <i>mod</i> and <i>mod</i>'s superclasses are returned.
00880  *
00881  *     module A
00882  *       def method1()  end
00883  *     end
00884  *     class B
00885  *       def method2()  end
00886  *     end
00887  *     class C < B
00888  *       def method3()  end
00889  *     end
00890  *
00891  *     A.instance_methods                #=> [:method1]
00892  *     B.instance_methods(false)         #=> [:method2]
00893  *     C.instance_methods(false)         #=> [:method3]
00894  *     C.instance_methods(true).length   #=> 43
00895  */
00896 
00897 VALUE
00898 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod)
00899 {
00900     return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
00901 }
00902 
00903 /*
00904  *  call-seq:
00905  *     mod.protected_instance_methods(include_super=true)   -> array
00906  *
00907  *  Returns a list of the protected instance methods defined in
00908  *  <i>mod</i>. If the optional parameter is not <code>false</code>, the
00909  *  methods of any ancestors are included.
00910  */
00911 
00912 VALUE
00913 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod)
00914 {
00915     return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
00916 }
00917 
00918 /*
00919  *  call-seq:
00920  *     mod.private_instance_methods(include_super=true)    -> array
00921  *
00922  *  Returns a list of the private instance methods defined in
00923  *  <i>mod</i>. If the optional parameter is not <code>false</code>, the
00924  *  methods of any ancestors are included.
00925  *
00926  *     module Mod
00927  *       def method1()  end
00928  *       private :method1
00929  *       def method2()  end
00930  *     end
00931  *     Mod.instance_methods           #=> [:method2]
00932  *     Mod.private_instance_methods   #=> [:method1]
00933  */
00934 
00935 VALUE
00936 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod)
00937 {
00938     return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
00939 }
00940 
00941 /*
00942  *  call-seq:
00943  *     mod.public_instance_methods(include_super=true)   -> array
00944  *
00945  *  Returns a list of the public instance methods defined in <i>mod</i>.
00946  *  If the optional parameter is not <code>false</code>, the methods of
00947  *  any ancestors are included.
00948  */
00949 
00950 VALUE
00951 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
00952 {
00953     return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
00954 }
00955 
00956 /*
00957  *  call-seq:
00958  *     obj.methods    -> array
00959  *
00960  *  Returns a list of the names of methods publicly accessible in
00961  *  <i>obj</i>. This will include all the methods accessible in
00962  *  <i>obj</i>'s ancestors.
00963  *
00964  *     class Klass
00965  *       def kMethod()
00966  *       end
00967  *     end
00968  *     k = Klass.new
00969  *     k.methods[0..9]    #=> [:kMethod, :freeze, :nil?, :is_a?,
00970  *                        #    :class, :instance_variable_set,
00971  *                        #    :methods, :extend, :__send__, :instance_eval]
00972  *     k.methods.length   #=> 42
00973  */
00974 
00975 VALUE
00976 rb_obj_methods(int argc, VALUE *argv, VALUE obj)
00977 {
00978   retry:
00979     if (argc == 0) {
00980         VALUE args[1];
00981 
00982         args[0] = Qtrue;
00983         return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
00984     }
00985     else {
00986         VALUE recur;
00987 
00988         rb_scan_args(argc, argv, "1", &recur);
00989         if (RTEST(recur)) {
00990             argc = 0;
00991             goto retry;
00992         }
00993         return rb_obj_singleton_methods(argc, argv, obj);
00994     }
00995 }
00996 
00997 /*
00998  *  call-seq:
00999  *     obj.protected_methods(all=true)   -> array
01000  *
01001  *  Returns the list of protected methods accessible to <i>obj</i>. If
01002  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
01003  *  in the receiver will be listed.
01004  */
01005 
01006 VALUE
01007 rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj)
01008 {
01009     return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
01010 }
01011 
01012 /*
01013  *  call-seq:
01014  *     obj.private_methods(all=true)   -> array
01015  *
01016  *  Returns the list of private methods accessible to <i>obj</i>. If
01017  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
01018  *  in the receiver will be listed.
01019  */
01020 
01021 VALUE
01022 rb_obj_private_methods(int argc, VALUE *argv, VALUE obj)
01023 {
01024     return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
01025 }
01026 
01027 /*
01028  *  call-seq:
01029  *     obj.public_methods(all=true)   -> array
01030  *
01031  *  Returns the list of public methods accessible to <i>obj</i>. If
01032  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
01033  *  in the receiver will be listed.
01034  */
01035 
01036 VALUE
01037 rb_obj_public_methods(int argc, VALUE *argv, VALUE obj)
01038 {
01039     return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
01040 }
01041 
01042 /*
01043  *  call-seq:
01044  *     obj.singleton_methods(all=true)    -> array
01045  *
01046  *  Returns an array of the names of singleton methods for <i>obj</i>.
01047  *  If the optional <i>all</i> parameter is true, the list will include
01048  *  methods in modules included in <i>obj</i>.
01049  *  Only public and protected singleton methods are returned.
01050  *
01051  *     module Other
01052  *       def three() end
01053  *     end
01054  *
01055  *     class Single
01056  *       def Single.four() end
01057  *     end
01058  *
01059  *     a = Single.new
01060  *
01061  *     def a.one()
01062  *     end
01063  *
01064  *     class << a
01065  *       include Other
01066  *       def two()
01067  *       end
01068  *     end
01069  *
01070  *     Single.singleton_methods    #=> [:four]
01071  *     a.singleton_methods(false)  #=> [:two, :one]
01072  *     a.singleton_methods         #=> [:two, :one, :three]
01073  */
01074 
01075 VALUE
01076 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
01077 {
01078     VALUE recur, ary, klass;
01079     st_table *list;
01080 
01081     if (argc == 0) {
01082         recur = Qtrue;
01083     }
01084     else {
01085         rb_scan_args(argc, argv, "01", &recur);
01086     }
01087     klass = CLASS_OF(obj);
01088     list = st_init_numtable();
01089     if (klass && FL_TEST(klass, FL_SINGLETON)) {
01090         st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
01091         klass = RCLASS_SUPER(klass);
01092     }
01093     if (RTEST(recur)) {
01094         while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
01095             st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
01096             klass = RCLASS_SUPER(klass);
01097         }
01098     }
01099     ary = rb_ary_new();
01100     st_foreach(list, ins_methods_i, ary);
01101     st_free_table(list);
01102 
01103     return ary;
01104 }
01105 
01163 void
01164 rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
01165 {
01166     rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC);
01167 }
01168 
01169 void
01170 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01171 {
01172     rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC);
01173 }
01174 
01175 void
01176 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01177 {
01178     rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED);
01179 }
01180 
01181 void
01182 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01183 {
01184     rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE);
01185 }
01186 
01187 void
01188 rb_undef_method(VALUE klass, const char *name)
01189 {
01190     rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF);
01191 }
01192 
01201 #define SPECIAL_SINGLETON(x,c) do {\
01202     if (obj == (x)) {\
01203         return c;\
01204     }\
01205 } while (0)
01206 
01207 
01217 static VALUE
01218 singleton_class_of(VALUE obj)
01219 {
01220     VALUE klass;
01221 
01222     if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
01223         rb_raise(rb_eTypeError, "can't define singleton");
01224     }
01225     if (rb_special_const_p(obj)) {
01226         SPECIAL_SINGLETON(Qnil, rb_cNilClass);
01227         SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
01228         SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
01229         rb_bug("unknown immediate %ld", obj);
01230     }
01231 
01232     if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
01233         rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) {
01234         klass = RBASIC(obj)->klass;
01235     }
01236     else {
01237         klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
01238     }
01239 
01240     if (OBJ_TAINTED(obj)) {
01241         OBJ_TAINT(klass);
01242     }
01243     else {
01244         FL_UNSET(klass, FL_TAINT);
01245     }
01246     if (OBJ_UNTRUSTED(obj)) {
01247         OBJ_UNTRUST(klass);
01248     }
01249     else {
01250         FL_UNSET(klass, FL_UNTRUSTED);
01251     }
01252     if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
01253 
01254     return klass;
01255 }
01256 
01257 
01275 VALUE
01276 rb_singleton_class(VALUE obj)
01277 {
01278     VALUE klass = singleton_class_of(obj);
01279 
01280     /* ensures an exposed class belongs to its own eigenclass */
01281     if (TYPE(obj) == T_CLASS) ENSURE_EIGENCLASS(klass);
01282 
01283     return klass;
01284 }
01285 
01302 void
01303 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
01304 {
01305     rb_define_method(singleton_class_of(obj), name, func, argc);
01306 }
01307 
01308 
01309 
01317 void
01318 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
01319 {
01320     rb_define_private_method(module, name, func, argc);
01321     rb_define_singleton_method(module, name, func, argc);
01322 }
01323 
01324 
01331 void
01332 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
01333 {
01334     rb_define_module_function(rb_mKernel, name, func, argc);
01335 }
01336 
01337 
01344 void
01345 rb_define_alias(VALUE klass, const char *name1, const char *name2)
01346 {
01347     rb_alias(klass, rb_intern(name1), rb_intern(name2));
01348 }
01349 
01357 void
01358 rb_define_attr(VALUE klass, const char *name, int read, int write)
01359 {
01360     rb_attr(klass, rb_intern(name), read, write, FALSE);
01361 }
01362 
01363 int
01364 rb_obj_basic_to_s_p(VALUE obj)
01365 {
01366     const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s"));
01367     if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
01368         me->def->body.cfunc.func == rb_any_to_s)
01369         return 1;
01370     return 0;
01371 }
01372 
01373 #include <stdarg.h>
01374 
01375 int
01376 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
01377 {
01378     int i;
01379     const char *p = fmt;
01380     VALUE *var;
01381     va_list vargs;
01382     int f_var = 0, f_block = 0;
01383     int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
01384     int argi = 0;
01385 
01386     if (ISDIGIT(*p)) {
01387         n_lead = *p - '0';
01388         p++;
01389         if (ISDIGIT(*p)) {
01390             n_opt = *p - '0';
01391             p++;
01392             if (ISDIGIT(*p)) {
01393                 n_trail = *p - '0';
01394                 p++;
01395                 goto block_arg;
01396             }
01397         }
01398     }
01399     if (*p == '*') {
01400         f_var = 1;
01401         p++;
01402         if (ISDIGIT(*p)) {
01403             n_trail = *p - '0';
01404             p++;
01405         }
01406     }
01407   block_arg:
01408     if (*p == '&') {
01409         f_block = 1;
01410         p++;
01411     }
01412     if (*p != '\0') {
01413         rb_fatal("bad scan arg format: %s", fmt);
01414     }
01415     n_mand = n_lead + n_trail;
01416 
01417     if (argc < n_mand)
01418         goto argc_error;
01419 
01420     va_start(vargs, fmt);
01421 
01422     /* capture leading mandatory arguments */
01423     for (i = n_lead; i-- > 0; ) {
01424         var = va_arg(vargs, VALUE *);
01425         if (var) *var = argv[argi];
01426         argi++;
01427     }
01428     /* capture optional arguments */
01429     for (i = n_opt; i-- > 0; ) {
01430         var = va_arg(vargs, VALUE *);
01431         if (argi < argc - n_trail) {
01432             if (var) *var = argv[argi];
01433             argi++;
01434         }
01435         else {
01436             if (var) *var = Qnil;
01437         }
01438     }
01439     /* capture variable length arguments */
01440     if (f_var) {
01441         int n_var = argc - argi - n_trail;
01442 
01443         var = va_arg(vargs, VALUE *);
01444         if (0 < n_var) {
01445             if (var) *var = rb_ary_new4(n_var, &argv[argi]);
01446             argi += n_var;
01447         }
01448         else {
01449             if (var) *var = rb_ary_new();
01450         }
01451     }
01452     /* capture trailing mandatory arguments */
01453     for (i = n_trail; i-- > 0; ) {
01454         var = va_arg(vargs, VALUE *);
01455         if (var) *var = argv[argi];
01456         argi++;
01457     }
01458     /* capture iterator block */
01459     if (f_block) {
01460         var = va_arg(vargs, VALUE *);
01461         if (rb_block_given_p()) {
01462             *var = rb_block_proc();
01463         }
01464         else {
01465             *var = Qnil;
01466         }
01467     }
01468     va_end(vargs);
01469 
01470     if (argi < argc)
01471         goto argc_error;
01472 
01473     return argc;
01474 
01475   argc_error:
01476     if (0 < n_opt)
01477         rb_raise(rb_eArgError, "wrong number of arguments (%d for %d..%d%s)",
01478                  argc, n_mand, n_mand + n_opt, f_var ? "+" : "");
01479     else
01480         rb_raise(rb_eArgError, "wrong number of arguments (%d for %d%s)",
01481                  argc, n_mand, f_var ? "+" : "");
01482 }
01483 

Generated on Thu Sep 8 2011 03:46:40 for Ruby by  doxygen 1.7.1