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

Generated on Wed Sep 8 2010 21:50:17 for Ruby by  doxygen 1.7.1