|
Ruby
2.0.0p594(2014-10-27revision48167)
|
00001 /********************************************************************** 00002 00003 class.c - 00004 00005 $Author: usa $ 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 "constant.h" 00030 #include "vm_core.h" 00031 #include "internal.h" 00032 #include <ctype.h> 00033 00034 extern st_table *rb_class_tbl; 00035 static ID id_attached; 00036 00049 static VALUE 00050 class_alloc(VALUE flags, VALUE klass) 00051 { 00052 NEWOBJ_OF(obj, struct RClass, klass, flags); 00053 obj->ptr = ALLOC(rb_classext_t); 00054 RCLASS_IV_TBL(obj) = 0; 00055 RCLASS_CONST_TBL(obj) = 0; 00056 RCLASS_M_TBL(obj) = 0; 00057 RCLASS_SUPER(obj) = 0; 00058 RCLASS_ORIGIN(obj) = (VALUE)obj; 00059 RCLASS_IV_INDEX_TBL(obj) = 0; 00060 RCLASS_REFINED_CLASS(obj) = Qnil; 00061 RCLASS_EXT(obj)->allocator = 0; 00062 return (VALUE)obj; 00063 } 00064 00065 00075 VALUE 00076 rb_class_boot(VALUE super) 00077 { 00078 VALUE klass = class_alloc(T_CLASS, rb_cClass); 00079 00080 RCLASS_SUPER(klass) = super; 00081 RCLASS_M_TBL(klass) = st_init_numtable(); 00082 00083 OBJ_INFECT(klass, super); 00084 return (VALUE)klass; 00085 } 00086 00087 00094 void 00095 rb_check_inheritable(VALUE super) 00096 { 00097 if (!RB_TYPE_P(super, T_CLASS)) { 00098 rb_raise(rb_eTypeError, "superclass must be a Class (%s given)", 00099 rb_obj_classname(super)); 00100 } 00101 if (RBASIC(super)->flags & FL_SINGLETON) { 00102 rb_raise(rb_eTypeError, "can't make subclass of singleton class"); 00103 } 00104 if (super == rb_cClass) { 00105 rb_raise(rb_eTypeError, "can't make subclass of Class"); 00106 } 00107 } 00108 00109 00116 VALUE 00117 rb_class_new(VALUE super) 00118 { 00119 Check_Type(super, T_CLASS); 00120 rb_check_inheritable(super); 00121 return rb_class_boot(super); 00122 } 00123 00124 static NODE* 00125 rewrite_cref_stack(NODE *node, VALUE old_klass, VALUE new_klass) 00126 { 00127 NODE *new_node; 00128 if (!node) { 00129 return NULL; 00130 } 00131 if (node->nd_clss == old_klass) { 00132 new_node = NEW_CREF(new_klass); 00133 new_node->nd_next = node->nd_next; 00134 } else { 00135 new_node = NEW_CREF(node->nd_clss); 00136 new_node->nd_next = rewrite_cref_stack(node->nd_next, old_klass, new_klass); 00137 } 00138 return new_node; 00139 } 00140 00141 static void 00142 clone_method(VALUE klass, ID mid, const rb_method_entry_t *me) 00143 { 00144 VALUE newiseqval; 00145 if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) { 00146 rb_iseq_t *iseq; 00147 newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass); 00148 GetISeqPtr(newiseqval, iseq); 00149 iseq->cref_stack = rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass); 00150 rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); 00151 RB_GC_GUARD(newiseqval); 00152 } 00153 else { 00154 rb_method_entry_set(klass, mid, me, me->flag); 00155 } 00156 } 00157 00158 static int 00159 clone_method_i(st_data_t key, st_data_t value, st_data_t data) 00160 { 00161 clone_method((VALUE)data, (ID)key, (const rb_method_entry_t *)value); 00162 return ST_CONTINUE; 00163 } 00164 00165 static int 00166 clone_const(ID key, const rb_const_entry_t *ce, st_table *tbl) 00167 { 00168 rb_const_entry_t *nce = ALLOC(rb_const_entry_t); 00169 *nce = *ce; 00170 st_insert(tbl, key, (st_data_t)nce); 00171 return ST_CONTINUE; 00172 } 00173 00174 static int 00175 clone_const_i(st_data_t key, st_data_t value, st_data_t data) 00176 { 00177 return clone_const((ID)key, (const rb_const_entry_t *)value, (st_table *)data); 00178 } 00179 00180 static void 00181 class_init_copy_check(VALUE clone, VALUE orig) 00182 { 00183 if (orig == rb_cBasicObject) { 00184 rb_raise(rb_eTypeError, "can't copy the root class"); 00185 } 00186 if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) { 00187 rb_raise(rb_eTypeError, "already initialized class"); 00188 } 00189 if (FL_TEST(orig, FL_SINGLETON)) { 00190 rb_raise(rb_eTypeError, "can't copy singleton class"); 00191 } 00192 } 00193 00194 /* :nodoc: */ 00195 VALUE 00196 rb_mod_init_copy(VALUE clone, VALUE orig) 00197 { 00198 if (RB_TYPE_P(clone, T_CLASS)) { 00199 class_init_copy_check(clone, orig); 00200 } 00201 if (!OBJ_INIT_COPY(clone, orig)) return clone; 00202 if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) { 00203 RBASIC(clone)->klass = rb_singleton_class_clone(orig); 00204 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); 00205 } 00206 RCLASS_SUPER(clone) = RCLASS_SUPER(orig); 00207 RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator; 00208 if (RCLASS_IV_TBL(clone)) { 00209 st_free_table(RCLASS_IV_TBL(clone)); 00210 RCLASS_IV_TBL(clone) = 0; 00211 } 00212 if (RCLASS_CONST_TBL(clone)) { 00213 rb_free_const_table(RCLASS_CONST_TBL(clone)); 00214 RCLASS_CONST_TBL(clone) = 0; 00215 } 00216 if (RCLASS_M_TBL(clone)) { 00217 rb_free_m_table(RCLASS_M_TBL(clone)); 00218 RCLASS_M_TBL(clone) = 0; 00219 } 00220 if (RCLASS_IV_TBL(orig)) { 00221 st_data_t id; 00222 00223 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig)); 00224 CONST_ID(id, "__tmp_classpath__"); 00225 st_delete(RCLASS_IV_TBL(clone), &id, 0); 00226 CONST_ID(id, "__classpath__"); 00227 st_delete(RCLASS_IV_TBL(clone), &id, 0); 00228 CONST_ID(id, "__classid__"); 00229 st_delete(RCLASS_IV_TBL(clone), &id, 0); 00230 } 00231 if (RCLASS_CONST_TBL(orig)) { 00232 00233 RCLASS_CONST_TBL(clone) = st_init_numtable(); 00234 st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone)); 00235 } 00236 if (RCLASS_M_TBL(orig)) { 00237 RCLASS_M_TBL(clone) = st_init_numtable(); 00238 st_foreach(RCLASS_M_TBL(orig), clone_method_i, (st_data_t)clone); 00239 } 00240 00241 return clone; 00242 } 00243 00244 VALUE 00245 rb_singleton_class_clone(VALUE obj) 00246 { 00247 return rb_singleton_class_clone_and_attach(obj, Qundef); 00248 } 00249 00250 VALUE 00251 rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach) 00252 { 00253 VALUE klass = RBASIC(obj)->klass; 00254 00255 if (!FL_TEST(klass, FL_SINGLETON)) 00256 return klass; 00257 else { 00258 /* copy singleton(unnamed) class */ 00259 VALUE clone = class_alloc(RBASIC(klass)->flags, 0); 00260 00261 if (BUILTIN_TYPE(obj) == T_CLASS) { 00262 RBASIC(clone)->klass = clone; 00263 } 00264 else { 00265 RBASIC(clone)->klass = rb_singleton_class_clone(klass); 00266 } 00267 00268 RCLASS_SUPER(clone) = RCLASS_SUPER(klass); 00269 RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator; 00270 if (RCLASS_IV_TBL(klass)) { 00271 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass)); 00272 } 00273 if (RCLASS_CONST_TBL(klass)) { 00274 RCLASS_CONST_TBL(clone) = st_init_numtable(); 00275 st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone)); 00276 } 00277 if (attach != Qundef) { 00278 rb_singleton_class_attached(clone, attach); 00279 } 00280 RCLASS_M_TBL(clone) = st_init_numtable(); 00281 st_foreach(RCLASS_M_TBL(klass), clone_method_i, (st_data_t)clone); 00282 rb_singleton_class_attached(RBASIC(clone)->klass, clone); 00283 FL_SET(clone, FL_SINGLETON); 00284 return clone; 00285 } 00286 } 00287 00292 void 00293 rb_singleton_class_attached(VALUE klass, VALUE obj) 00294 { 00295 if (FL_TEST(klass, FL_SINGLETON)) { 00296 if (!RCLASS_IV_TBL(klass)) { 00297 RCLASS_IV_TBL(klass) = st_init_numtable(); 00298 } 00299 st_insert(RCLASS_IV_TBL(klass), id_attached, obj); 00300 } 00301 } 00302 00303 00304 00305 #define METACLASS_OF(k) RBASIC(k)->klass 00306 00312 #define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k)) 00313 00319 #define HAVE_METACLASS_P(k) \ 00320 (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \ 00321 rb_ivar_get(METACLASS_OF(k), id_attached) == (k)) 00322 00330 #define ENSURE_EIGENCLASS(klass) \ 00331 (HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass)) 00332 00333 00343 static inline VALUE 00344 make_metaclass(VALUE klass) 00345 { 00346 VALUE super; 00347 VALUE metaclass = rb_class_boot(Qundef); 00348 00349 FL_SET(metaclass, FL_SINGLETON); 00350 rb_singleton_class_attached(metaclass, klass); 00351 00352 if (META_CLASS_OF_CLASS_CLASS_P(klass)) { 00353 METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass; 00354 } 00355 else { 00356 VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */ 00357 METACLASS_OF(klass) = metaclass; 00358 METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp); 00359 } 00360 00361 super = RCLASS_SUPER(klass); 00362 while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super); 00363 RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass; 00364 00365 OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass)); 00366 00367 return metaclass; 00368 } 00369 00376 static inline VALUE 00377 make_singleton_class(VALUE obj) 00378 { 00379 VALUE orig_class = RBASIC(obj)->klass; 00380 VALUE klass = rb_class_boot(orig_class); 00381 00382 FL_SET(klass, FL_SINGLETON); 00383 RBASIC(obj)->klass = klass; 00384 rb_singleton_class_attached(klass, obj); 00385 00386 METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class)); 00387 return klass; 00388 } 00389 00390 00391 static VALUE 00392 boot_defclass(const char *name, VALUE super) 00393 { 00394 extern st_table *rb_class_tbl; 00395 VALUE obj = rb_class_boot(super); 00396 ID id = rb_intern(name); 00397 00398 rb_name_class(obj, id); 00399 st_add_direct(rb_class_tbl, id, obj); 00400 rb_const_set((rb_cObject ? rb_cObject : obj), id, obj); 00401 return obj; 00402 } 00403 00404 void 00405 Init_class_hierarchy(void) 00406 { 00407 id_attached = rb_intern("__attached__"); 00408 00409 rb_cBasicObject = boot_defclass("BasicObject", 0); 00410 rb_cObject = boot_defclass("Object", rb_cBasicObject); 00411 rb_cModule = boot_defclass("Module", rb_cObject); 00412 rb_cClass = boot_defclass("Class", rb_cModule); 00413 00414 rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject); 00415 RBASIC(rb_cClass)->klass 00416 = RBASIC(rb_cModule)->klass 00417 = RBASIC(rb_cObject)->klass 00418 = RBASIC(rb_cBasicObject)->klass 00419 = rb_cClass; 00420 } 00421 00422 00433 VALUE 00434 rb_make_metaclass(VALUE obj, VALUE unused) 00435 { 00436 if (BUILTIN_TYPE(obj) == T_CLASS) { 00437 return make_metaclass(obj); 00438 } 00439 else { 00440 return make_singleton_class(obj); 00441 } 00442 } 00443 00444 00455 VALUE 00456 rb_define_class_id(ID id, VALUE super) 00457 { 00458 VALUE klass; 00459 00460 if (!super) super = rb_cObject; 00461 klass = rb_class_new(super); 00462 rb_make_metaclass(klass, RBASIC(super)->klass); 00463 00464 return klass; 00465 } 00466 00467 00476 VALUE 00477 rb_class_inherited(VALUE super, VALUE klass) 00478 { 00479 ID inherited; 00480 if (!super) super = rb_cObject; 00481 CONST_ID(inherited, "inherited"); 00482 return rb_funcall(super, inherited, 1, klass); 00483 } 00484 00485 00486 00502 VALUE 00503 rb_define_class(const char *name, VALUE super) 00504 { 00505 VALUE klass; 00506 ID id; 00507 00508 id = rb_intern(name); 00509 if (rb_const_defined(rb_cObject, id)) { 00510 klass = rb_const_get(rb_cObject, id); 00511 if (!RB_TYPE_P(klass, T_CLASS)) { 00512 rb_raise(rb_eTypeError, "%s is not a class", name); 00513 } 00514 if (rb_class_real(RCLASS_SUPER(klass)) != super) { 00515 rb_raise(rb_eTypeError, "superclass mismatch for class %s", name); 00516 } 00517 return klass; 00518 } 00519 if (!super) { 00520 rb_warn("no super class for `%s', Object assumed", name); 00521 } 00522 klass = rb_define_class_id(id, super); 00523 st_add_direct(rb_class_tbl, id, klass); 00524 rb_name_class(klass, id); 00525 rb_const_set(rb_cObject, id, klass); 00526 rb_class_inherited(super, klass); 00527 00528 return klass; 00529 } 00530 00531 00548 VALUE 00549 rb_define_class_under(VALUE outer, const char *name, VALUE super) 00550 { 00551 return rb_define_class_id_under(outer, rb_intern(name), super); 00552 } 00553 00554 00571 VALUE 00572 rb_define_class_id_under(VALUE outer, ID id, VALUE super) 00573 { 00574 VALUE klass; 00575 00576 if (rb_const_defined_at(outer, id)) { 00577 klass = rb_const_get_at(outer, id); 00578 if (!RB_TYPE_P(klass, T_CLASS)) { 00579 rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id)); 00580 } 00581 if (rb_class_real(RCLASS_SUPER(klass)) != super) { 00582 rb_name_error(id, "%s is already defined", rb_id2name(id)); 00583 } 00584 return klass; 00585 } 00586 if (!super) { 00587 rb_warn("no super class for `%s::%s', Object assumed", 00588 rb_class2name(outer), rb_id2name(id)); 00589 } 00590 klass = rb_define_class_id(id, super); 00591 rb_set_class_path_string(klass, outer, rb_id2str(id)); 00592 rb_const_set(outer, id, klass); 00593 rb_class_inherited(super, klass); 00594 rb_gc_register_mark_object(klass); 00595 00596 return klass; 00597 } 00598 00599 VALUE 00600 rb_module_new(void) 00601 { 00602 VALUE mdl = class_alloc(T_MODULE, rb_cModule); 00603 00604 RCLASS_M_TBL(mdl) = st_init_numtable(); 00605 00606 return (VALUE)mdl; 00607 } 00608 00609 VALUE 00610 rb_define_module_id(ID id) 00611 { 00612 VALUE mdl; 00613 00614 mdl = rb_module_new(); 00615 rb_name_class(mdl, id); 00616 00617 return mdl; 00618 } 00619 00620 VALUE 00621 rb_define_module(const char *name) 00622 { 00623 VALUE module; 00624 ID id; 00625 00626 id = rb_intern(name); 00627 if (rb_const_defined(rb_cObject, id)) { 00628 module = rb_const_get(rb_cObject, id); 00629 if (RB_TYPE_P(module, T_MODULE)) 00630 return module; 00631 rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module)); 00632 } 00633 module = rb_define_module_id(id); 00634 st_add_direct(rb_class_tbl, id, module); 00635 rb_const_set(rb_cObject, id, module); 00636 00637 return module; 00638 } 00639 00640 VALUE 00641 rb_define_module_under(VALUE outer, const char *name) 00642 { 00643 return rb_define_module_id_under(outer, rb_intern(name)); 00644 } 00645 00646 VALUE 00647 rb_define_module_id_under(VALUE outer, ID id) 00648 { 00649 VALUE module; 00650 00651 if (rb_const_defined_at(outer, id)) { 00652 module = rb_const_get_at(outer, id); 00653 if (RB_TYPE_P(module, T_MODULE)) 00654 return module; 00655 rb_raise(rb_eTypeError, "%s::%s is not a module", 00656 rb_class2name(outer), rb_obj_classname(module)); 00657 } 00658 module = rb_define_module_id(id); 00659 rb_const_set(outer, id, module); 00660 rb_set_class_path_string(module, outer, rb_id2str(id)); 00661 rb_gc_register_mark_object(module); 00662 00663 return module; 00664 } 00665 00666 VALUE 00667 rb_include_class_new(VALUE module, VALUE super) 00668 { 00669 VALUE klass = class_alloc(T_ICLASS, rb_cClass); 00670 00671 if (BUILTIN_TYPE(module) == T_ICLASS) { 00672 module = RBASIC(module)->klass; 00673 } 00674 if (!RCLASS_IV_TBL(module)) { 00675 RCLASS_IV_TBL(module) = st_init_numtable(); 00676 } 00677 if (!RCLASS_CONST_TBL(module)) { 00678 RCLASS_CONST_TBL(module) = st_init_numtable(); 00679 } 00680 RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module); 00681 RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module); 00682 RCLASS_M_TBL(klass) = RCLASS_M_TBL(RCLASS_ORIGIN(module)); 00683 RCLASS_SUPER(klass) = super; 00684 if (RB_TYPE_P(module, T_ICLASS)) { 00685 RBASIC(klass)->klass = RBASIC(module)->klass; 00686 } 00687 else { 00688 RBASIC(klass)->klass = module; 00689 } 00690 OBJ_INFECT(klass, module); 00691 OBJ_INFECT(klass, super); 00692 00693 return (VALUE)klass; 00694 } 00695 00696 static int include_modules_at(const VALUE klass, VALUE c, VALUE module); 00697 00698 void 00699 rb_include_module(VALUE klass, VALUE module) 00700 { 00701 int changed = 0; 00702 00703 rb_frozen_class_p(klass); 00704 if (!OBJ_UNTRUSTED(klass)) { 00705 rb_secure(4); 00706 } 00707 00708 if (!RB_TYPE_P(module, T_MODULE)) { 00709 Check_Type(module, T_MODULE); 00710 } 00711 00712 OBJ_INFECT(klass, module); 00713 00714 changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module); 00715 if (changed < 0) 00716 rb_raise(rb_eArgError, "cyclic include detected"); 00717 if (changed) rb_clear_cache(); 00718 } 00719 00720 static int 00721 add_refined_method_entry_i(st_data_t key, st_data_t value, st_data_t data) 00722 { 00723 rb_add_refined_method_entry((VALUE) data, (ID) key); 00724 return ST_CONTINUE; 00725 } 00726 00727 static int 00728 include_modules_at(const VALUE klass, VALUE c, VALUE module) 00729 { 00730 VALUE p; 00731 int changed = 0; 00732 const st_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass)); 00733 00734 while (module) { 00735 int superclass_seen = FALSE; 00736 00737 if (RCLASS_ORIGIN(module) != module) 00738 goto skip; 00739 if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module)) 00740 return -1; 00741 /* ignore if the module included already in superclasses */ 00742 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) { 00743 switch (BUILTIN_TYPE(p)) { 00744 case T_ICLASS: 00745 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) { 00746 if (!superclass_seen) { 00747 c = p; /* move insertion point */ 00748 } 00749 goto skip; 00750 } 00751 break; 00752 case T_CLASS: 00753 superclass_seen = TRUE; 00754 break; 00755 } 00756 } 00757 c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c)); 00758 if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) { 00759 VALUE refined_class = 00760 rb_refinement_module_get_refined_class(klass); 00761 00762 st_foreach(RMODULE_M_TBL(module), add_refined_method_entry_i, 00763 (st_data_t) refined_class); 00764 FL_SET(c, RMODULE_INCLUDED_INTO_REFINEMENT); 00765 } 00766 if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries) 00767 changed = 1; 00768 if (RMODULE_CONST_TBL(module) && RMODULE_CONST_TBL(module)->num_entries) 00769 changed = 1; 00770 skip: 00771 module = RCLASS_SUPER(module); 00772 } 00773 00774 return changed; 00775 } 00776 00777 static int 00778 move_refined_method(st_data_t key, st_data_t value, st_data_t data) 00779 { 00780 rb_method_entry_t *me = (rb_method_entry_t *) value; 00781 st_table *tbl = (st_table *) data; 00782 00783 if (me->def->type == VM_METHOD_TYPE_REFINED) { 00784 if (me->def->body.orig_me) { 00785 rb_method_entry_t *orig_me = me->def->body.orig_me, *new_me; 00786 me->def->body.orig_me = NULL; 00787 new_me = ALLOC(rb_method_entry_t); 00788 *new_me = *me; 00789 st_add_direct(tbl, key, (st_data_t) new_me); 00790 *me = *orig_me; 00791 xfree(orig_me); 00792 return ST_CONTINUE; 00793 } 00794 else { 00795 st_add_direct(tbl, key, (st_data_t) me); 00796 return ST_DELETE; 00797 } 00798 } 00799 else { 00800 return ST_CONTINUE; 00801 } 00802 } 00803 00804 void 00805 rb_prepend_module(VALUE klass, VALUE module) 00806 { 00807 void rb_vm_check_redefinition_by_prepend(VALUE klass); 00808 VALUE origin; 00809 int changed = 0; 00810 00811 rb_frozen_class_p(klass); 00812 if (!OBJ_UNTRUSTED(klass)) { 00813 rb_secure(4); 00814 } 00815 00816 Check_Type(module, T_MODULE); 00817 00818 OBJ_INFECT(klass, module); 00819 00820 origin = RCLASS_ORIGIN(klass); 00821 if (origin == klass) { 00822 origin = class_alloc(T_ICLASS, klass); 00823 RCLASS_SUPER(origin) = RCLASS_SUPER(klass); 00824 RCLASS_SUPER(klass) = origin; 00825 RCLASS_ORIGIN(klass) = origin; 00826 RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass); 00827 RCLASS_M_TBL(klass) = st_init_numtable(); 00828 st_foreach(RCLASS_M_TBL(origin), move_refined_method, 00829 (st_data_t) RCLASS_M_TBL(klass)); 00830 } 00831 changed = include_modules_at(klass, klass, module); 00832 if (changed < 0) 00833 rb_raise(rb_eArgError, "cyclic prepend detected"); 00834 if (changed) { 00835 rb_clear_cache(); 00836 rb_vm_check_redefinition_by_prepend(klass); 00837 } 00838 } 00839 00840 /* 00841 * call-seq: 00842 * mod.included_modules -> array 00843 * 00844 * Returns the list of modules included in <i>mod</i>. 00845 * 00846 * module Mixin 00847 * end 00848 * 00849 * module Outer 00850 * include Mixin 00851 * end 00852 * 00853 * Mixin.included_modules #=> [] 00854 * Outer.included_modules #=> [Mixin] 00855 */ 00856 00857 VALUE 00858 rb_mod_included_modules(VALUE mod) 00859 { 00860 VALUE ary = rb_ary_new(); 00861 VALUE p; 00862 VALUE origin = RCLASS_ORIGIN(mod); 00863 00864 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) { 00865 if (p != origin && BUILTIN_TYPE(p) == T_ICLASS) { 00866 VALUE m = RBASIC(p)->klass; 00867 if (RB_TYPE_P(m, T_MODULE)) 00868 rb_ary_push(ary, m); 00869 } 00870 } 00871 return ary; 00872 } 00873 00874 /* 00875 * call-seq: 00876 * mod.include?(module) -> true or false 00877 * 00878 * Returns <code>true</code> if <i>module</i> is included in 00879 * <i>mod</i> or one of <i>mod</i>'s ancestors. 00880 * 00881 * module A 00882 * end 00883 * class B 00884 * include A 00885 * end 00886 * class C < B 00887 * end 00888 * B.include?(A) #=> true 00889 * C.include?(A) #=> true 00890 * A.include?(A) #=> false 00891 */ 00892 00893 VALUE 00894 rb_mod_include_p(VALUE mod, VALUE mod2) 00895 { 00896 VALUE p; 00897 00898 Check_Type(mod2, T_MODULE); 00899 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) { 00900 if (BUILTIN_TYPE(p) == T_ICLASS) { 00901 if (RBASIC(p)->klass == mod2) return Qtrue; 00902 } 00903 } 00904 return Qfalse; 00905 } 00906 00907 /* 00908 * call-seq: 00909 * mod.ancestors -> array 00910 * 00911 * Returns a list of modules included in <i>mod</i> (including 00912 * <i>mod</i> itself). 00913 * 00914 * module Mod 00915 * include Math 00916 * include Comparable 00917 * end 00918 * 00919 * Mod.ancestors #=> [Mod, Comparable, Math] 00920 * Math.ancestors #=> [Math] 00921 */ 00922 00923 VALUE 00924 rb_mod_ancestors(VALUE mod) 00925 { 00926 VALUE p, ary = rb_ary_new(); 00927 00928 for (p = mod; p; p = RCLASS_SUPER(p)) { 00929 if (FL_TEST(p, FL_SINGLETON)) 00930 continue; 00931 if (BUILTIN_TYPE(p) == T_ICLASS) { 00932 rb_ary_push(ary, RBASIC(p)->klass); 00933 } 00934 else if (p == RCLASS_ORIGIN(p)) { 00935 rb_ary_push(ary, p); 00936 } 00937 } 00938 return ary; 00939 } 00940 00941 #define VISI(x) ((x)&NOEX_MASK) 00942 #define VISI_CHECK(x,f) (VISI(x) == (f)) 00943 00944 static int 00945 ins_methods_push(ID name, long type, VALUE ary, long visi) 00946 { 00947 if (type == -1) return ST_CONTINUE; 00948 00949 switch (visi) { 00950 case NOEX_PRIVATE: 00951 case NOEX_PROTECTED: 00952 case NOEX_PUBLIC: 00953 visi = (type == visi); 00954 break; 00955 default: 00956 visi = (type != NOEX_PRIVATE); 00957 break; 00958 } 00959 if (visi) { 00960 rb_ary_push(ary, ID2SYM(name)); 00961 } 00962 return ST_CONTINUE; 00963 } 00964 00965 static int 00966 ins_methods_i(st_data_t name, st_data_t type, st_data_t ary) 00967 { 00968 return ins_methods_push((ID)name, (long)type, (VALUE)ary, -1); /* everything but private */ 00969 } 00970 00971 static int 00972 ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary) 00973 { 00974 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PROTECTED); 00975 } 00976 00977 static int 00978 ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary) 00979 { 00980 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PRIVATE); 00981 } 00982 00983 static int 00984 ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary) 00985 { 00986 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC); 00987 } 00988 00989 static int 00990 method_entry_i(st_data_t key, st_data_t value, st_data_t data) 00991 { 00992 const rb_method_entry_t *me = (const rb_method_entry_t *)value; 00993 st_table *list = (st_table *)data; 00994 long type; 00995 00996 if (me && me->def->type == VM_METHOD_TYPE_REFINED) { 00997 me = rb_resolve_refined_method(Qnil, me, NULL); 00998 if (!me) return ST_CONTINUE; 00999 } 01000 if (!st_lookup(list, key, 0)) { 01001 if (UNDEFINED_METHOD_ENTRY_P(me)) { 01002 type = -1; /* none */ 01003 } 01004 else { 01005 type = VISI(me->flag); 01006 } 01007 st_add_direct(list, key, type); 01008 } 01009 return ST_CONTINUE; 01010 } 01011 01012 static VALUE 01013 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t)) 01014 { 01015 VALUE ary; 01016 int recur, prepended = 0; 01017 st_table *list; 01018 01019 if (argc == 0) { 01020 recur = TRUE; 01021 } 01022 else { 01023 VALUE r; 01024 rb_scan_args(argc, argv, "01", &r); 01025 recur = RTEST(r); 01026 } 01027 01028 if (!recur && RCLASS_ORIGIN(mod) != mod) { 01029 mod = RCLASS_ORIGIN(mod); 01030 prepended = 1; 01031 } 01032 01033 list = st_init_numtable(); 01034 for (; mod; mod = RCLASS_SUPER(mod)) { 01035 if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list); 01036 if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue; 01037 if (obj && FL_TEST(mod, FL_SINGLETON)) continue; 01038 if (!recur) break; 01039 } 01040 ary = rb_ary_new(); 01041 st_foreach(list, func, ary); 01042 st_free_table(list); 01043 01044 return ary; 01045 } 01046 01047 /* 01048 * call-seq: 01049 * mod.instance_methods(include_super=true) -> array 01050 * 01051 * Returns an array containing the names of the public and protected instance 01052 * methods in the receiver. For a module, these are the public and protected methods; 01053 * for a class, they are the instance (not singleton) methods. With no 01054 * argument, or with an argument that is <code>false</code>, the 01055 * instance methods in <i>mod</i> are returned, otherwise the methods 01056 * in <i>mod</i> and <i>mod</i>'s superclasses are returned. 01057 * 01058 * module A 01059 * def method1() end 01060 * end 01061 * class B 01062 * def method2() end 01063 * end 01064 * class C < B 01065 * def method3() end 01066 * end 01067 * 01068 * A.instance_methods #=> [:method1] 01069 * B.instance_methods(false) #=> [:method2] 01070 * C.instance_methods(false) #=> [:method3] 01071 * C.instance_methods(true).length #=> 43 01072 */ 01073 01074 VALUE 01075 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod) 01076 { 01077 return class_instance_method_list(argc, argv, mod, 0, ins_methods_i); 01078 } 01079 01080 /* 01081 * call-seq: 01082 * mod.protected_instance_methods(include_super=true) -> array 01083 * 01084 * Returns a list of the protected instance methods defined in 01085 * <i>mod</i>. If the optional parameter is not <code>false</code>, the 01086 * methods of any ancestors are included. 01087 */ 01088 01089 VALUE 01090 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod) 01091 { 01092 return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i); 01093 } 01094 01095 /* 01096 * call-seq: 01097 * mod.private_instance_methods(include_super=true) -> array 01098 * 01099 * Returns a list of the private instance methods defined in 01100 * <i>mod</i>. If the optional parameter is not <code>false</code>, the 01101 * methods of any ancestors are included. 01102 * 01103 * module Mod 01104 * def method1() end 01105 * private :method1 01106 * def method2() end 01107 * end 01108 * Mod.instance_methods #=> [:method2] 01109 * Mod.private_instance_methods #=> [:method1] 01110 */ 01111 01112 VALUE 01113 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod) 01114 { 01115 return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i); 01116 } 01117 01118 /* 01119 * call-seq: 01120 * mod.public_instance_methods(include_super=true) -> array 01121 * 01122 * Returns a list of the public instance methods defined in <i>mod</i>. 01123 * If the optional parameter is not <code>false</code>, the methods of 01124 * any ancestors are included. 01125 */ 01126 01127 VALUE 01128 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod) 01129 { 01130 return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i); 01131 } 01132 01133 /* 01134 * call-seq: 01135 * obj.methods(all=true) -> array 01136 * 01137 * Returns a list of the names of public and protected methods of 01138 * <i>obj</i>. This will include all the methods accessible in 01139 * <i>obj</i>'s ancestors. 01140 * If the <i>all</i> parameter is set to <code>false</code>, only those methods 01141 * in the receiver will be listed. 01142 * 01143 * class Klass 01144 * def klass_method() 01145 * end 01146 * end 01147 * k = Klass.new 01148 * k.methods[0..9] #=> [:klass_method, :nil?, :===, 01149 * # :==~, :!, :eql? 01150 * # :hash, :<=>, :class, :singleton_class] 01151 * k.methods.length #=> 57 01152 */ 01153 01154 VALUE 01155 rb_obj_methods(int argc, VALUE *argv, VALUE obj) 01156 { 01157 retry: 01158 if (argc == 0) { 01159 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i); 01160 } 01161 else { 01162 VALUE recur; 01163 01164 rb_scan_args(argc, argv, "1", &recur); 01165 if (RTEST(recur)) { 01166 argc = 0; 01167 goto retry; 01168 } 01169 return rb_obj_singleton_methods(argc, argv, obj); 01170 } 01171 } 01172 01173 /* 01174 * call-seq: 01175 * obj.protected_methods(all=true) -> array 01176 * 01177 * Returns the list of protected methods accessible to <i>obj</i>. If 01178 * the <i>all</i> parameter is set to <code>false</code>, only those methods 01179 * in the receiver will be listed. 01180 */ 01181 01182 VALUE 01183 rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj) 01184 { 01185 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i); 01186 } 01187 01188 /* 01189 * call-seq: 01190 * obj.private_methods(all=true) -> array 01191 * 01192 * Returns the list of private methods accessible to <i>obj</i>. If 01193 * the <i>all</i> parameter is set to <code>false</code>, only those methods 01194 * in the receiver will be listed. 01195 */ 01196 01197 VALUE 01198 rb_obj_private_methods(int argc, VALUE *argv, VALUE obj) 01199 { 01200 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i); 01201 } 01202 01203 /* 01204 * call-seq: 01205 * obj.public_methods(all=true) -> array 01206 * 01207 * Returns the list of public methods accessible to <i>obj</i>. If 01208 * the <i>all</i> parameter is set to <code>false</code>, only those methods 01209 * in the receiver will be listed. 01210 */ 01211 01212 VALUE 01213 rb_obj_public_methods(int argc, VALUE *argv, VALUE obj) 01214 { 01215 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i); 01216 } 01217 01218 /* 01219 * call-seq: 01220 * obj.singleton_methods(all=true) -> array 01221 * 01222 * Returns an array of the names of singleton methods for <i>obj</i>. 01223 * If the optional <i>all</i> parameter is true, the list will include 01224 * methods in modules included in <i>obj</i>. 01225 * Only public and protected singleton methods are returned. 01226 * 01227 * module Other 01228 * def three() end 01229 * end 01230 * 01231 * class Single 01232 * def Single.four() end 01233 * end 01234 * 01235 * a = Single.new 01236 * 01237 * def a.one() 01238 * end 01239 * 01240 * class << a 01241 * include Other 01242 * def two() 01243 * end 01244 * end 01245 * 01246 * Single.singleton_methods #=> [:four] 01247 * a.singleton_methods(false) #=> [:two, :one] 01248 * a.singleton_methods #=> [:two, :one, :three] 01249 */ 01250 01251 VALUE 01252 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj) 01253 { 01254 VALUE recur, ary, klass; 01255 st_table *list; 01256 01257 if (argc == 0) { 01258 recur = Qtrue; 01259 } 01260 else { 01261 rb_scan_args(argc, argv, "01", &recur); 01262 } 01263 klass = CLASS_OF(obj); 01264 list = st_init_numtable(); 01265 if (klass && FL_TEST(klass, FL_SINGLETON)) { 01266 if (RCLASS_M_TBL(klass)) 01267 st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list); 01268 klass = RCLASS_SUPER(klass); 01269 } 01270 if (RTEST(recur)) { 01271 while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) { 01272 if (RCLASS_M_TBL(klass)) 01273 st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list); 01274 klass = RCLASS_SUPER(klass); 01275 } 01276 } 01277 ary = rb_ary_new(); 01278 st_foreach(list, ins_methods_i, ary); 01279 st_free_table(list); 01280 01281 return ary; 01282 } 01283 01341 void 01342 rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc) 01343 { 01344 rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC); 01345 } 01346 01347 void 01348 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) 01349 { 01350 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC); 01351 } 01352 01353 void 01354 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) 01355 { 01356 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED); 01357 } 01358 01359 void 01360 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) 01361 { 01362 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE); 01363 } 01364 01365 void 01366 rb_undef_method(VALUE klass, const char *name) 01367 { 01368 rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF); 01369 } 01370 01379 #define SPECIAL_SINGLETON(x,c) do {\ 01380 if (obj == (x)) {\ 01381 return (c);\ 01382 }\ 01383 } while (0) 01384 01385 static inline VALUE 01386 special_singleton_class_of(VALUE obj) 01387 { 01388 SPECIAL_SINGLETON(Qnil, rb_cNilClass); 01389 SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); 01390 SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); 01391 return Qnil; 01392 } 01393 01394 VALUE 01395 rb_special_singleton_class(VALUE obj) 01396 { 01397 return special_singleton_class_of(obj); 01398 } 01399 01409 static VALUE 01410 singleton_class_of(VALUE obj) 01411 { 01412 VALUE klass; 01413 01414 if (FIXNUM_P(obj) || FLONUM_P(obj) || SYMBOL_P(obj)) { 01415 rb_raise(rb_eTypeError, "can't define singleton"); 01416 } 01417 if (SPECIAL_CONST_P(obj)) { 01418 klass = special_singleton_class_of(obj); 01419 if (NIL_P(klass)) 01420 rb_bug("unknown immediate %p", (void *)obj); 01421 return klass; 01422 } 01423 else { 01424 enum ruby_value_type type = BUILTIN_TYPE(obj); 01425 if (type == T_FLOAT || type == T_BIGNUM) { 01426 rb_raise(rb_eTypeError, "can't define singleton"); 01427 } 01428 } 01429 01430 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && 01431 rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) { 01432 klass = RBASIC(obj)->klass; 01433 } 01434 else { 01435 klass = rb_make_metaclass(obj, RBASIC(obj)->klass); 01436 } 01437 01438 if (OBJ_TAINTED(obj)) { 01439 OBJ_TAINT(klass); 01440 } 01441 else { 01442 FL_UNSET(klass, FL_TAINT); 01443 } 01444 if (OBJ_UNTRUSTED(obj)) { 01445 OBJ_UNTRUST(klass); 01446 } 01447 else { 01448 FL_UNSET(klass, FL_UNTRUSTED); 01449 } 01450 if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); 01451 01452 return klass; 01453 } 01454 01455 01473 VALUE 01474 rb_singleton_class(VALUE obj) 01475 { 01476 VALUE klass = singleton_class_of(obj); 01477 01478 /* ensures an exposed class belongs to its own eigenclass */ 01479 if (RB_TYPE_P(obj, T_CLASS)) (void)ENSURE_EIGENCLASS(klass); 01480 01481 return klass; 01482 } 01483 01500 void 01501 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc) 01502 { 01503 rb_define_method(singleton_class_of(obj), name, func, argc); 01504 } 01505 01506 01507 01515 void 01516 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc) 01517 { 01518 rb_define_private_method(module, name, func, argc); 01519 rb_define_singleton_method(module, name, func, argc); 01520 } 01521 01522 01529 void 01530 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc) 01531 { 01532 rb_define_module_function(rb_mKernel, name, func, argc); 01533 } 01534 01535 01542 void 01543 rb_define_alias(VALUE klass, const char *name1, const char *name2) 01544 { 01545 rb_alias(klass, rb_intern(name1), rb_intern(name2)); 01546 } 01547 01555 void 01556 rb_define_attr(VALUE klass, const char *name, int read, int write) 01557 { 01558 rb_attr(klass, rb_intern(name), read, write, FALSE); 01559 } 01560 01561 int 01562 rb_obj_basic_to_s_p(VALUE obj) 01563 { 01564 const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s"), 0); 01565 if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC && 01566 me->def->body.cfunc.func == rb_any_to_s) 01567 return 1; 01568 return 0; 01569 } 01570 01571 #include <stdarg.h> 01572 01573 int 01574 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) 01575 { 01576 int i; 01577 const char *p = fmt; 01578 VALUE *var; 01579 va_list vargs; 01580 int f_var = 0, f_hash = 0, f_block = 0; 01581 int n_lead = 0, n_opt = 0, n_trail = 0, n_mand; 01582 int argi = 0; 01583 VALUE hash = Qnil; 01584 01585 if (ISDIGIT(*p)) { 01586 n_lead = *p - '0'; 01587 p++; 01588 if (ISDIGIT(*p)) { 01589 n_opt = *p - '0'; 01590 p++; 01591 if (ISDIGIT(*p)) { 01592 n_trail = *p - '0'; 01593 p++; 01594 goto block_arg; 01595 } 01596 } 01597 } 01598 if (*p == '*') { 01599 f_var = 1; 01600 p++; 01601 if (ISDIGIT(*p)) { 01602 n_trail = *p - '0'; 01603 p++; 01604 } 01605 } 01606 block_arg: 01607 if (*p == ':') { 01608 f_hash = 1; 01609 p++; 01610 } 01611 if (*p == '&') { 01612 f_block = 1; 01613 p++; 01614 } 01615 if (*p != '\0') { 01616 rb_fatal("bad scan arg format: %s", fmt); 01617 } 01618 n_mand = n_lead + n_trail; 01619 01620 if (argc < n_mand) 01621 goto argc_error; 01622 01623 va_start(vargs, fmt); 01624 01625 /* capture an option hash - phase 1: pop */ 01626 if (f_hash && n_mand < argc) { 01627 VALUE last = argv[argc - 1]; 01628 01629 if (NIL_P(last)) { 01630 /* nil is taken as an empty option hash only if it is not 01631 ambiguous; i.e. '*' is not specified and arguments are 01632 given more than sufficient */ 01633 if (!f_var && n_mand + n_opt < argc) 01634 argc--; 01635 } 01636 else { 01637 hash = rb_check_hash_type(last); 01638 if (!NIL_P(hash)) 01639 argc--; 01640 } 01641 } 01642 /* capture leading mandatory arguments */ 01643 for (i = n_lead; i-- > 0; ) { 01644 var = va_arg(vargs, VALUE *); 01645 if (var) *var = argv[argi]; 01646 argi++; 01647 } 01648 /* capture optional arguments */ 01649 for (i = n_opt; i-- > 0; ) { 01650 var = va_arg(vargs, VALUE *); 01651 if (argi < argc - n_trail) { 01652 if (var) *var = argv[argi]; 01653 argi++; 01654 } 01655 else { 01656 if (var) *var = Qnil; 01657 } 01658 } 01659 /* capture variable length arguments */ 01660 if (f_var) { 01661 int n_var = argc - argi - n_trail; 01662 01663 var = va_arg(vargs, VALUE *); 01664 if (0 < n_var) { 01665 if (var) *var = rb_ary_new4(n_var, &argv[argi]); 01666 argi += n_var; 01667 } 01668 else { 01669 if (var) *var = rb_ary_new(); 01670 } 01671 } 01672 /* capture trailing mandatory arguments */ 01673 for (i = n_trail; i-- > 0; ) { 01674 var = va_arg(vargs, VALUE *); 01675 if (var) *var = argv[argi]; 01676 argi++; 01677 } 01678 /* capture an option hash - phase 2: assignment */ 01679 if (f_hash) { 01680 var = va_arg(vargs, VALUE *); 01681 if (var) *var = hash; 01682 } 01683 /* capture iterator block */ 01684 if (f_block) { 01685 var = va_arg(vargs, VALUE *); 01686 if (rb_block_given_p()) { 01687 *var = rb_block_proc(); 01688 } 01689 else { 01690 *var = Qnil; 01691 } 01692 } 01693 va_end(vargs); 01694 01695 if (argi < argc) { 01696 argc_error: 01697 rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt); 01698 } 01699 01700 return argc; 01701 } 01702
1.7.6.1