class.c


DEFINITIONS

This source file includes following functions.
  1. rb_class_boot
  2. rb_class_new
  3. clone_method
  4. rb_mod_clone
  5. rb_mod_dup
  6. rb_singleton_class_clone
  7. rb_singleton_class_attached
  8. rb_make_metaclass
  9. rb_define_class_id
  10. rb_class_inherited
  11. rb_define_class
  12. rb_define_class_under
  13. rb_module_new
  14. rb_define_module_id
  15. rb_define_module
  16. rb_define_module_under
  17. include_class_new
  18. rb_include_module
  19. rb_mod_included_modules
  20. rb_mod_include_p
  21. rb_mod_ancestors
  22. ins_methods_i
  23. ins_methods_prot_i
  24. ins_methods_priv_i
  25. method_list
  26. rb_class_instance_methods
  27. rb_class_protected_instance_methods
  28. rb_class_private_instance_methods
  29. rb_obj_singleton_methods
  30. rb_define_method_id
  31. rb_define_method
  32. rb_define_protected_method
  33. rb_define_private_method
  34. rb_undef_method
  35. rb_singleton_class
  36. rb_define_singleton_method
  37. rb_define_module_function
  38. rb_define_global_function
  39. rb_define_alias
  40. rb_define_attr
  41. rb_scan_args


   1  /**********************************************************************
   2  
   3    class.c -
   4  
   5    $Author: matz $
   6    $Date: 2002/09/05 09:42:56 $
   7    created at: Tue Aug 10 15:05:44 JST 1993
   8  
   9    Copyright (C) 1993-2002 Yukihiro Matsumoto
  10  
  11  **********************************************************************/
  12  
  13  #include "ruby.h"
  14  #include "rubysig.h"
  15  #include "node.h"
  16  #include "st.h"
  17  #include <ctype.h>
  18  
  19  extern st_table *rb_class_tbl;
  20  
  21  VALUE
  22  rb_class_boot(super)
  23      VALUE super;
  24  {
  25      NEWOBJ(klass, struct RClass);
  26      OBJSETUP(klass, rb_cClass, T_CLASS);
  27  
  28      klass->super = super;
  29      klass->iv_tbl = 0;
  30      klass->m_tbl = 0;           /* safe GC */
  31      klass->m_tbl = st_init_numtable();
  32  
  33      OBJ_INFECT(klass, super);
  34      return (VALUE)klass;
  35  }
  36  
  37  VALUE
  38  rb_class_new(super)
  39      VALUE super;
  40  {
  41      Check_Type(super, T_CLASS);
  42      if (super == rb_cClass) {
  43          rb_raise(rb_eTypeError, "can't make subclass of Class");
  44      }
  45      if (FL_TEST(super, FL_SINGLETON)) {
  46          rb_raise(rb_eTypeError, "can't make subclass of virtual class");
  47      }
  48      return rb_class_boot(super);
  49  }
  50  
  51  static int
  52  clone_method(mid, body, tbl)
  53      ID mid;
  54      NODE *body;
  55      st_table *tbl;
  56  {
  57      st_insert(tbl, mid, NEW_METHOD(body->nd_body, body->nd_noex));
  58      return ST_CONTINUE;
  59  }
  60  
  61  VALUE
  62  rb_mod_clone(module)
  63      VALUE module;
  64  {
  65      NEWOBJ(clone, struct RClass);
  66      CLONESETUP(clone, module);
  67  
  68      RCLASS(clone)->super = RCLASS(module)->super;
  69      if (RCLASS(module)->iv_tbl) {
  70          ID id;
  71  
  72          RCLASS(clone)->iv_tbl = st_copy(RCLASS(module)->iv_tbl);
  73          id = rb_intern("__classpath__");
  74          st_delete(RCLASS(clone)->iv_tbl, &id, 0);
  75          id = rb_intern("__classid__");
  76          st_delete(RCLASS(clone)->iv_tbl, &id, 0);
  77      }
  78      if (RCLASS(module)->m_tbl) {
  79          RCLASS(clone)->m_tbl = st_init_numtable();
  80          st_foreach(RCLASS(module)->m_tbl, clone_method, RCLASS(clone)->m_tbl);
  81      }
  82  
  83      return (VALUE)clone;
  84  }
  85  
  86  VALUE
  87  rb_mod_dup(mod)
  88      VALUE mod;
  89  {
  90      VALUE dup = rb_mod_clone(mod);
  91  
  92      RBASIC(dup)->flags = RBASIC(mod)->flags & (T_MASK|FL_TAINT|FL_SINGLETON);
  93      return dup;
  94  }
  95  
  96  VALUE
  97  rb_singleton_class_clone(obj)
  98      VALUE obj;
  99  {
 100      VALUE klass = RBASIC(obj)->klass;
 101  
 102      if (!FL_TEST(klass, FL_SINGLETON))
 103          return klass;
 104      else {
 105          /* copy singleton(unnamed) class */
 106          NEWOBJ(clone, struct RClass);
 107          OBJSETUP(clone, 0, RBASIC(klass)->flags);
 108  
 109          if (BUILTIN_TYPE(obj) == T_CLASS) {
 110              RBASIC(clone)->klass = (VALUE)clone;
 111          }
 112          else {
 113              RBASIC(clone)->klass = rb_singleton_class_clone(klass);
 114          }
 115  
 116          clone->super = RCLASS(klass)->super;
 117          clone->iv_tbl = 0;
 118          clone->m_tbl = 0;
 119          if (RCLASS(klass)->iv_tbl) {
 120              clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
 121          }
 122          clone->m_tbl = st_init_numtable();
 123          st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl);
 124          rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
 125          FL_SET(clone, FL_SINGLETON);
 126          return (VALUE)clone;
 127      }
 128  }
 129  
 130  void
 131  rb_singleton_class_attached(klass, obj)
 132      VALUE klass, obj;
 133  {
 134      if (FL_TEST(klass, FL_SINGLETON)) {
 135          if (!RCLASS(klass)->iv_tbl) {
 136              RCLASS(klass)->iv_tbl = st_init_numtable();
 137          }
 138          st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj);
 139      }
 140  }
 141  
 142  VALUE
 143  rb_make_metaclass(obj, super)
 144      VALUE obj, super;
 145  {
 146      VALUE klass = rb_class_boot(super);
 147      FL_SET(klass, FL_SINGLETON);
 148      RBASIC(obj)->klass = klass;
 149      rb_singleton_class_attached(klass, obj);
 150      if (BUILTIN_TYPE(obj) == T_CLASS) {
 151          RBASIC(klass)->klass = klass;
 152          if (FL_TEST(obj, FL_SINGLETON)) {
 153              RCLASS(klass)->super = RBASIC(rb_class_real(RCLASS(obj)->super))->klass;
 154          }
 155      }
 156  
 157      return klass;
 158  }
 159  
 160  VALUE
 161  rb_define_class_id(id, super)
 162      ID id;
 163      VALUE super;
 164  {
 165      VALUE klass;
 166  
 167      if (!super) super = rb_cObject;
 168      klass = rb_class_new(super);
 169      rb_name_class(klass, id);
 170      rb_make_metaclass(klass, RBASIC(super)->klass);
 171  
 172      return klass;
 173  }
 174  
 175  VALUE
 176  rb_class_inherited(super, klass)
 177      VALUE super, klass;
 178  {
 179      if (!super) super = rb_cObject;
 180      return rb_funcall(super, rb_intern("inherited"), 1, klass);
 181  }
 182  
 183  VALUE
 184  rb_define_class(name, super)
 185      const char *name;
 186      VALUE super;
 187  {
 188      VALUE klass;
 189      ID id;
 190  
 191      id = rb_intern(name);
 192      if (rb_autoload_defined(id)) {
 193          rb_autoload_load(id);
 194      }
 195      if (rb_const_defined(rb_cObject, id)) {
 196          klass = rb_const_get(rb_cObject, id);
 197          if (TYPE(klass) != T_CLASS) {
 198              rb_raise(rb_eTypeError, "%s is not a class", name);
 199          }
 200          if (rb_class_real(RCLASS(klass)->super) != super) {
 201              rb_name_error(id, "%s is already defined", name);
 202          }
 203          return klass;
 204      }
 205      if (!super) {
 206          rb_warn("no super class for `%s', Object assumed", name);
 207      }
 208      klass = rb_define_class_id(id, super);
 209      rb_class_inherited(super, klass);
 210      st_add_direct(rb_class_tbl, id, klass);
 211  
 212      return klass;
 213  }
 214  
 215  VALUE
 216  rb_define_class_under(outer, name, super)
 217      VALUE outer;
 218      const char *name;
 219      VALUE super;
 220  {
 221      VALUE klass;
 222      ID id;
 223  
 224      id = rb_intern(name);
 225      if (rb_const_defined_at(outer, id)) {
 226          klass = rb_const_get(outer, id);
 227          if (TYPE(klass) != T_CLASS) {
 228              rb_raise(rb_eTypeError, "%s is not a class", name);
 229          }
 230          if (rb_class_real(RCLASS(klass)->super) != super) {
 231              rb_name_error(id, "%s is already defined", name);
 232          }
 233          return klass;
 234      }
 235      if (!super) {
 236          rb_warn("no super class for `%s::%s', Object assumed",
 237                  rb_class2name(outer), name);
 238      }
 239      klass = rb_define_class_id(id, super);
 240      rb_set_class_path(klass, outer, name);
 241      rb_class_inherited(super, klass);
 242      rb_const_set(outer, id, klass);
 243  
 244      return klass;
 245  }
 246  
 247  VALUE
 248  rb_module_new()
 249  {
 250      NEWOBJ(mdl, struct RClass);
 251      OBJSETUP(mdl, rb_cModule, T_MODULE);
 252  
 253      mdl->super = 0;
 254      mdl->iv_tbl = 0;
 255      mdl->m_tbl = 0;
 256      mdl->m_tbl = st_init_numtable();
 257  
 258      return (VALUE)mdl;
 259  }
 260  
 261  VALUE
 262  rb_define_module_id(id)
 263      ID id;
 264  {
 265      VALUE mdl;
 266  
 267      mdl = rb_module_new();
 268      rb_name_class(mdl, id);
 269  
 270      return mdl;
 271  }
 272  
 273  VALUE
 274  rb_define_module(name)
 275      const char *name;
 276  {
 277      VALUE module;
 278      ID id;
 279  
 280      id = rb_intern(name);
 281      if (rb_autoload_defined(id)) {
 282          rb_autoload_load(id);
 283      }
 284      if (rb_const_defined(rb_cObject, id)) {
 285          module = rb_const_get(rb_cObject, id);
 286          if (TYPE(module) == T_MODULE)
 287              return module;
 288          rb_raise(rb_eTypeError, "%s is not a module", rb_class2name(CLASS_OF(module)));
 289      }
 290      module = rb_define_module_id(id);
 291      st_add_direct(rb_class_tbl, id, module);
 292  
 293      return module;
 294  }
 295  
 296  VALUE
 297  rb_define_module_under(outer, name)
 298      VALUE outer;
 299      const char *name;
 300  {
 301      VALUE module;
 302      ID id;
 303  
 304      id = rb_intern(name);
 305      if (rb_const_defined_at(outer, id)) {
 306          module = rb_const_get(outer, id);
 307          if (TYPE(module) == T_MODULE)
 308              return module;
 309          rb_raise(rb_eTypeError, "%s::%s is not a module",
 310                   rb_class2name(outer), rb_class2name(CLASS_OF(module)));
 311      }
 312      module = rb_define_module_id(id);
 313      rb_const_set(outer, id, module);
 314      rb_set_class_path(module, outer, name);
 315  
 316      return module;
 317  }
 318  
 319  static VALUE
 320  include_class_new(module, super)
 321      VALUE module, super;
 322  {
 323      NEWOBJ(klass, struct RClass);
 324      OBJSETUP(klass, rb_cClass, T_ICLASS);
 325  
 326      if (BUILTIN_TYPE(module) == T_ICLASS) {
 327          module = RBASIC(module)->klass;
 328      }
 329      if (!RCLASS(module)->iv_tbl) {
 330          RCLASS(module)->iv_tbl = st_init_numtable();
 331      }
 332      klass->iv_tbl = RCLASS(module)->iv_tbl;
 333      klass->m_tbl = RCLASS(module)->m_tbl;
 334      klass->super = super;
 335      if (TYPE(module) == T_ICLASS) {
 336          RBASIC(klass)->klass = RBASIC(module)->klass;
 337      }
 338      else {
 339          RBASIC(klass)->klass = module;
 340      }
 341      OBJ_INFECT(klass, module);
 342      OBJ_INFECT(klass, super);
 343  
 344      return (VALUE)klass;
 345  }
 346  
 347  void
 348  rb_include_module(klass, module)
 349      VALUE klass, module;
 350  {
 351      VALUE p, c;
 352      int changed = 0;
 353  
 354      rb_frozen_class_p(klass);
 355      if (!OBJ_TAINTED(klass)) {
 356          rb_secure(4);
 357      }
 358      
 359      if (NIL_P(module)) return;
 360      if (klass == module) return;
 361  
 362      switch (TYPE(module)) {
 363        case T_MODULE:
 364        case T_CLASS:
 365        case T_ICLASS:
 366          break;
 367        default:
 368          Check_Type(module, T_MODULE);
 369      }
 370  
 371      OBJ_INFECT(klass, module);
 372      c = klass;
 373      while (module) {
 374          int superclass_seen = Qfalse;
 375  
 376          if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
 377              rb_raise(rb_eArgError, "cyclic include detected");
 378          /* ignore if the module included already in superclasses */
 379          for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
 380              switch (BUILTIN_TYPE(p)) {
 381                case T_ICLASS:
 382                  if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
 383                      if (!superclass_seen) {
 384                          c = p;  /* move insertion point */
 385                      }
 386                      goto skip;
 387                  }
 388                  break;
 389                case T_CLASS:
 390                  superclass_seen = Qtrue;
 391                  break;
 392              }
 393          }
 394          c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
 395          changed = 1;
 396        skip:
 397          module = RCLASS(module)->super;
 398      }
 399      if (changed) rb_clear_cache();
 400  }
 401  
 402  VALUE
 403  rb_mod_included_modules(mod)
 404      VALUE mod;
 405  {
 406      VALUE ary = rb_ary_new();
 407      VALUE p;
 408  
 409      for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
 410          if (BUILTIN_TYPE(p) == T_ICLASS) {
 411              rb_ary_push(ary, RBASIC(p)->klass);
 412          }
 413      }
 414      return ary;
 415  }
 416  
 417  VALUE
 418  rb_mod_include_p(mod, mod2)
 419      VALUE mod;
 420      VALUE mod2;
 421  {
 422      VALUE p;
 423  
 424      Check_Type(mod2, T_MODULE);
 425      for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
 426          if (BUILTIN_TYPE(p) == T_ICLASS) {
 427              if (RBASIC(p)->klass == mod2) return Qtrue;
 428          }
 429      }
 430      return Qfalse;
 431  }
 432  
 433  VALUE
 434  rb_mod_ancestors(mod)
 435      VALUE mod;
 436  {
 437      VALUE ary = rb_ary_new();
 438      VALUE p;
 439  
 440      for (p = mod; p; p = RCLASS(p)->super) {
 441          if (FL_TEST(p, FL_SINGLETON))
 442              continue;
 443          if (BUILTIN_TYPE(p) == T_ICLASS) {
 444              rb_ary_push(ary, RBASIC(p)->klass);
 445          }
 446          else {
 447              rb_ary_push(ary, p);
 448          }
 449      }
 450      return ary;
 451  }
 452  
 453  static int
 454  ins_methods_i(key, body, ary)
 455      ID key;
 456      NODE *body;
 457      VALUE ary;
 458  {
 459      if ((body->nd_noex&(NOEX_PRIVATE|NOEX_PROTECTED)) == 0) {
 460          VALUE name = rb_str_new2(rb_id2name(key));
 461  
 462          if (!rb_ary_includes(ary, name)) {
 463              if (!body->nd_body) {
 464                  rb_ary_push(ary, Qnil);
 465              }
 466              rb_ary_push(ary, name);
 467          }
 468      }
 469      else if (body->nd_body && nd_type(body->nd_body) == NODE_ZSUPER) {
 470          rb_ary_push(ary, Qnil);
 471          rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
 472      }
 473      return ST_CONTINUE;
 474  }
 475  
 476  static int
 477  ins_methods_prot_i(key, body, ary)
 478      ID key;
 479      NODE *body;
 480      VALUE ary;
 481  {
 482      if (!body->nd_body) {
 483          rb_ary_push(ary, Qnil);
 484          rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
 485      }
 486      else if (body->nd_noex & NOEX_PROTECTED) {
 487          VALUE name = rb_str_new2(rb_id2name(key));
 488  
 489          if (!rb_ary_includes(ary, name)) {
 490              rb_ary_push(ary, name);
 491          }
 492      }
 493      else if (nd_type(body->nd_body) == NODE_ZSUPER) {
 494          rb_ary_push(ary, Qnil);
 495          rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
 496      }
 497      return ST_CONTINUE;
 498  }
 499  
 500  static int
 501  ins_methods_priv_i(key, body, ary)
 502      ID key;
 503      NODE *body;
 504      VALUE ary;
 505  {
 506      if (!body->nd_body) {
 507          rb_ary_push(ary, Qnil);
 508          rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
 509      }
 510      else if (body->nd_noex & NOEX_PRIVATE) {
 511          VALUE name = rb_str_new2(rb_id2name(key));
 512  
 513          if (!rb_ary_includes(ary, name)) {
 514              rb_ary_push(ary, name);
 515          }
 516      }
 517      else if (nd_type(body->nd_body) == NODE_ZSUPER) {
 518          rb_ary_push(ary, Qnil);
 519          rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
 520      }
 521      return ST_CONTINUE;
 522  }
 523  
 524  static VALUE
 525  method_list(mod, option, func)
 526      VALUE mod;
 527      int option;
 528      int (*func)();
 529  {
 530      VALUE ary;
 531      VALUE klass;
 532      VALUE *p, *q, *pend;
 533  
 534      ary = rb_ary_new();
 535      for (klass = mod; klass; klass = RCLASS(klass)->super) {
 536          st_foreach(RCLASS(klass)->m_tbl, func, ary);
 537          if (!option) break;
 538      }
 539      p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
 540      while (p < pend) {
 541          if (*p == Qnil) {
 542              p+=2;
 543              continue;
 544          }
 545          *q++ = *p++;
 546      }
 547      RARRAY(ary)->len = q - RARRAY(ary)->ptr;
 548      return ary;
 549  }
 550  
 551  VALUE
 552  rb_class_instance_methods(argc, argv, mod)
 553      int argc;
 554      VALUE *argv;
 555      VALUE mod;
 556  {
 557      VALUE option;
 558  
 559      rb_scan_args(argc, argv, "01", &option);
 560      return method_list(mod, RTEST(option), ins_methods_i);
 561  }
 562  
 563  VALUE
 564  rb_class_protected_instance_methods(argc, argv, mod)
 565      int argc;
 566      VALUE *argv;
 567      VALUE mod;
 568  {
 569      VALUE option;
 570  
 571      rb_scan_args(argc, argv, "01", &option);
 572      return method_list(mod, RTEST(option), ins_methods_prot_i);
 573  }
 574  
 575  VALUE
 576  rb_class_private_instance_methods(argc, argv, mod)
 577      int argc;
 578      VALUE *argv;
 579      VALUE mod;
 580  {
 581      VALUE option;
 582  
 583      rb_scan_args(argc, argv, "01", &option);
 584      return method_list(mod, RTEST(option), ins_methods_priv_i);
 585  }
 586  
 587  VALUE
 588  rb_obj_singleton_methods(argc, argv, obj)
 589      int argc;
 590      VALUE *argv;
 591      VALUE obj;
 592  {
 593      VALUE all;
 594      VALUE ary;
 595      VALUE klass;
 596      VALUE *p, *q, *pend;
 597  
 598      rb_scan_args(argc, argv, "01", &all);
 599      ary = rb_ary_new();
 600      klass = CLASS_OF(obj);
 601      while (klass && FL_TEST(klass, FL_SINGLETON)) {
 602          st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
 603          klass = RCLASS(klass)->super;
 604      }
 605      if (RTEST(all)) {
 606          while (klass && TYPE(klass) == T_ICLASS) {
 607              st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
 608              klass = RCLASS(klass)->super;
 609          }
 610      }
 611      p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
 612      while (p < pend) {
 613          if (*p == Qnil) {
 614              p+=2;
 615              continue;
 616          }
 617          *q++ = *p++;
 618      }
 619      RARRAY(ary)->len = q - RARRAY(ary)->ptr;
 620  
 621      return ary;
 622  }
 623  
 624  void
 625  rb_define_method_id(klass, name, func, argc)
 626      VALUE klass;
 627      ID name;
 628      VALUE (*func)();
 629      int argc;
 630  {
 631      rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC|NOEX_CFUNC);
 632  }
 633  
 634  void
 635  rb_define_method(klass, name, func, argc)
 636      VALUE klass;
 637      const char *name;
 638      VALUE (*func)();
 639      int argc;
 640  {
 641      ID id = rb_intern(name);
 642  
 643      rb_add_method(klass, id, NEW_CFUNC(func, argc), 
 644                    ((name[0] == 'i' && id == rb_intern("initialize"))?
 645                     NOEX_PRIVATE:NOEX_PUBLIC)|NOEX_CFUNC);
 646  }
 647  
 648  void
 649  rb_define_protected_method(klass, name, func, argc)
 650      VALUE klass;
 651      const char *name;
 652      VALUE (*func)();
 653      int argc;
 654  {
 655      rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
 656                    NOEX_PROTECTED|NOEX_CFUNC);
 657  }
 658  
 659  void
 660  rb_define_private_method(klass, name, func, argc)
 661      VALUE klass;
 662      const char *name;
 663      VALUE (*func)();
 664      int argc;
 665  {
 666      rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
 667                    NOEX_PRIVATE|NOEX_CFUNC);
 668  }
 669  
 670  void
 671  rb_undef_method(klass, name)
 672      VALUE klass;
 673      const char *name;
 674  {
 675      rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
 676  }
 677  
 678  #define SPECIAL_SINGLETON(x,c) do {\
 679      if (obj == (x)) {\
 680          return c;\
 681      }\
 682  } while (0)
 683  
 684  VALUE
 685  rb_singleton_class(obj)
 686      VALUE obj;
 687  {
 688      VALUE klass;
 689  
 690      if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
 691          rb_raise(rb_eTypeError, "can't define singleton");
 692      }
 693      if (rb_special_const_p(obj)) {
 694          SPECIAL_SINGLETON(Qnil, rb_cNilClass);
 695          SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
 696          SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
 697          rb_bug("unknown immediate %ld", obj);
 698      }
 699  
 700      DEFER_INTS;
 701      if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
 702          (BUILTIN_TYPE(obj) == T_CLASS || /* metaclass (or metaclass of metaclass) */
 703           rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj)) {
 704          klass = RBASIC(obj)->klass;
 705      }
 706      else {
 707          klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
 708      }
 709      if (OBJ_TAINTED(obj)) {
 710          OBJ_TAINT(klass);
 711      }
 712      else {
 713          FL_UNSET(klass, FL_TAINT);
 714      }
 715      if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
 716      ALLOW_INTS;
 717  
 718      return klass;
 719  }
 720  
 721  void
 722  rb_define_singleton_method(obj, name, func, argc)
 723      VALUE obj;
 724      const char *name;
 725      VALUE (*func)();
 726      int argc;
 727  {
 728      rb_define_method(rb_singleton_class(obj), name, func, argc);
 729  }
 730  
 731  void
 732  rb_define_module_function(module, name, func, argc)
 733      VALUE module;
 734      const char *name;
 735      VALUE (*func)();
 736      int argc;
 737  {
 738      rb_define_private_method(module, name, func, argc);
 739      rb_define_singleton_method(module, name, func, argc);
 740  }
 741  
 742  void
 743  rb_define_global_function(name, func, argc)
 744      const char *name;
 745      VALUE (*func)();
 746      int argc;
 747  {
 748      rb_define_module_function(rb_mKernel, name, func, argc);
 749  }
 750  
 751  void
 752  rb_define_alias(klass, name1, name2)
 753      VALUE klass;
 754      const char *name1, *name2;
 755  {
 756      rb_alias(klass, rb_intern(name1), rb_intern(name2));
 757  }
 758  
 759  void
 760  rb_define_attr(klass, name, read, write)
 761      VALUE klass;
 762      const char *name;
 763      int read, write;
 764  {
 765      rb_attr(klass, rb_intern(name), read, write, Qfalse);
 766  }
 767  
 768  #ifdef HAVE_STDARG_PROTOTYPES
 769  #include <stdarg.h>
 770  #define va_init_list(a,b) va_start(a,b)
 771  #else
 772  #include <varargs.h>
 773  #define va_init_list(a,b) va_start(a)
 774  #endif
 775  
 776  int
 777  #ifdef HAVE_STDARG_PROTOTYPES
 778  rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
 779  #else
 780  rb_scan_args(argc, argv, fmt, va_alist)
 781      int argc;
 782      const VALUE *argv;
 783      const char *fmt;
 784      va_dcl
 785  #endif
 786  {
 787      int n, i = 0;
 788      const char *p = fmt;
 789      VALUE *var;
 790      va_list vargs;
 791  
 792      va_init_list(vargs, fmt);
 793  
 794      if (*p == '*') goto rest_arg;
 795  
 796      if (ISDIGIT(*p)) {
 797          n = *p - '0';
 798          if (n > argc)
 799              rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, n);
 800          for (i=0; i<n; i++) {
 801              var = va_arg(vargs, VALUE*);
 802              if (var) *var = argv[i];
 803          }
 804          p++;
 805      }
 806      else {
 807          goto error;
 808      }
 809  
 810      if (ISDIGIT(*p)) {
 811          n = i + *p - '0';
 812          for (; i<n; i++) {
 813              var = va_arg(vargs, VALUE*);
 814              if (argc > i) {
 815                  if (var) *var = argv[i];
 816              }
 817              else {
 818                  if (var) *var = Qnil;
 819              }
 820          }
 821          p++;
 822      }
 823  
 824      if(*p == '*') {
 825        rest_arg:
 826          var = va_arg(vargs, VALUE*);
 827          if (argc > i) {
 828              if (var) *var = rb_ary_new4(argc-i, argv+i);
 829              i = argc;
 830          }
 831          else {
 832              if (var) *var = rb_ary_new();
 833          }
 834          p++;
 835      }
 836  
 837      if (*p == '&') {
 838          var = va_arg(vargs, VALUE*);
 839          if (rb_block_given_p()) {
 840              *var = rb_f_lambda();
 841          }
 842          else {
 843              *var = Qnil;
 844          }
 845          p++;
 846      }
 847      va_end(vargs);
 848  
 849      if (*p != '\0') {
 850          goto error;
 851      }
 852  
 853      if (argc > i) {
 854          rb_raise(rb_eArgError, "wrong number of arguments(%d for %d)", argc, i);
 855      }
 856  
 857      return argc;
 858  
 859    error:
 860      rb_fatal("bad scan arg format: %s", fmt);
 861      return 0;
 862  }