Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals

class.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   class.c -
00004 
00005   $Author: nobu $
00006   $Date: 2005/09/28 14:42:46 $
00007   created at: Tue Aug 10 15:05:44 JST 1993
00008 
00009   Copyright (C) 1993-2003 Yukihiro Matsumoto
00010 
00011 **********************************************************************/
00012 
00013 #include "ruby.h"
00014 #include "rubysig.h"
00015 #include "node.h"
00016 #include "st.h"
00017 #include <ctype.h>
00018 
00019 extern st_table *rb_class_tbl;
00020 
00021 VALUE
00022 rb_class_boot(super)
00023     VALUE super;
00024 {
00025     NEWOBJ(klass, struct RClass);
00026     OBJSETUP(klass, rb_cClass, T_CLASS);
00027 
00028     klass->super = super;
00029     klass->iv_tbl = 0;
00030     klass->m_tbl = 0;           /* safe GC */
00031     klass->m_tbl = st_init_numtable();
00032 
00033     OBJ_INFECT(klass, super);
00034     return (VALUE)klass;
00035 }
00036 
00037 VALUE
00038 rb_class_new(super)
00039     VALUE super;
00040 {
00041     Check_Type(super, T_CLASS);
00042     if (super == rb_cClass) {
00043         rb_raise(rb_eTypeError, "can't make subclass of Class");
00044     }
00045     if (FL_TEST(super, FL_SINGLETON)) {
00046         rb_raise(rb_eTypeError, "can't make subclass of virtual class");
00047     }
00048     return rb_class_boot(super);
00049 }
00050 
00051 static int
00052 clone_method(mid, body, tbl)
00053     ID mid;
00054     NODE *body;
00055     st_table *tbl;
00056 {
00057     st_insert(tbl, mid, (st_data_t)NEW_METHOD(body->nd_body, body->nd_noex));
00058     return ST_CONTINUE;
00059 }
00060 
00061 /* :nodoc: */
00062 VALUE
00063 rb_mod_init_copy(clone, orig)
00064     VALUE clone, orig;
00065 {
00066     rb_obj_init_copy(clone, orig);
00067     if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
00068         RBASIC(clone)->klass = rb_singleton_class_clone(orig);
00069     }
00070     RCLASS(clone)->super = RCLASS(orig)->super;
00071     if (RCLASS(orig)->iv_tbl) {
00072         ID id;
00073 
00074         RCLASS(clone)->iv_tbl = st_copy(RCLASS(orig)->iv_tbl);
00075         id = rb_intern("__classpath__");
00076         st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);
00077         id = rb_intern("__classid__");
00078         st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);
00079     }
00080     if (RCLASS(orig)->m_tbl) {
00081         RCLASS(clone)->m_tbl = st_init_numtable();
00082         st_foreach(RCLASS(orig)->m_tbl, clone_method,
00083           (st_data_t)RCLASS(clone)->m_tbl);
00084     }
00085 
00086     return clone;
00087 }
00088 
00089 /* :nodoc: */
00090 VALUE
00091 rb_class_init_copy(clone, orig)
00092     VALUE clone, orig;
00093 {
00094     if (RCLASS(clone)->super != 0) {
00095         rb_raise(rb_eTypeError, "already initialized class");
00096     }
00097     if (FL_TEST(orig, FL_SINGLETON)) {
00098         rb_raise(rb_eTypeError, "can't copy singleton class");
00099     }
00100     return rb_mod_init_copy(clone, orig);
00101 }
00102 
00103 VALUE
00104 rb_singleton_class_clone(obj)
00105     VALUE obj;
00106 {
00107     VALUE klass = RBASIC(obj)->klass;
00108 
00109     if (!FL_TEST(klass, FL_SINGLETON))
00110         return klass;
00111     else {
00112         /* copy singleton(unnamed) class */
00113         NEWOBJ(clone, struct RClass);
00114         OBJSETUP(clone, 0, RBASIC(klass)->flags);
00115 
00116         if (BUILTIN_TYPE(obj) == T_CLASS) {
00117             RBASIC(clone)->klass = (VALUE)clone;
00118         }
00119         else {
00120             RBASIC(clone)->klass = rb_singleton_class_clone(klass);
00121         }
00122 
00123         clone->super = RCLASS(klass)->super;
00124         clone->iv_tbl = 0;
00125         clone->m_tbl = 0;
00126         if (RCLASS(klass)->iv_tbl) {
00127             clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
00128         }
00129         clone->m_tbl = st_init_numtable();
00130         st_foreach(RCLASS(klass)->m_tbl, clone_method,
00131           (st_data_t)clone->m_tbl);
00132         rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
00133         FL_SET(clone, FL_SINGLETON);
00134         return (VALUE)clone;
00135     }
00136 }
00137 
00138 void
00139 rb_singleton_class_attached(klass, obj)
00140     VALUE klass, obj;
00141 {
00142     if (FL_TEST(klass, FL_SINGLETON)) {
00143         if (!RCLASS(klass)->iv_tbl) {
00144             RCLASS(klass)->iv_tbl = st_init_numtable();
00145         }
00146         st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj);
00147     }
00148 }
00149 
00150 VALUE
00151 rb_make_metaclass(obj, super)
00152     VALUE obj, super;
00153 {
00154     VALUE klass = rb_class_boot(super);
00155     FL_SET(klass, FL_SINGLETON);
00156     RBASIC(obj)->klass = klass;
00157     rb_singleton_class_attached(klass, obj);
00158     if (BUILTIN_TYPE(obj) == T_CLASS && FL_TEST(obj, FL_SINGLETON)) {
00159         RBASIC(klass)->klass = klass;
00160         RCLASS(klass)->super = RBASIC(rb_class_real(RCLASS(obj)->super))->klass;
00161     }
00162     else {
00163         VALUE metasuper = RBASIC(rb_class_real(super))->klass;
00164 
00165         /* metaclass of a superclass may be NULL at boot time */
00166         if (metasuper) {
00167             RBASIC(klass)->klass = metasuper;
00168         }
00169     }
00170 
00171     return klass;
00172 }
00173 
00174 VALUE
00175 rb_define_class_id(id, super)
00176     ID id;
00177     VALUE super;
00178 {
00179     VALUE klass;
00180 
00181     if (!super) super = rb_cObject;
00182     klass = rb_class_new(super);
00183     rb_make_metaclass(klass, RBASIC(super)->klass);
00184 
00185     return klass;
00186 }
00187 
00188 void
00189 rb_check_inheritable(super)
00190     VALUE super;
00191 {
00192     if (TYPE(super) != T_CLASS) {
00193         rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
00194                  rb_obj_classname(super));
00195     }
00196     if (RBASIC(super)->flags & FL_SINGLETON) {
00197         rb_raise(rb_eTypeError, "can't make subclass of virtual class");
00198     }
00199 }
00200 
00201 VALUE
00202 rb_class_inherited(super, klass)
00203     VALUE super, klass;
00204 {
00205     if (!super) super = rb_cObject;
00206     return rb_funcall(super, rb_intern("inherited"), 1, klass);
00207 }
00208 
00209 VALUE
00210 rb_define_class(name, super)
00211     const char *name;
00212     VALUE super;
00213 {
00214     VALUE klass;
00215     ID id;
00216 
00217     id = rb_intern(name);
00218     if (rb_const_defined(rb_cObject, id)) {
00219         klass = rb_const_get(rb_cObject, id);
00220         if (TYPE(klass) != T_CLASS) {
00221             rb_raise(rb_eTypeError, "%s is not a class", name);
00222         }
00223         if (rb_class_real(RCLASS(klass)->super) != super) {
00224             rb_name_error(id, "%s is already defined", name);
00225         }
00226         return klass;
00227     }
00228     if (!super) {
00229         rb_warn("no super class for `%s', Object assumed", name);
00230     }
00231     klass = rb_define_class_id(id, super);
00232     st_add_direct(rb_class_tbl, id, klass);
00233     rb_name_class(klass, id);
00234     rb_const_set(rb_cObject, id, klass);
00235     rb_class_inherited(super, klass);
00236 
00237     return klass;
00238 }
00239 
00240 VALUE
00241 rb_define_class_under(outer, name, super)
00242     VALUE outer;
00243     const char *name;
00244     VALUE super;
00245 {
00246     VALUE klass;
00247     ID id;
00248 
00249     id = rb_intern(name);
00250     if (rb_const_defined_at(outer, id)) {
00251         klass = rb_const_get_at(outer, id);
00252         if (TYPE(klass) != T_CLASS) {
00253             rb_raise(rb_eTypeError, "%s is not a class", name);
00254         }
00255         if (rb_class_real(RCLASS(klass)->super) != super) {
00256             rb_name_error(id, "%s is already defined", name);
00257         }
00258         return klass;
00259     }
00260     if (!super) {
00261         rb_warn("no super class for `%s::%s', Object assumed",
00262                 rb_class2name(outer), name);
00263     }
00264     klass = rb_define_class_id(id, super);
00265     rb_set_class_path(klass, outer, name);
00266     rb_const_set(outer, id, klass);
00267     rb_class_inherited(super, klass);
00268 
00269     return klass;
00270 }
00271 
00272 VALUE
00273 rb_module_new()
00274 {
00275     NEWOBJ(mdl, struct RClass);
00276     OBJSETUP(mdl, rb_cModule, T_MODULE);
00277 
00278     mdl->super = 0;
00279     mdl->iv_tbl = 0;
00280     mdl->m_tbl = 0;
00281     mdl->m_tbl = st_init_numtable();
00282 
00283     return (VALUE)mdl;
00284 }
00285 
00286 VALUE
00287 rb_define_module_id(id)
00288     ID id;
00289 {
00290     VALUE mdl;
00291 
00292     mdl = rb_module_new();
00293     rb_name_class(mdl, id);
00294 
00295     return mdl;
00296 }
00297 
00298 VALUE
00299 rb_define_module(name)
00300     const char *name;
00301 {
00302     VALUE module;
00303     ID id;
00304 
00305     id = rb_intern(name);
00306     if (rb_const_defined(rb_cObject, id)) {
00307         module = rb_const_get(rb_cObject, id);
00308         if (TYPE(module) == T_MODULE)
00309             return module;
00310         rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
00311     }
00312     module = rb_define_module_id(id);
00313     st_add_direct(rb_class_tbl, id, module);
00314     rb_const_set(rb_cObject, id, module);
00315 
00316     return module;
00317 }
00318 
00319 VALUE
00320 rb_define_module_under(outer, name)
00321     VALUE outer;
00322     const char *name;
00323 {
00324     VALUE module;
00325     ID id;
00326 
00327     id = rb_intern(name);
00328     if (rb_const_defined_at(outer, id)) {
00329         module = rb_const_get_at(outer, id);
00330         if (TYPE(module) == T_MODULE)
00331             return module;
00332         rb_raise(rb_eTypeError, "%s::%s is not a module",
00333                  rb_class2name(outer), rb_obj_classname(module));
00334     }
00335     module = rb_define_module_id(id);
00336     rb_const_set(outer, id, module);
00337     rb_set_class_path(module, outer, name);
00338 
00339     return module;
00340 }
00341 
00342 static VALUE
00343 include_class_new(module, super)
00344     VALUE module, super;
00345 {
00346     NEWOBJ(klass, struct RClass);
00347     OBJSETUP(klass, rb_cClass, T_ICLASS);
00348 
00349     if (BUILTIN_TYPE(module) == T_ICLASS) {
00350         module = RBASIC(module)->klass;
00351     }
00352     if (!RCLASS(module)->iv_tbl) {
00353         RCLASS(module)->iv_tbl = st_init_numtable();
00354     }
00355     klass->iv_tbl = RCLASS(module)->iv_tbl;
00356     klass->m_tbl = RCLASS(module)->m_tbl;
00357     klass->super = super;
00358     if (TYPE(module) == T_ICLASS) {
00359         RBASIC(klass)->klass = RBASIC(module)->klass;
00360     }
00361     else {
00362         RBASIC(klass)->klass = module;
00363     }
00364     OBJ_INFECT(klass, module);
00365     OBJ_INFECT(klass, super);
00366 
00367     return (VALUE)klass;
00368 }
00369 
00370 void
00371 rb_include_module(klass, module)
00372     VALUE klass, module;
00373 {
00374     VALUE p, c;
00375     int changed = 0;
00376 
00377     rb_frozen_class_p(klass);
00378     if (!OBJ_TAINTED(klass)) {
00379         rb_secure(4);
00380     }
00381     
00382     if (NIL_P(module)) return;
00383     if (klass == module) return;
00384 
00385     if (TYPE(module) != T_MODULE) {
00386         Check_Type(module, T_MODULE);
00387     }
00388 
00389     OBJ_INFECT(klass, module);
00390     c = klass;
00391     while (module) {
00392         int superclass_seen = Qfalse;
00393 
00394         if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
00395             rb_raise(rb_eArgError, "cyclic include detected");
00396         /* ignore if the module included already in superclasses */
00397         for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
00398             switch (BUILTIN_TYPE(p)) {
00399               case T_ICLASS:
00400                 if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
00401                     if (!superclass_seen) {
00402                         c = p;  /* move insertion point */
00403                     }
00404                     goto skip;
00405                 }
00406                 break;
00407               case T_CLASS:
00408                 superclass_seen = Qtrue;
00409                 break;
00410             }
00411         }
00412         c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
00413         changed = 1;
00414       skip:
00415         module = RCLASS(module)->super;
00416     }
00417     if (changed) rb_clear_cache();
00418 }
00419 
00420 /*
00421  *  call-seq:
00422  *     mod.included_modules -> array
00423  *  
00424  *  Returns the list of modules included in <i>mod</i>.
00425  *     
00426  *     module Mixin
00427  *     end
00428  *     
00429  *     module Outer
00430  *       include Mixin
00431  *     end
00432  *     
00433  *     Mixin.included_modules   #=> []
00434  *     Outer.included_modules   #=> [Mixin]
00435  */
00436 
00437 VALUE
00438 rb_mod_included_modules(mod)
00439     VALUE mod;
00440 {
00441     VALUE ary = rb_ary_new();
00442     VALUE p;
00443 
00444     for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
00445         if (BUILTIN_TYPE(p) == T_ICLASS) {
00446             rb_ary_push(ary, RBASIC(p)->klass);
00447         }
00448     }
00449     return ary;
00450 }
00451 
00452 /*
00453  *  call-seq:
00454  *     mod.include?(module)    => true or false
00455  *  
00456  *  Returns <code>true</code> if <i>module</i> is included in
00457  *  <i>mod</i> or one of <i>mod</i>'s ancestors.
00458  *     
00459  *     module A
00460  *     end
00461  *     class B
00462  *       include A
00463  *     end
00464  *     class C < B
00465  *     end
00466  *     B.include?(A)   #=> true
00467  *     C.include?(A)   #=> true
00468  *     A.include?(A)   #=> false
00469  */
00470 
00471 VALUE
00472 rb_mod_include_p(mod, mod2)
00473     VALUE mod;
00474     VALUE mod2;
00475 {
00476     VALUE p;
00477 
00478     Check_Type(mod2, T_MODULE);
00479     for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
00480         if (BUILTIN_TYPE(p) == T_ICLASS) {
00481             if (RBASIC(p)->klass == mod2) return Qtrue;
00482         }
00483     }
00484     return Qfalse;
00485 }
00486 
00487 /*
00488  *  call-seq:
00489  *     mod.ancestors -> array
00490  *  
00491  *  Returns a list of modules included in <i>mod</i> (including
00492  *  <i>mod</i> itself).
00493  *     
00494  *     module Mod
00495  *       include Math
00496  *       include Comparable
00497  *     end
00498  *     
00499  *     Mod.ancestors    #=> [Mod, Comparable, Math]
00500  *     Math.ancestors   #=> [Math]
00501  */
00502 
00503 VALUE
00504 rb_mod_ancestors(mod)
00505     VALUE mod;
00506 {
00507     VALUE p, ary = rb_ary_new();
00508 
00509     for (p = mod; p; p = RCLASS(p)->super) {
00510         if (FL_TEST(p, FL_SINGLETON))
00511             continue;
00512         if (BUILTIN_TYPE(p) == T_ICLASS) {
00513             rb_ary_push(ary, RBASIC(p)->klass);
00514         }
00515         else {
00516             rb_ary_push(ary, p);
00517         }
00518     }
00519     return ary;
00520 }
00521 
00522 #define VISI(x) ((x)&NOEX_MASK)
00523 #define VISI_CHECK(x,f) (VISI(x) == (f))
00524 
00525 static int
00526 ins_methods_push(name, type, ary, visi)
00527     ID name;
00528     long type;
00529     VALUE ary;
00530     long visi;
00531 {
00532     if (type == -1) return ST_CONTINUE;
00533     switch (visi) {
00534       case NOEX_PRIVATE:
00535       case NOEX_PROTECTED:
00536       case NOEX_PUBLIC:
00537         visi = (type == visi);
00538         break;
00539       default:
00540         visi = (type != NOEX_PRIVATE);
00541         break;
00542     }
00543     if (visi) {
00544         rb_ary_push(ary, rb_str_new2(rb_id2name(name)));
00545     }
00546     return ST_CONTINUE;
00547 }
00548 
00549 static int
00550 ins_methods_i(name, type, ary)
00551     ID name;
00552     long type;
00553     VALUE ary;
00554 {
00555     return ins_methods_push(name, type, ary, -1); /* everything but private */
00556 }
00557 
00558 static int
00559 ins_methods_prot_i(name, type, ary)
00560     ID name;
00561     long type;
00562     VALUE ary;
00563 {
00564     return ins_methods_push(name, type, ary, NOEX_PROTECTED);
00565 }
00566 
00567 static int
00568 ins_methods_priv_i(name, type, ary)
00569     ID name;
00570     long type;
00571     VALUE ary;
00572 {
00573     return ins_methods_push(name, type, ary, NOEX_PRIVATE);
00574 }
00575 
00576 static int
00577 ins_methods_pub_i(name, type, ary)
00578     ID name;
00579     long type;
00580     VALUE ary;
00581 {
00582     return ins_methods_push(name, type, ary, NOEX_PUBLIC);
00583 }
00584 
00585 static int
00586 method_entry(key, body, list)
00587     ID key;
00588     NODE *body;
00589     st_table *list;
00590 {
00591     long type;
00592 
00593     if (key == ID_ALLOCATOR) return ST_CONTINUE;
00594     if (!st_lookup(list, key, 0)) {
00595         if (!body->nd_body) type = -1; /* none */
00596         else type = VISI(body->nd_noex);
00597         st_add_direct(list, key, type);
00598     }
00599     return ST_CONTINUE;
00600 }
00601 
00602 static VALUE
00603 class_instance_method_list(argc, argv, mod, func)
00604     int argc;
00605     VALUE *argv;
00606     VALUE mod;
00607     int (*func) (ID, long, VALUE);
00608 {
00609     VALUE ary;
00610     int recur;
00611     st_table *list;
00612 
00613     if (argc == 0) {
00614         recur = Qtrue;
00615     }
00616     else {
00617         VALUE r;
00618         rb_scan_args(argc, argv, "01", &r);
00619         recur = RTEST(r);
00620     }
00621 
00622     list = st_init_numtable();
00623     for (; mod; mod = RCLASS(mod)->super) {
00624         st_foreach(RCLASS(mod)->m_tbl, method_entry, (st_data_t)list);
00625         if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
00626         if (FL_TEST(mod, FL_SINGLETON)) continue;
00627         if (!recur) break;
00628     }
00629     ary = rb_ary_new();
00630     st_foreach(list, func, ary);
00631     st_free_table(list);
00632 
00633     return ary;
00634 }
00635 
00636 /*
00637  *  call-seq:
00638  *     mod.instance_methods(include_super=true)   => array
00639  *  
00640  *  Returns an array containing the names of public instance methods in
00641  *  the receiver. For a module, these are the public methods; for a
00642  *  class, they are the instance (not singleton) methods. With no
00643  *  argument, or with an argument that is <code>false</code>, the
00644  *  instance methods in <i>mod</i> are returned, otherwise the methods
00645  *  in <i>mod</i> and <i>mod</i>'s superclasses are returned.
00646  *     
00647  *     module A
00648  *       def method1()  end
00649  *     end
00650  *     class B
00651  *       def method2()  end
00652  *     end
00653  *     class C < B
00654  *       def method3()  end
00655  *     end
00656  *     
00657  *     A.instance_methods                #=> ["method1"]
00658  *     B.instance_methods(false)         #=> ["method2"]
00659  *     C.instance_methods(false)         #=> ["method3"]
00660  *     C.instance_methods(true).length   #=> 43
00661  */
00662 
00663 VALUE
00664 rb_class_instance_methods(argc, argv, mod)
00665     int argc;
00666     VALUE *argv;
00667     VALUE mod;
00668 {
00669     return class_instance_method_list(argc, argv, mod, ins_methods_i);
00670 }
00671 
00672 /*
00673  *  call-seq:
00674  *     mod.protected_instance_methods(include_super=true)   => array
00675  *  
00676  *  Returns a list of the protected instance methods defined in
00677  *  <i>mod</i>. If the optional parameter is not <code>false</code>, the
00678  *  methods of any ancestors are included.
00679  */
00680 
00681 VALUE
00682 rb_class_protected_instance_methods(argc, argv, mod)
00683     int argc;
00684     VALUE *argv;
00685     VALUE mod;
00686 {
00687     return class_instance_method_list(argc, argv, mod, ins_methods_prot_i);
00688 }
00689 
00690 /*
00691  *  call-seq:
00692  *     mod.private_instance_methods(include_super=true)    => array
00693  *  
00694  *  Returns a list of the private instance methods defined in
00695  *  <i>mod</i>. If the optional parameter is not <code>false</code>, the
00696  *  methods of any ancestors are included.
00697  *     
00698  *     module Mod
00699  *       def method1()  end
00700  *       private :method1
00701  *       def method2()  end
00702  *     end
00703  *     Mod.instance_methods           #=> ["method2"]
00704  *     Mod.private_instance_methods   #=> ["method1"]
00705  */
00706 
00707 VALUE
00708 rb_class_private_instance_methods(argc, argv, mod)
00709     int argc;
00710     VALUE *argv;
00711     VALUE mod;
00712 {
00713     return class_instance_method_list(argc, argv, mod, ins_methods_priv_i);
00714 }
00715 
00716 /*
00717  *  call-seq:
00718  *     mod.public_instance_methods(include_super=true)   => array
00719  *  
00720  *  Returns a list of the public instance methods defined in <i>mod</i>.
00721  *  If the optional parameter is not <code>false</code>, the methods of
00722  *  any ancestors are included.
00723  */
00724 
00725 VALUE
00726 rb_class_public_instance_methods(argc, argv, mod)
00727     int argc;
00728     VALUE *argv;
00729     VALUE mod;
00730 {
00731     return class_instance_method_list(argc, argv, mod, ins_methods_pub_i);
00732 }
00733 
00734 /*
00735  *  call-seq:
00736  *     obj.singleton_methods(all=true)    => array
00737  *  
00738  *  Returns an array of the names of singleton methods for <i>obj</i>.
00739  *  If the optional <i>all</i> parameter is true, the list will include
00740  *  methods in modules included in <i>obj</i>.
00741  *     
00742  *     module Other
00743  *       def three() end
00744  *     end
00745  *     
00746  *     class Single
00747  *       def Single.four() end
00748  *     end
00749  *     
00750  *     a = Single.new
00751  *     
00752  *     def a.one()
00753  *     end
00754  *     
00755  *     class << a
00756  *       include Other
00757  *       def two()
00758  *       end
00759  *     end
00760  *     
00761  *     Single.singleton_methods    #=> ["four"]
00762  *     a.singleton_methods(false)  #=> ["two", "one"]
00763  *     a.singleton_methods         #=> ["two", "one", "three"]
00764  */
00765 
00766 VALUE
00767 rb_obj_singleton_methods(argc, argv, obj)
00768     int argc;
00769     VALUE *argv;
00770     VALUE obj;
00771 {
00772     VALUE recur, ary, klass;
00773     st_table *list;
00774 
00775     rb_scan_args(argc, argv, "01", &recur);
00776     if (argc == 0) {
00777         recur = Qtrue;
00778     }
00779     klass = CLASS_OF(obj);
00780     list = st_init_numtable();
00781     if (klass && FL_TEST(klass, FL_SINGLETON)) {
00782         st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
00783         klass = RCLASS(klass)->super;
00784     }
00785     if (RTEST(recur)) {
00786         while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
00787             st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
00788             klass = RCLASS(klass)->super;
00789         }
00790     }
00791     ary = rb_ary_new();
00792     st_foreach(list, ins_methods_i, ary);
00793     st_free_table(list);
00794 
00795     return ary;
00796 }
00797 
00798 void
00799 rb_define_method_id(klass, name, func, argc)
00800     VALUE klass;
00801     ID name;
00802     VALUE (*func)();
00803     int argc;
00804 {
00805     rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);
00806 }
00807 
00808 void
00809 rb_define_method(klass, name, func, argc)
00810     VALUE klass;
00811     const char *name;
00812     VALUE (*func)();
00813     int argc;
00814 {
00815     ID id = rb_intern(name);
00816     int ex = NOEX_PUBLIC;
00817 
00818 
00819     rb_add_method(klass, id, NEW_CFUNC(func, argc), ex);
00820 }
00821 
00822 void
00823 rb_define_protected_method(klass, name, func, argc)
00824     VALUE klass;
00825     const char *name;
00826     VALUE (*func)();
00827     int argc;
00828 {
00829     rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PROTECTED);
00830 }
00831 
00832 void
00833 rb_define_private_method(klass, name, func, argc)
00834     VALUE klass;
00835     const char *name;
00836     VALUE (*func)();
00837     int argc;
00838 {
00839     rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);
00840 }
00841 
00842 void
00843 rb_undef_method(klass, name)
00844     VALUE klass;
00845     const char *name;
00846 {
00847     rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
00848 }
00849 
00850 #define SPECIAL_SINGLETON(x,c) do {\
00851     if (obj == (x)) {\
00852         return c;\
00853     }\
00854 } while (0)
00855 
00856 VALUE
00857 rb_singleton_class(obj)
00858     VALUE obj;
00859 {
00860     VALUE klass;
00861 
00862     if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
00863         rb_raise(rb_eTypeError, "can't define singleton");
00864     }
00865     if (rb_special_const_p(obj)) {
00866         SPECIAL_SINGLETON(Qnil, rb_cNilClass);
00867         SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
00868         SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
00869         rb_bug("unknown immediate %ld", obj);
00870     }
00871 
00872     DEFER_INTS;
00873     if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
00874         rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) {
00875         klass = RBASIC(obj)->klass;
00876     }
00877     else {
00878         klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
00879     }
00880     if (OBJ_TAINTED(obj)) {
00881         OBJ_TAINT(klass);
00882     }
00883     else {
00884         FL_UNSET(klass, FL_TAINT);
00885     }
00886     if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
00887     ALLOW_INTS;
00888 
00889     return klass;
00890 }
00891 
00892 void
00893 rb_define_singleton_method(obj, name, func, argc)
00894     VALUE obj;
00895     const char *name;
00896     VALUE (*func)();
00897     int argc;
00898 {
00899     rb_define_method(rb_singleton_class(obj), name, func, argc);
00900 }
00901 
00902 void
00903 rb_define_module_function(module, name, func, argc)
00904     VALUE module;
00905     const char *name;
00906     VALUE (*func)();
00907     int argc;
00908 {
00909     rb_define_private_method(module, name, func, argc);
00910     rb_define_singleton_method(module, name, func, argc);
00911 }
00912 
00913 void
00914 rb_define_global_function(name, func, argc)
00915     const char *name;
00916     VALUE (*func)();
00917     int argc;
00918 {
00919     rb_define_module_function(rb_mKernel, name, func, argc);
00920 }
00921 
00922 void
00923 rb_define_alias(klass, name1, name2)
00924     VALUE klass;
00925     const char *name1, *name2;
00926 {
00927     rb_alias(klass, rb_intern(name1), rb_intern(name2));
00928 }
00929 
00930 void
00931 rb_define_attr(klass, name, read, write)
00932     VALUE klass;
00933     const char *name;
00934     int read, write;
00935 {
00936     rb_attr(klass, rb_intern(name), read, write, Qfalse);
00937 }
00938 
00939 #ifdef HAVE_STDARG_PROTOTYPES
00940 #include <stdarg.h>
00941 #define va_init_list(a,b) va_start(a,b)
00942 #else
00943 #include <varargs.h>
00944 #define va_init_list(a,b) va_start(a)
00945 #endif
00946 
00947 int
00948 #ifdef HAVE_STDARG_PROTOTYPES
00949 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
00950 #else
00951 rb_scan_args(argc, argv, fmt, va_alist)
00952     int argc;
00953     const VALUE *argv;
00954     const char *fmt;
00955     va_dcl
00956 #endif
00957 {
00958     int n, i = 0;
00959     const char *p = fmt;
00960     VALUE *var;
00961     va_list vargs;
00962 
00963     va_init_list(vargs, fmt);
00964 
00965     if (*p == '*') goto rest_arg;
00966 
00967     if (ISDIGIT(*p)) {
00968         n = *p - '0';
00969         if (n > argc)
00970             rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, n);
00971         for (i=0; i<n; i++) {
00972             var = va_arg(vargs, VALUE*);
00973             if (var) *var = argv[i];
00974         }
00975         p++;
00976     }
00977     else {
00978         goto error;
00979     }
00980 
00981     if (ISDIGIT(*p)) {
00982         n = i + *p - '0';
00983         for (; i<n; i++) {
00984             var = va_arg(vargs, VALUE*);
00985             if (argc > i) {
00986                 if (var) *var = argv[i];
00987             }
00988             else {
00989                 if (var) *var = Qnil;
00990             }
00991         }
00992         p++;
00993     }
00994 
00995     if(*p == '*') {
00996       rest_arg:
00997         var = va_arg(vargs, VALUE*);
00998         if (argc > i) {
00999             if (var) *var = rb_ary_new4(argc-i, argv+i);
01000             i = argc;
01001         }
01002         else {
01003             if (var) *var = rb_ary_new();
01004         }
01005         p++;
01006     }
01007 
01008     if (*p == '&') {
01009         var = va_arg(vargs, VALUE*);
01010         if (rb_block_given_p()) {
01011             *var = rb_block_proc();
01012         }
01013         else {
01014             *var = Qnil;
01015         }
01016         p++;
01017     }
01018     va_end(vargs);
01019 
01020     if (*p != '\0') {
01021         goto error;
01022     }
01023 
01024     if (argc > i) {
01025         rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, i);
01026     }
01027 
01028     return argc;
01029 
01030   error:
01031     rb_fatal("bad scan arg format: %s", fmt);
01032     return 0;
01033 }
01034 

Generated on Wed Jan 18 23:31:58 2006 for Ruby by doxygen 1.3.5