Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /********************************************************************** 00002 00003 class.c - 00004 00005 $Author: nagachika $ 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 rb_obj_init_copy(clone, orig); 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(orig)) { 00209 st_data_t id; 00210 00211 if (RCLASS_IV_TBL(clone)) { 00212 st_free_table(RCLASS_IV_TBL(clone)); 00213 } 00214 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig)); 00215 CONST_ID(id, "__tmp_classpath__"); 00216 st_delete(RCLASS_IV_TBL(clone), &id, 0); 00217 CONST_ID(id, "__classpath__"); 00218 st_delete(RCLASS_IV_TBL(clone), &id, 0); 00219 CONST_ID(id, "__classid__"); 00220 st_delete(RCLASS_IV_TBL(clone), &id, 0); 00221 } 00222 if (RCLASS_CONST_TBL(orig)) { 00223 if (RCLASS_CONST_TBL(clone)) { 00224 rb_free_const_table(RCLASS_CONST_TBL(clone)); 00225 } 00226 RCLASS_CONST_TBL(clone) = st_init_numtable(); 00227 st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone)); 00228 } 00229 if (RCLASS_M_TBL(orig)) { 00230 if (RCLASS_M_TBL(clone)) { 00231 rb_free_m_table(RCLASS_M_TBL(clone)); 00232 } 00233 RCLASS_M_TBL(clone) = st_init_numtable(); 00234 st_foreach(RCLASS_M_TBL(orig), clone_method_i, (st_data_t)clone); 00235 } 00236 00237 return clone; 00238 } 00239 00240 VALUE 00241 rb_singleton_class_clone(VALUE obj) 00242 { 00243 return rb_singleton_class_clone_and_attach(obj, Qundef); 00244 } 00245 00246 VALUE 00247 rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach) 00248 { 00249 VALUE klass = RBASIC(obj)->klass; 00250 00251 if (!FL_TEST(klass, FL_SINGLETON)) 00252 return klass; 00253 else { 00254 /* copy singleton(unnamed) class */ 00255 VALUE clone = class_alloc(RBASIC(klass)->flags, 0); 00256 00257 if (BUILTIN_TYPE(obj) == T_CLASS) { 00258 RBASIC(clone)->klass = clone; 00259 } 00260 else { 00261 RBASIC(clone)->klass = rb_singleton_class_clone(klass); 00262 } 00263 00264 RCLASS_SUPER(clone) = RCLASS_SUPER(klass); 00265 RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator; 00266 if (RCLASS_IV_TBL(klass)) { 00267 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass)); 00268 } 00269 if (RCLASS_CONST_TBL(klass)) { 00270 RCLASS_CONST_TBL(clone) = st_init_numtable(); 00271 st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone)); 00272 } 00273 if (attach != Qundef) { 00274 rb_singleton_class_attached(clone, attach); 00275 } 00276 RCLASS_M_TBL(clone) = st_init_numtable(); 00277 st_foreach(RCLASS_M_TBL(klass), clone_method_i, (st_data_t)clone); 00278 rb_singleton_class_attached(RBASIC(clone)->klass, clone); 00279 FL_SET(clone, FL_SINGLETON); 00280 return clone; 00281 } 00282 } 00283 00288 void 00289 rb_singleton_class_attached(VALUE klass, VALUE obj) 00290 { 00291 if (FL_TEST(klass, FL_SINGLETON)) { 00292 if (!RCLASS_IV_TBL(klass)) { 00293 RCLASS_IV_TBL(klass) = st_init_numtable(); 00294 } 00295 st_insert(RCLASS_IV_TBL(klass), id_attached, obj); 00296 } 00297 } 00298 00299 00300 00301 #define METACLASS_OF(k) RBASIC(k)->klass 00302 00308 #define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k)) 00309 00315 #define HAVE_METACLASS_P(k) \ 00316 (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \ 00317 rb_ivar_get(METACLASS_OF(k), id_attached) == (k)) 00318 00326 #define ENSURE_EIGENCLASS(klass) \ 00327 (HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass)) 00328 00329 00339 static inline VALUE 00340 make_metaclass(VALUE klass) 00341 { 00342 VALUE super; 00343 VALUE metaclass = rb_class_boot(Qundef); 00344 00345 FL_SET(metaclass, FL_SINGLETON); 00346 rb_singleton_class_attached(metaclass, klass); 00347 00348 if (META_CLASS_OF_CLASS_CLASS_P(klass)) { 00349 METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass; 00350 } 00351 else { 00352 VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */ 00353 METACLASS_OF(klass) = metaclass; 00354 METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp); 00355 } 00356 00357 super = RCLASS_SUPER(klass); 00358 while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super); 00359 RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass; 00360 00361 OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass)); 00362 00363 return metaclass; 00364 } 00365 00372 static inline VALUE 00373 make_singleton_class(VALUE obj) 00374 { 00375 VALUE orig_class = RBASIC(obj)->klass; 00376 VALUE klass = rb_class_boot(orig_class); 00377 00378 FL_SET(klass, FL_SINGLETON); 00379 RBASIC(obj)->klass = klass; 00380 rb_singleton_class_attached(klass, obj); 00381 00382 METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class)); 00383 return klass; 00384 } 00385 00386 00387 static VALUE 00388 boot_defclass(const char *name, VALUE super) 00389 { 00390 extern st_table *rb_class_tbl; 00391 VALUE obj = rb_class_boot(super); 00392 ID id = rb_intern(name); 00393 00394 rb_name_class(obj, id); 00395 st_add_direct(rb_class_tbl, id, obj); 00396 rb_const_set((rb_cObject ? rb_cObject : obj), id, obj); 00397 return obj; 00398 } 00399 00400 void 00401 Init_class_hierarchy(void) 00402 { 00403 id_attached = rb_intern("__attached__"); 00404 00405 rb_cBasicObject = boot_defclass("BasicObject", 0); 00406 rb_cObject = boot_defclass("Object", rb_cBasicObject); 00407 rb_cModule = boot_defclass("Module", rb_cObject); 00408 rb_cClass = boot_defclass("Class", rb_cModule); 00409 00410 rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject); 00411 RBASIC(rb_cClass)->klass 00412 = RBASIC(rb_cModule)->klass 00413 = RBASIC(rb_cObject)->klass 00414 = RBASIC(rb_cBasicObject)->klass 00415 = rb_cClass; 00416 } 00417 00418 00429 VALUE 00430 rb_make_metaclass(VALUE obj, VALUE unused) 00431 { 00432 if (BUILTIN_TYPE(obj) == T_CLASS) { 00433 return make_metaclass(obj); 00434 } 00435 else { 00436 return make_singleton_class(obj); 00437 } 00438 } 00439 00440 00451 VALUE 00452 rb_define_class_id(ID id, VALUE super) 00453 { 00454 VALUE klass; 00455 00456 if (!super) super = rb_cObject; 00457 klass = rb_class_new(super); 00458 rb_make_metaclass(klass, RBASIC(super)->klass); 00459 00460 return klass; 00461 } 00462 00463 00472 VALUE 00473 rb_class_inherited(VALUE super, VALUE klass) 00474 { 00475 ID inherited; 00476 if (!super) super = rb_cObject; 00477 CONST_ID(inherited, "inherited"); 00478 return rb_funcall(super, inherited, 1, klass); 00479 } 00480 00481 00482 00498 VALUE 00499 rb_define_class(const char *name, VALUE super) 00500 { 00501 VALUE klass; 00502 ID id; 00503 00504 id = rb_intern(name); 00505 if (rb_const_defined(rb_cObject, id)) { 00506 klass = rb_const_get(rb_cObject, id); 00507 if (!RB_TYPE_P(klass, T_CLASS)) { 00508 rb_raise(rb_eTypeError, "%s is not a class", name); 00509 } 00510 if (rb_class_real(RCLASS_SUPER(klass)) != super) { 00511 rb_raise(rb_eTypeError, "superclass mismatch for class %s", name); 00512 } 00513 return klass; 00514 } 00515 if (!super) { 00516 rb_warn("no super class for `%s', Object assumed", name); 00517 } 00518 klass = rb_define_class_id(id, super); 00519 st_add_direct(rb_class_tbl, id, klass); 00520 rb_name_class(klass, id); 00521 rb_const_set(rb_cObject, id, klass); 00522 rb_class_inherited(super, klass); 00523 00524 return klass; 00525 } 00526 00527 00544 VALUE 00545 rb_define_class_under(VALUE outer, const char *name, VALUE super) 00546 { 00547 return rb_define_class_id_under(outer, rb_intern(name), super); 00548 } 00549 00550 00567 VALUE 00568 rb_define_class_id_under(VALUE outer, ID id, VALUE super) 00569 { 00570 VALUE klass; 00571 00572 if (rb_const_defined_at(outer, id)) { 00573 klass = rb_const_get_at(outer, id); 00574 if (!RB_TYPE_P(klass, T_CLASS)) { 00575 rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id)); 00576 } 00577 if (rb_class_real(RCLASS_SUPER(klass)) != super) { 00578 rb_name_error(id, "%s is already defined", rb_id2name(id)); 00579 } 00580 return klass; 00581 } 00582 if (!super) { 00583 rb_warn("no super class for `%s::%s', Object assumed", 00584 rb_class2name(outer), rb_id2name(id)); 00585 } 00586 klass = rb_define_class_id(id, super); 00587 rb_set_class_path_string(klass, outer, rb_id2str(id)); 00588 rb_const_set(outer, id, klass); 00589 rb_class_inherited(super, klass); 00590 rb_gc_register_mark_object(klass); 00591 00592 return klass; 00593 } 00594 00595 VALUE 00596 rb_module_new(void) 00597 { 00598 VALUE mdl = class_alloc(T_MODULE, rb_cModule); 00599 00600 RCLASS_M_TBL(mdl) = st_init_numtable(); 00601 00602 return (VALUE)mdl; 00603 } 00604 00605 VALUE 00606 rb_define_module_id(ID id) 00607 { 00608 VALUE mdl; 00609 00610 mdl = rb_module_new(); 00611 rb_name_class(mdl, id); 00612 00613 return mdl; 00614 } 00615 00616 VALUE 00617 rb_define_module(const char *name) 00618 { 00619 VALUE module; 00620 ID id; 00621 00622 id = rb_intern(name); 00623 if (rb_const_defined(rb_cObject, id)) { 00624 module = rb_const_get(rb_cObject, id); 00625 if (RB_TYPE_P(module, T_MODULE)) 00626 return module; 00627 rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module)); 00628 } 00629 module = rb_define_module_id(id); 00630 st_add_direct(rb_class_tbl, id, module); 00631 rb_const_set(rb_cObject, id, module); 00632 00633 return module; 00634 } 00635 00636 VALUE 00637 rb_define_module_under(VALUE outer, const char *name) 00638 { 00639 return rb_define_module_id_under(outer, rb_intern(name)); 00640 } 00641 00642 VALUE 00643 rb_define_module_id_under(VALUE outer, ID id) 00644 { 00645 VALUE module; 00646 00647 if (rb_const_defined_at(outer, id)) { 00648 module = rb_const_get_at(outer, id); 00649 if (RB_TYPE_P(module, T_MODULE)) 00650 return module; 00651 rb_raise(rb_eTypeError, "%s::%s is not a module", 00652 rb_class2name(outer), rb_obj_classname(module)); 00653 } 00654 module = rb_define_module_id(id); 00655 rb_const_set(outer, id, module); 00656 rb_set_class_path_string(module, outer, rb_id2str(id)); 00657 rb_gc_register_mark_object(module); 00658 00659 return module; 00660 } 00661 00662 VALUE 00663 rb_include_class_new(VALUE module, VALUE super) 00664 { 00665 VALUE klass = class_alloc(T_ICLASS, rb_cClass); 00666 00667 if (BUILTIN_TYPE(module) == T_ICLASS) { 00668 module = RBASIC(module)->klass; 00669 } 00670 if (!RCLASS_IV_TBL(module)) { 00671 RCLASS_IV_TBL(module) = st_init_numtable(); 00672 } 00673 if (!RCLASS_CONST_TBL(module)) { 00674 RCLASS_CONST_TBL(module) = st_init_numtable(); 00675 } 00676 RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module); 00677 RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module); 00678 RCLASS_M_TBL(klass) = RCLASS_M_TBL(RCLASS_ORIGIN(module)); 00679 RCLASS_SUPER(klass) = super; 00680 if (RB_TYPE_P(module, T_ICLASS)) { 00681 RBASIC(klass)->klass = RBASIC(module)->klass; 00682 } 00683 else { 00684 RBASIC(klass)->klass = module; 00685 } 00686 OBJ_INFECT(klass, module); 00687 OBJ_INFECT(klass, super); 00688 00689 return (VALUE)klass; 00690 } 00691 00692 static int include_modules_at(const VALUE klass, VALUE c, VALUE module); 00693 00694 void 00695 rb_include_module(VALUE klass, VALUE module) 00696 { 00697 int changed = 0; 00698 00699 rb_frozen_class_p(klass); 00700 if (!OBJ_UNTRUSTED(klass)) { 00701 rb_secure(4); 00702 } 00703 00704 if (!RB_TYPE_P(module, T_MODULE)) { 00705 Check_Type(module, T_MODULE); 00706 } 00707 00708 OBJ_INFECT(klass, module); 00709 00710 changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module); 00711 if (changed < 0) 00712 rb_raise(rb_eArgError, "cyclic include detected"); 00713 if (changed) rb_clear_cache(); 00714 } 00715 00716 static int 00717 add_refined_method_entry_i(st_data_t key, st_data_t value, st_data_t data) 00718 { 00719 rb_add_refined_method_entry((VALUE) data, (ID) key); 00720 return ST_CONTINUE; 00721 } 00722 00723 static int 00724 include_modules_at(const VALUE klass, VALUE c, VALUE module) 00725 { 00726 VALUE p; 00727 int changed = 0; 00728 const st_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass)); 00729 00730 while (module) { 00731 int superclass_seen = FALSE; 00732 00733 if (RCLASS_ORIGIN(module) != module) 00734 goto skip; 00735 if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module)) 00736 return -1; 00737 /* ignore if the module included already in superclasses */ 00738 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) { 00739 switch (BUILTIN_TYPE(p)) { 00740 case T_ICLASS: 00741 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) { 00742 if (!superclass_seen) { 00743 c = p; /* move insertion point */ 00744 } 00745 goto skip; 00746 } 00747 break; 00748 case T_CLASS: 00749 superclass_seen = TRUE; 00750 break; 00751 } 00752 } 00753 c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c)); 00754 if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) { 00755 VALUE refined_class = 00756 rb_refinement_module_get_refined_class(klass); 00757 00758 st_foreach(RMODULE_M_TBL(module), add_refined_method_entry_i, 00759 (st_data_t) refined_class); 00760 FL_SET(c, RMODULE_INCLUDED_INTO_REFINEMENT); 00761 } 00762 if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries) 00763 changed = 1; 00764 if (RMODULE_CONST_TBL(module) && RMODULE_CONST_TBL(module)->num_entries) 00765 changed = 1; 00766 skip: 00767 module = RCLASS_SUPER(module); 00768 } 00769 00770 return changed; 00771 } 00772 00773 static int 00774 move_refined_method(st_data_t key, st_data_t value, st_data_t data) 00775 { 00776 rb_method_entry_t *me = (rb_method_entry_t *) value; 00777 st_table *tbl = (st_table *) data; 00778 00779 if (me->def->type == VM_METHOD_TYPE_REFINED) { 00780 if (me->def->body.orig_me) { 00781 rb_method_entry_t *orig_me = me->def->body.orig_me, *new_me; 00782 me->def->body.orig_me = NULL; 00783 new_me = ALLOC(rb_method_entry_t); 00784 *new_me = *me; 00785 st_add_direct(tbl, key, (st_data_t) new_me); 00786 *me = *orig_me; 00787 xfree(orig_me); 00788 return ST_CONTINUE; 00789 } 00790 else { 00791 st_add_direct(tbl, key, (st_data_t) me); 00792 return ST_DELETE; 00793 } 00794 } 00795 else { 00796 return ST_CONTINUE; 00797 } 00798 } 00799 00800 void 00801 rb_prepend_module(VALUE klass, VALUE module) 00802 { 00803 void rb_vm_check_redefinition_by_prepend(VALUE klass); 00804 VALUE origin; 00805 int changed = 0; 00806 00807 rb_frozen_class_p(klass); 00808 if (!OBJ_UNTRUSTED(klass)) { 00809 rb_secure(4); 00810 } 00811 00812 Check_Type(module, T_MODULE); 00813 00814 OBJ_INFECT(klass, module); 00815 00816 origin = RCLASS_ORIGIN(klass); 00817 if (origin == klass) { 00818 origin = class_alloc(T_ICLASS, klass); 00819 RCLASS_SUPER(origin) = RCLASS_SUPER(klass); 00820 RCLASS_SUPER(klass) = origin; 00821 RCLASS_ORIGIN(klass) = origin; 00822 RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass); 00823 RCLASS_M_TBL(klass) = st_init_numtable(); 00824 st_foreach(RCLASS_M_TBL(origin), move_refined_method, 00825 (st_data_t) RCLASS_M_TBL(klass)); 00826 } 00827 changed = include_modules_at(klass, klass, module); 00828 if (changed < 0) 00829 rb_raise(rb_eArgError, "cyclic prepend detected"); 00830 if (changed) { 00831 rb_clear_cache(); 00832 rb_vm_check_redefinition_by_prepend(klass); 00833 } 00834 } 00835 00836 /* 00837 * call-seq: 00838 * mod.included_modules -> array 00839 * 00840 * Returns the list of modules included in <i>mod</i>. 00841 * 00842 * module Mixin 00843 * end 00844 * 00845 * module Outer 00846 * include Mixin 00847 * end 00848 * 00849 * Mixin.included_modules #=> [] 00850 * Outer.included_modules #=> [Mixin] 00851 */ 00852 00853 VALUE 00854 rb_mod_included_modules(VALUE mod) 00855 { 00856 VALUE ary = rb_ary_new(); 00857 VALUE p; 00858 VALUE origin = RCLASS_ORIGIN(mod); 00859 00860 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) { 00861 if (p != origin && BUILTIN_TYPE(p) == T_ICLASS) { 00862 VALUE m = RBASIC(p)->klass; 00863 if (RB_TYPE_P(m, T_MODULE)) 00864 rb_ary_push(ary, m); 00865 } 00866 } 00867 return ary; 00868 } 00869 00870 /* 00871 * call-seq: 00872 * mod.include?(module) -> true or false 00873 * 00874 * Returns <code>true</code> if <i>module</i> is included in 00875 * <i>mod</i> or one of <i>mod</i>'s ancestors. 00876 * 00877 * module A 00878 * end 00879 * class B 00880 * include A 00881 * end 00882 * class C < B 00883 * end 00884 * B.include?(A) #=> true 00885 * C.include?(A) #=> true 00886 * A.include?(A) #=> false 00887 */ 00888 00889 VALUE 00890 rb_mod_include_p(VALUE mod, VALUE mod2) 00891 { 00892 VALUE p; 00893 00894 Check_Type(mod2, T_MODULE); 00895 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) { 00896 if (BUILTIN_TYPE(p) == T_ICLASS) { 00897 if (RBASIC(p)->klass == mod2) return Qtrue; 00898 } 00899 } 00900 return Qfalse; 00901 } 00902 00903 /* 00904 * call-seq: 00905 * mod.ancestors -> array 00906 * 00907 * Returns a list of modules included in <i>mod</i> (including 00908 * <i>mod</i> itself). 00909 * 00910 * module Mod 00911 * include Math 00912 * include Comparable 00913 * end 00914 * 00915 * Mod.ancestors #=> [Mod, Comparable, Math] 00916 * Math.ancestors #=> [Math] 00917 */ 00918 00919 VALUE 00920 rb_mod_ancestors(VALUE mod) 00921 { 00922 VALUE p, ary = rb_ary_new(); 00923 00924 for (p = mod; p; p = RCLASS_SUPER(p)) { 00925 if (FL_TEST(p, FL_SINGLETON)) 00926 continue; 00927 if (BUILTIN_TYPE(p) == T_ICLASS) { 00928 rb_ary_push(ary, RBASIC(p)->klass); 00929 } 00930 else if (p == RCLASS_ORIGIN(p)) { 00931 rb_ary_push(ary, p); 00932 } 00933 } 00934 return ary; 00935 } 00936 00937 #define VISI(x) ((x)&NOEX_MASK) 00938 #define VISI_CHECK(x,f) (VISI(x) == (f)) 00939 00940 static int 00941 ins_methods_push(ID name, long type, VALUE ary, long visi) 00942 { 00943 if (type == -1) return ST_CONTINUE; 00944 00945 switch (visi) { 00946 case NOEX_PRIVATE: 00947 case NOEX_PROTECTED: 00948 case NOEX_PUBLIC: 00949 visi = (type == visi); 00950 break; 00951 default: 00952 visi = (type != NOEX_PRIVATE); 00953 break; 00954 } 00955 if (visi) { 00956 rb_ary_push(ary, ID2SYM(name)); 00957 } 00958 return ST_CONTINUE; 00959 } 00960 00961 static int 00962 ins_methods_i(st_data_t name, st_data_t type, st_data_t ary) 00963 { 00964 return ins_methods_push((ID)name, (long)type, (VALUE)ary, -1); /* everything but private */ 00965 } 00966 00967 static int 00968 ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary) 00969 { 00970 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PROTECTED); 00971 } 00972 00973 static int 00974 ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary) 00975 { 00976 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PRIVATE); 00977 } 00978 00979 static int 00980 ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary) 00981 { 00982 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC); 00983 } 00984 00985 static int 00986 method_entry_i(st_data_t key, st_data_t value, st_data_t data) 00987 { 00988 const rb_method_entry_t *me = (const rb_method_entry_t *)value; 00989 st_table *list = (st_table *)data; 00990 long type; 00991 00992 if (!st_lookup(list, key, 0)) { 00993 if (UNDEFINED_METHOD_ENTRY_P(me)) { 00994 type = -1; /* none */ 00995 } 00996 else { 00997 type = VISI(me->flag); 00998 } 00999 st_add_direct(list, key, type); 01000 } 01001 return ST_CONTINUE; 01002 } 01003 01004 static VALUE 01005 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t)) 01006 { 01007 VALUE ary; 01008 int recur, prepended = 0; 01009 st_table *list; 01010 01011 if (argc == 0) { 01012 recur = TRUE; 01013 } 01014 else { 01015 VALUE r; 01016 rb_scan_args(argc, argv, "01", &r); 01017 recur = RTEST(r); 01018 } 01019 01020 if (!recur && RCLASS_ORIGIN(mod) != mod) { 01021 mod = RCLASS_ORIGIN(mod); 01022 prepended = 1; 01023 } 01024 01025 list = st_init_numtable(); 01026 for (; mod; mod = RCLASS_SUPER(mod)) { 01027 if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list); 01028 if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue; 01029 if (obj && FL_TEST(mod, FL_SINGLETON)) continue; 01030 if (!recur) break; 01031 } 01032 ary = rb_ary_new(); 01033 st_foreach(list, func, ary); 01034 st_free_table(list); 01035 01036 return ary; 01037 } 01038 01039 /* 01040 * call-seq: 01041 * mod.instance_methods(include_super=true) -> array 01042 * 01043 * Returns an array containing the names of the public and protected instance 01044 * methods in the receiver. For a module, these are the public and protected methods; 01045 * for a class, they are the instance (not singleton) methods. With no 01046 * argument, or with an argument that is <code>false</code>, the 01047 * instance methods in <i>mod</i> are returned, otherwise the methods 01048 * in <i>mod</i> and <i>mod</i>'s superclasses are returned. 01049 * 01050 * module A 01051 * def method1() end 01052 * end 01053 * class B 01054 * def method2() end 01055 * end 01056 * class C < B 01057 * def method3() end 01058 * end 01059 * 01060 * A.instance_methods #=> [:method1] 01061 * B.instance_methods(false) #=> [:method2] 01062 * C.instance_methods(false) #=> [:method3] 01063 * C.instance_methods(true).length #=> 43 01064 */ 01065 01066 VALUE 01067 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod) 01068 { 01069 return class_instance_method_list(argc, argv, mod, 0, ins_methods_i); 01070 } 01071 01072 /* 01073 * call-seq: 01074 * mod.protected_instance_methods(include_super=true) -> array 01075 * 01076 * Returns a list of the protected instance methods defined in 01077 * <i>mod</i>. If the optional parameter is not <code>false</code>, the 01078 * methods of any ancestors are included. 01079 */ 01080 01081 VALUE 01082 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod) 01083 { 01084 return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i); 01085 } 01086 01087 /* 01088 * call-seq: 01089 * mod.private_instance_methods(include_super=true) -> array 01090 * 01091 * Returns a list of the private instance methods defined in 01092 * <i>mod</i>. If the optional parameter is not <code>false</code>, the 01093 * methods of any ancestors are included. 01094 * 01095 * module Mod 01096 * def method1() end 01097 * private :method1 01098 * def method2() end 01099 * end 01100 * Mod.instance_methods #=> [:method2] 01101 * Mod.private_instance_methods #=> [:method1] 01102 */ 01103 01104 VALUE 01105 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod) 01106 { 01107 return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i); 01108 } 01109 01110 /* 01111 * call-seq: 01112 * mod.public_instance_methods(include_super=true) -> array 01113 * 01114 * Returns a list of the public instance methods defined in <i>mod</i>. 01115 * If the optional parameter is not <code>false</code>, the methods of 01116 * any ancestors are included. 01117 */ 01118 01119 VALUE 01120 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod) 01121 { 01122 return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i); 01123 } 01124 01125 /* 01126 * call-seq: 01127 * obj.methods(all=true) -> array 01128 * 01129 * Returns a list of the names of public and protected methods of 01130 * <i>obj</i>. This will include all the methods accessible in 01131 * <i>obj</i>'s ancestors. 01132 * If the <i>all</i> parameter is set to <code>false</code>, only those methods 01133 * in the receiver will be listed. 01134 * 01135 * class Klass 01136 * def klass_method() 01137 * end 01138 * end 01139 * k = Klass.new 01140 * k.methods[0..9] #=> [:klass_method, :nil?, :===, 01141 * # :==~, :!, :eql? 01142 * # :hash, :<=>, :class, :singleton_class] 01143 * k.methods.length #=> 57 01144 */ 01145 01146 VALUE 01147 rb_obj_methods(int argc, VALUE *argv, VALUE obj) 01148 { 01149 retry: 01150 if (argc == 0) { 01151 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i); 01152 } 01153 else { 01154 VALUE recur; 01155 01156 rb_scan_args(argc, argv, "1", &recur); 01157 if (RTEST(recur)) { 01158 argc = 0; 01159 goto retry; 01160 } 01161 return rb_obj_singleton_methods(argc, argv, obj); 01162 } 01163 } 01164 01165 /* 01166 * call-seq: 01167 * obj.protected_methods(all=true) -> array 01168 * 01169 * Returns the list of protected methods accessible to <i>obj</i>. If 01170 * the <i>all</i> parameter is set to <code>false</code>, only those methods 01171 * in the receiver will be listed. 01172 */ 01173 01174 VALUE 01175 rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj) 01176 { 01177 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i); 01178 } 01179 01180 /* 01181 * call-seq: 01182 * obj.private_methods(all=true) -> array 01183 * 01184 * Returns the list of private methods accessible to <i>obj</i>. If 01185 * the <i>all</i> parameter is set to <code>false</code>, only those methods 01186 * in the receiver will be listed. 01187 */ 01188 01189 VALUE 01190 rb_obj_private_methods(int argc, VALUE *argv, VALUE obj) 01191 { 01192 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i); 01193 } 01194 01195 /* 01196 * call-seq: 01197 * obj.public_methods(all=true) -> array 01198 * 01199 * Returns the list of public methods accessible to <i>obj</i>. If 01200 * the <i>all</i> parameter is set to <code>false</code>, only those methods 01201 * in the receiver will be listed. 01202 */ 01203 01204 VALUE 01205 rb_obj_public_methods(int argc, VALUE *argv, VALUE obj) 01206 { 01207 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i); 01208 } 01209 01210 /* 01211 * call-seq: 01212 * obj.singleton_methods(all=true) -> array 01213 * 01214 * Returns an array of the names of singleton methods for <i>obj</i>. 01215 * If the optional <i>all</i> parameter is true, the list will include 01216 * methods in modules included in <i>obj</i>. 01217 * Only public and protected singleton methods are returned. 01218 * 01219 * module Other 01220 * def three() end 01221 * end 01222 * 01223 * class Single 01224 * def Single.four() end 01225 * end 01226 * 01227 * a = Single.new 01228 * 01229 * def a.one() 01230 * end 01231 * 01232 * class << a 01233 * include Other 01234 * def two() 01235 * end 01236 * end 01237 * 01238 * Single.singleton_methods #=> [:four] 01239 * a.singleton_methods(false) #=> [:two, :one] 01240 * a.singleton_methods #=> [:two, :one, :three] 01241 */ 01242 01243 VALUE 01244 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj) 01245 { 01246 VALUE recur, ary, klass; 01247 st_table *list; 01248 01249 if (argc == 0) { 01250 recur = Qtrue; 01251 } 01252 else { 01253 rb_scan_args(argc, argv, "01", &recur); 01254 } 01255 klass = CLASS_OF(obj); 01256 list = st_init_numtable(); 01257 if (klass && FL_TEST(klass, FL_SINGLETON)) { 01258 if (RCLASS_M_TBL(klass)) 01259 st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list); 01260 klass = RCLASS_SUPER(klass); 01261 } 01262 if (RTEST(recur)) { 01263 while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) { 01264 if (RCLASS_M_TBL(klass)) 01265 st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list); 01266 klass = RCLASS_SUPER(klass); 01267 } 01268 } 01269 ary = rb_ary_new(); 01270 st_foreach(list, ins_methods_i, ary); 01271 st_free_table(list); 01272 01273 return ary; 01274 } 01275 01333 void 01334 rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc) 01335 { 01336 rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC); 01337 } 01338 01339 void 01340 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) 01341 { 01342 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC); 01343 } 01344 01345 void 01346 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) 01347 { 01348 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED); 01349 } 01350 01351 void 01352 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) 01353 { 01354 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE); 01355 } 01356 01357 void 01358 rb_undef_method(VALUE klass, const char *name) 01359 { 01360 rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF); 01361 } 01362 01371 #define SPECIAL_SINGLETON(x,c) do {\ 01372 if (obj == (x)) {\ 01373 return (c);\ 01374 }\ 01375 } while (0) 01376 01377 static inline VALUE 01378 special_singleton_class_of(VALUE obj) 01379 { 01380 SPECIAL_SINGLETON(Qnil, rb_cNilClass); 01381 SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); 01382 SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); 01383 return Qnil; 01384 } 01385 01386 VALUE 01387 rb_special_singleton_class(VALUE obj) 01388 { 01389 return special_singleton_class_of(obj); 01390 } 01391 01401 static VALUE 01402 singleton_class_of(VALUE obj) 01403 { 01404 VALUE klass; 01405 01406 if (FIXNUM_P(obj) || FLONUM_P(obj) || SYMBOL_P(obj)) { 01407 rb_raise(rb_eTypeError, "can't define singleton"); 01408 } 01409 if (SPECIAL_CONST_P(obj)) { 01410 klass = special_singleton_class_of(obj); 01411 if (NIL_P(klass)) 01412 rb_bug("unknown immediate %p", (void *)obj); 01413 return klass; 01414 } 01415 else { 01416 enum ruby_value_type type = BUILTIN_TYPE(obj); 01417 if (type == T_FLOAT || type == T_BIGNUM) { 01418 rb_raise(rb_eTypeError, "can't define singleton"); 01419 } 01420 } 01421 01422 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && 01423 rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) { 01424 klass = RBASIC(obj)->klass; 01425 } 01426 else { 01427 klass = rb_make_metaclass(obj, RBASIC(obj)->klass); 01428 } 01429 01430 if (OBJ_TAINTED(obj)) { 01431 OBJ_TAINT(klass); 01432 } 01433 else { 01434 FL_UNSET(klass, FL_TAINT); 01435 } 01436 if (OBJ_UNTRUSTED(obj)) { 01437 OBJ_UNTRUST(klass); 01438 } 01439 else { 01440 FL_UNSET(klass, FL_UNTRUSTED); 01441 } 01442 if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); 01443 01444 return klass; 01445 } 01446 01447 01465 VALUE 01466 rb_singleton_class(VALUE obj) 01467 { 01468 VALUE klass = singleton_class_of(obj); 01469 01470 /* ensures an exposed class belongs to its own eigenclass */ 01471 if (RB_TYPE_P(obj, T_CLASS)) (void)ENSURE_EIGENCLASS(klass); 01472 01473 return klass; 01474 } 01475 01492 void 01493 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc) 01494 { 01495 rb_define_method(singleton_class_of(obj), name, func, argc); 01496 } 01497 01498 01499 01507 void 01508 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc) 01509 { 01510 rb_define_private_method(module, name, func, argc); 01511 rb_define_singleton_method(module, name, func, argc); 01512 } 01513 01514 01521 void 01522 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc) 01523 { 01524 rb_define_module_function(rb_mKernel, name, func, argc); 01525 } 01526 01527 01534 void 01535 rb_define_alias(VALUE klass, const char *name1, const char *name2) 01536 { 01537 rb_alias(klass, rb_intern(name1), rb_intern(name2)); 01538 } 01539 01547 void 01548 rb_define_attr(VALUE klass, const char *name, int read, int write) 01549 { 01550 rb_attr(klass, rb_intern(name), read, write, FALSE); 01551 } 01552 01553 int 01554 rb_obj_basic_to_s_p(VALUE obj) 01555 { 01556 const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s"), 0); 01557 if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC && 01558 me->def->body.cfunc.func == rb_any_to_s) 01559 return 1; 01560 return 0; 01561 } 01562 01563 #include <stdarg.h> 01564 01565 int 01566 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) 01567 { 01568 int i; 01569 const char *p = fmt; 01570 VALUE *var; 01571 va_list vargs; 01572 int f_var = 0, f_hash = 0, f_block = 0; 01573 int n_lead = 0, n_opt = 0, n_trail = 0, n_mand; 01574 int argi = 0; 01575 VALUE hash = Qnil; 01576 01577 if (ISDIGIT(*p)) { 01578 n_lead = *p - '0'; 01579 p++; 01580 if (ISDIGIT(*p)) { 01581 n_opt = *p - '0'; 01582 p++; 01583 if (ISDIGIT(*p)) { 01584 n_trail = *p - '0'; 01585 p++; 01586 goto block_arg; 01587 } 01588 } 01589 } 01590 if (*p == '*') { 01591 f_var = 1; 01592 p++; 01593 if (ISDIGIT(*p)) { 01594 n_trail = *p - '0'; 01595 p++; 01596 } 01597 } 01598 block_arg: 01599 if (*p == ':') { 01600 f_hash = 1; 01601 p++; 01602 } 01603 if (*p == '&') { 01604 f_block = 1; 01605 p++; 01606 } 01607 if (*p != '\0') { 01608 rb_fatal("bad scan arg format: %s", fmt); 01609 } 01610 n_mand = n_lead + n_trail; 01611 01612 if (argc < n_mand) 01613 goto argc_error; 01614 01615 va_start(vargs, fmt); 01616 01617 /* capture an option hash - phase 1: pop */ 01618 if (f_hash && n_mand < argc) { 01619 VALUE last = argv[argc - 1]; 01620 01621 if (NIL_P(last)) { 01622 /* nil is taken as an empty option hash only if it is not 01623 ambiguous; i.e. '*' is not specified and arguments are 01624 given more than sufficient */ 01625 if (!f_var && n_mand + n_opt < argc) 01626 argc--; 01627 } 01628 else { 01629 hash = rb_check_hash_type(last); 01630 if (!NIL_P(hash)) 01631 argc--; 01632 } 01633 } 01634 /* capture leading mandatory arguments */ 01635 for (i = n_lead; i-- > 0; ) { 01636 var = va_arg(vargs, VALUE *); 01637 if (var) *var = argv[argi]; 01638 argi++; 01639 } 01640 /* capture optional arguments */ 01641 for (i = n_opt; i-- > 0; ) { 01642 var = va_arg(vargs, VALUE *); 01643 if (argi < argc - n_trail) { 01644 if (var) *var = argv[argi]; 01645 argi++; 01646 } 01647 else { 01648 if (var) *var = Qnil; 01649 } 01650 } 01651 /* capture variable length arguments */ 01652 if (f_var) { 01653 int n_var = argc - argi - n_trail; 01654 01655 var = va_arg(vargs, VALUE *); 01656 if (0 < n_var) { 01657 if (var) *var = rb_ary_new4(n_var, &argv[argi]); 01658 argi += n_var; 01659 } 01660 else { 01661 if (var) *var = rb_ary_new(); 01662 } 01663 } 01664 /* capture trailing mandatory arguments */ 01665 for (i = n_trail; i-- > 0; ) { 01666 var = va_arg(vargs, VALUE *); 01667 if (var) *var = argv[argi]; 01668 argi++; 01669 } 01670 /* capture an option hash - phase 2: assignment */ 01671 if (f_hash) { 01672 var = va_arg(vargs, VALUE *); 01673 if (var) *var = hash; 01674 } 01675 /* capture iterator block */ 01676 if (f_block) { 01677 var = va_arg(vargs, VALUE *); 01678 if (rb_block_given_p()) { 01679 *var = rb_block_proc(); 01680 } 01681 else { 01682 *var = Qnil; 01683 } 01684 } 01685 va_end(vargs); 01686 01687 if (argi < argc) { 01688 argc_error: 01689 rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt); 01690 } 01691 01692 return argc; 01693 } 01694