* io.c (io_enc_str): code conversion removed.
[ruby-svn.git] / class.c
blob6f64d07612d297510482f1e6ee2e7e7b0de8203d
1 /**********************************************************************
3 class.c -
5 $Author$
6 created at: Tue Aug 10 15:05:44 JST 1993
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
10 **********************************************************************/
12 #include "ruby/ruby.h"
13 #include "ruby/signal.h"
14 #include "ruby/node.h"
15 #include "ruby/st.h"
16 #include "vm_core.h"
17 #include <ctype.h>
19 extern st_table *rb_class_tbl;
21 static VALUE
22 class_alloc(VALUE flags, VALUE klass)
24 rb_classext_t *ext = ALLOC(rb_classext_t);
25 NEWOBJ(obj, struct RClass);
26 OBJSETUP(obj, klass, flags);
27 obj->ptr = ext;
28 RCLASS_IV_TBL(obj) = 0;
29 RCLASS_M_TBL(obj) = 0;
30 RCLASS_SUPER(obj) = 0;
31 RCLASS_IV_INDEX_TBL(obj) = 0;
32 return (VALUE)obj;
35 VALUE
36 rb_class_boot(VALUE super)
38 VALUE klass = class_alloc(T_CLASS, rb_cClass);
40 RCLASS_SUPER(klass) = super;
41 RCLASS_M_TBL(klass) = st_init_numtable();
43 OBJ_INFECT(klass, super);
44 return (VALUE)klass;
47 void
48 rb_check_inheritable(VALUE super)
50 if (TYPE(super) != T_CLASS) {
51 rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
52 rb_obj_classname(super));
54 if (RBASIC(super)->flags & FL_SINGLETON) {
55 rb_raise(rb_eTypeError, "can't make subclass of singleton class");
59 VALUE
60 rb_class_new(VALUE super)
62 Check_Type(super, T_CLASS);
63 rb_check_inheritable(super);
64 if (super == rb_cClass) {
65 rb_raise(rb_eTypeError, "can't make subclass of Class");
67 return rb_class_boot(super);
70 struct clone_method_data {
71 st_table *tbl;
72 VALUE klass;
75 static int
76 clone_method(ID mid, NODE *body, struct clone_method_data *data)
78 if (body == 0) {
79 st_insert(data->tbl, mid, 0);
81 else {
82 NODE *fbody = body->nd_body->nd_body;
84 if (nd_type(fbody) == RUBY_VM_METHOD_NODE) {
85 fbody = NEW_NODE(RUBY_VM_METHOD_NODE, 0,
86 rb_iseq_clone((VALUE)fbody->nd_body, data->klass),
87 0);
89 st_insert(data->tbl, mid,
90 (st_data_t)
91 NEW_FBODY(
92 NEW_METHOD(fbody,
93 data->klass, /* TODO */
94 body->nd_body->nd_noex),
95 0));
97 return ST_CONTINUE;
100 /* :nodoc: */
101 VALUE
102 rb_mod_init_copy(VALUE clone, VALUE orig)
104 rb_obj_init_copy(clone, orig);
105 if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
106 RBASIC(clone)->klass = rb_singleton_class_clone(orig);
108 RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
109 if (RCLASS_IV_TBL(orig)) {
110 ID id;
112 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
113 CONST_ID(id, "__classpath__");
114 st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
115 CONST_ID(id, "__classid__");
116 st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
118 if (RCLASS_M_TBL(orig)) {
119 struct clone_method_data data;
120 data.tbl = RCLASS_M_TBL(clone) = st_init_numtable();
121 data.klass = clone;
122 st_foreach(RCLASS_M_TBL(orig), clone_method,
123 (st_data_t)&data);
126 return clone;
129 /* :nodoc: */
130 VALUE
131 rb_class_init_copy(VALUE clone, VALUE orig)
133 if (RCLASS_SUPER(clone) != 0) {
134 rb_raise(rb_eTypeError, "already initialized class");
136 if (FL_TEST(orig, FL_SINGLETON)) {
137 rb_raise(rb_eTypeError, "can't copy singleton class");
139 return rb_mod_init_copy(clone, orig);
142 VALUE
143 rb_singleton_class_clone(VALUE obj)
145 VALUE klass = RBASIC(obj)->klass;
147 if (!FL_TEST(klass, FL_SINGLETON))
148 return klass;
149 else {
150 struct clone_method_data data;
151 /* copy singleton(unnamed) class */
152 VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
154 if (BUILTIN_TYPE(obj) == T_CLASS) {
155 RBASIC(clone)->klass = (VALUE)clone;
157 else {
158 RBASIC(clone)->klass = rb_singleton_class_clone(klass);
161 RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
162 if (RCLASS_IV_TBL(klass)) {
163 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
165 RCLASS_M_TBL(clone) = st_init_numtable();
166 data.tbl = RCLASS_M_TBL(clone);
167 data.klass = (VALUE)clone;
168 st_foreach(RCLASS_M_TBL(klass), clone_method,
169 (st_data_t)&data);
170 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
171 FL_SET(clone, FL_SINGLETON);
172 return (VALUE)clone;
176 void
177 rb_singleton_class_attached(VALUE klass, VALUE obj)
179 if (FL_TEST(klass, FL_SINGLETON)) {
180 ID attached;
181 if (!RCLASS_IV_TBL(klass)) {
182 RCLASS_IV_TBL(klass) = st_init_numtable();
184 CONST_ID(attached, "__attached__");
185 st_insert(RCLASS_IV_TBL(klass), attached, obj);
189 VALUE
190 rb_make_metaclass(VALUE obj, VALUE super)
192 if (BUILTIN_TYPE(obj) == T_CLASS && FL_TEST(obj, FL_SINGLETON)) {
193 return RBASIC(obj)->klass = rb_cClass;
195 else {
196 VALUE metasuper;
197 VALUE klass = rb_class_boot(super);
199 FL_SET(klass, FL_SINGLETON);
200 RBASIC(obj)->klass = klass;
201 rb_singleton_class_attached(klass, obj);
203 metasuper = RBASIC(rb_class_real(super))->klass;
204 /* metaclass of a superclass may be NULL at boot time */
205 if (metasuper) {
206 RBASIC(klass)->klass = metasuper;
208 return klass;
212 VALUE
213 rb_define_class_id(ID id, VALUE super)
215 VALUE klass;
217 if (!super) super = rb_cObject;
218 klass = rb_class_new(super);
219 rb_make_metaclass(klass, RBASIC(super)->klass);
221 return klass;
224 VALUE
225 rb_class_inherited(VALUE super, VALUE klass)
227 ID inherited;
228 if (!super) super = rb_cObject;
229 CONST_ID(inherited, "inherited");
230 return rb_funcall(super, inherited, 1, klass);
233 VALUE
234 rb_define_class(const char *name, VALUE super)
236 VALUE klass;
237 ID id;
239 id = rb_intern(name);
240 if (rb_const_defined(rb_cObject, id)) {
241 klass = rb_const_get(rb_cObject, id);
242 if (TYPE(klass) != T_CLASS) {
243 rb_raise(rb_eTypeError, "%s is not a class", name);
245 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
246 rb_name_error(id, "%s is already defined", name);
248 return klass;
250 if (!super) {
251 rb_warn("no super class for `%s', Object assumed", name);
253 klass = rb_define_class_id(id, super);
254 st_add_direct(rb_class_tbl, id, klass);
255 rb_name_class(klass, id);
256 rb_const_set(rb_cObject, id, klass);
257 rb_class_inherited(super, klass);
259 return klass;
262 VALUE
263 rb_define_class_under(VALUE outer, const char *name, VALUE super)
265 VALUE klass;
266 ID id;
268 id = rb_intern(name);
269 if (rb_const_defined_at(outer, id)) {
270 klass = rb_const_get_at(outer, id);
271 if (TYPE(klass) != T_CLASS) {
272 rb_raise(rb_eTypeError, "%s is not a class", name);
274 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
275 rb_name_error(id, "%s is already defined", name);
277 return klass;
279 if (!super) {
280 rb_warn("no super class for `%s::%s', Object assumed",
281 rb_class2name(outer), name);
283 klass = rb_define_class_id(id, super);
284 rb_set_class_path(klass, outer, name);
285 rb_const_set(outer, id, klass);
286 rb_class_inherited(super, klass);
288 return klass;
291 VALUE
292 rb_module_new(void)
294 VALUE mdl = class_alloc(T_MODULE, rb_cModule);
296 RCLASS_M_TBL(mdl) = st_init_numtable();
298 return (VALUE)mdl;
301 VALUE
302 rb_define_module_id(ID id)
304 VALUE mdl;
306 mdl = rb_module_new();
307 rb_name_class(mdl, id);
309 return mdl;
312 VALUE
313 rb_define_module(const char *name)
315 VALUE module;
316 ID id;
318 id = rb_intern(name);
319 if (rb_const_defined(rb_cObject, id)) {
320 module = rb_const_get(rb_cObject, id);
321 if (TYPE(module) == T_MODULE)
322 return module;
323 rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
325 module = rb_define_module_id(id);
326 st_add_direct(rb_class_tbl, id, module);
327 rb_const_set(rb_cObject, id, module);
329 return module;
332 VALUE
333 rb_define_module_under(VALUE outer, const char *name)
335 VALUE module;
336 ID id;
338 id = rb_intern(name);
339 if (rb_const_defined_at(outer, id)) {
340 module = rb_const_get_at(outer, id);
341 if (TYPE(module) == T_MODULE)
342 return module;
343 rb_raise(rb_eTypeError, "%s::%s is not a module",
344 rb_class2name(outer), rb_obj_classname(module));
346 module = rb_define_module_id(id);
347 rb_const_set(outer, id, module);
348 rb_set_class_path(module, outer, name);
350 return module;
353 static VALUE
354 include_class_new(VALUE module, VALUE super)
356 VALUE klass = class_alloc(T_ICLASS, rb_cClass);
358 if (BUILTIN_TYPE(module) == T_ICLASS) {
359 module = RBASIC(module)->klass;
361 if (!RCLASS_IV_TBL(module)) {
362 RCLASS_IV_TBL(module) = st_init_numtable();
364 RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
365 RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
366 RCLASS_SUPER(klass) = super;
367 if (TYPE(module) == T_ICLASS) {
368 RBASIC(klass)->klass = RBASIC(module)->klass;
370 else {
371 RBASIC(klass)->klass = module;
373 OBJ_INFECT(klass, module);
374 OBJ_INFECT(klass, super);
376 return (VALUE)klass;
379 void
380 rb_include_module(VALUE klass, VALUE module)
382 VALUE p, c;
383 int changed = 0;
385 rb_frozen_class_p(klass);
386 if (!OBJ_UNTRUSTED(klass)) {
387 rb_secure(4);
390 if (TYPE(module) != T_MODULE) {
391 Check_Type(module, T_MODULE);
394 OBJ_INFECT(klass, module);
395 c = klass;
396 while (module) {
397 int superclass_seen = Qfalse;
399 if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
400 rb_raise(rb_eArgError, "cyclic include detected");
401 /* ignore if the module included already in superclasses */
402 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
403 switch (BUILTIN_TYPE(p)) {
404 case T_ICLASS:
405 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
406 if (!superclass_seen) {
407 c = p; /* move insertion point */
409 goto skip;
411 break;
412 case T_CLASS:
413 superclass_seen = Qtrue;
414 break;
417 c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
418 changed = 1;
419 skip:
420 module = RCLASS_SUPER(module);
422 if (changed) rb_clear_cache();
426 * call-seq:
427 * mod.included_modules -> array
429 * Returns the list of modules included in <i>mod</i>.
431 * module Mixin
432 * end
434 * module Outer
435 * include Mixin
436 * end
438 * Mixin.included_modules #=> []
439 * Outer.included_modules #=> [Mixin]
442 VALUE
443 rb_mod_included_modules(VALUE mod)
445 VALUE ary = rb_ary_new();
446 VALUE p;
448 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
449 if (BUILTIN_TYPE(p) == T_ICLASS) {
450 rb_ary_push(ary, RBASIC(p)->klass);
453 return ary;
457 * call-seq:
458 * mod.include?(module) => true or false
460 * Returns <code>true</code> if <i>module</i> is included in
461 * <i>mod</i> or one of <i>mod</i>'s ancestors.
463 * module A
464 * end
465 * class B
466 * include A
467 * end
468 * class C < B
469 * end
470 * B.include?(A) #=> true
471 * C.include?(A) #=> true
472 * A.include?(A) #=> false
475 VALUE
476 rb_mod_include_p(VALUE mod, VALUE mod2)
478 VALUE p;
480 Check_Type(mod2, T_MODULE);
481 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
482 if (BUILTIN_TYPE(p) == T_ICLASS) {
483 if (RBASIC(p)->klass == mod2) return Qtrue;
486 return Qfalse;
490 * call-seq:
491 * mod.ancestors -> array
493 * Returns a list of modules included in <i>mod</i> (including
494 * <i>mod</i> itself).
496 * module Mod
497 * include Math
498 * include Comparable
499 * end
501 * Mod.ancestors #=> [Mod, Comparable, Math]
502 * Math.ancestors #=> [Math]
505 VALUE
506 rb_mod_ancestors(VALUE mod)
508 VALUE p, ary = rb_ary_new();
510 for (p = mod; p; p = RCLASS_SUPER(p)) {
511 if (FL_TEST(p, FL_SINGLETON))
512 continue;
513 if (BUILTIN_TYPE(p) == T_ICLASS) {
514 rb_ary_push(ary, RBASIC(p)->klass);
516 else {
517 rb_ary_push(ary, p);
520 return ary;
523 #define VISI(x) ((x)&NOEX_MASK)
524 #define VISI_CHECK(x,f) (VISI(x) == (f))
526 static int
527 ins_methods_push(ID name, long type, VALUE ary, long visi)
529 if (type == -1) return ST_CONTINUE;
531 switch (visi) {
532 case NOEX_PRIVATE:
533 case NOEX_PROTECTED:
534 case NOEX_PUBLIC:
535 visi = (type == visi);
536 break;
537 default:
538 visi = (type != NOEX_PRIVATE);
539 break;
541 if (visi) {
542 rb_ary_push(ary, ID2SYM(name));
544 return ST_CONTINUE;
547 static int
548 ins_methods_i(ID name, long type, VALUE ary)
550 return ins_methods_push(name, type, ary, -1); /* everything but private */
553 static int
554 ins_methods_prot_i(ID name, long type, VALUE ary)
556 return ins_methods_push(name, type, ary, NOEX_PROTECTED);
559 static int
560 ins_methods_priv_i(ID name, long type, VALUE ary)
562 return ins_methods_push(name, type, ary, NOEX_PRIVATE);
565 static int
566 ins_methods_pub_i(ID name, long type, VALUE ary)
568 return ins_methods_push(name, type, ary, NOEX_PUBLIC);
571 static int
572 method_entry(ID key, NODE *body, st_table *list)
574 long type;
576 if (key == ID_ALLOCATOR) {
577 return ST_CONTINUE;
580 if (!st_lookup(list, key, 0)) {
581 if (body ==0 || !body->nd_body->nd_body) {
582 type = -1; /* none */
584 else {
585 type = VISI(body->nd_body->nd_noex);
587 st_add_direct(list, key, type);
589 return ST_CONTINUE;
592 static VALUE
593 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (ID, long, VALUE))
595 VALUE ary;
596 int recur;
597 st_table *list;
599 if (argc == 0) {
600 recur = Qtrue;
602 else {
603 VALUE r;
604 rb_scan_args(argc, argv, "01", &r);
605 recur = RTEST(r);
608 list = st_init_numtable();
609 for (; mod; mod = RCLASS_SUPER(mod)) {
610 st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
611 if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
612 if (FL_TEST(mod, FL_SINGLETON)) continue;
613 if (!recur) break;
615 ary = rb_ary_new();
616 st_foreach(list, func, ary);
617 st_free_table(list);
619 return ary;
623 * call-seq:
624 * mod.instance_methods(include_super=true) => array
626 * Returns an array containing the names of public instance methods in
627 * the receiver. For a module, these are the public methods; for a
628 * class, they are the instance (not singleton) methods. With no
629 * argument, or with an argument that is <code>false</code>, the
630 * instance methods in <i>mod</i> are returned, otherwise the methods
631 * in <i>mod</i> and <i>mod</i>'s superclasses are returned.
633 * module A
634 * def method1() end
635 * end
636 * class B
637 * def method2() end
638 * end
639 * class C < B
640 * def method3() end
641 * end
643 * A.instance_methods #=> [:method1]
644 * B.instance_methods(false) #=> [:method2]
645 * C.instance_methods(false) #=> [:method3]
646 * C.instance_methods(true).length #=> 43
649 VALUE
650 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod)
652 return class_instance_method_list(argc, argv, mod, ins_methods_i);
656 * call-seq:
657 * mod.protected_instance_methods(include_super=true) => array
659 * Returns a list of the protected instance methods defined in
660 * <i>mod</i>. If the optional parameter is not <code>false</code>, the
661 * methods of any ancestors are included.
664 VALUE
665 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod)
667 return class_instance_method_list(argc, argv, mod, ins_methods_prot_i);
671 * call-seq:
672 * mod.private_instance_methods(include_super=true) => array
674 * Returns a list of the private instance methods defined in
675 * <i>mod</i>. If the optional parameter is not <code>false</code>, the
676 * methods of any ancestors are included.
678 * module Mod
679 * def method1() end
680 * private :method1
681 * def method2() end
682 * end
683 * Mod.instance_methods #=> [:method2]
684 * Mod.private_instance_methods #=> [:method1]
687 VALUE
688 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod)
690 return class_instance_method_list(argc, argv, mod, ins_methods_priv_i);
694 * call-seq:
695 * mod.public_instance_methods(include_super=true) => array
697 * Returns a list of the public instance methods defined in <i>mod</i>.
698 * If the optional parameter is not <code>false</code>, the methods of
699 * any ancestors are included.
702 VALUE
703 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
705 return class_instance_method_list(argc, argv, mod, ins_methods_pub_i);
709 * call-seq:
710 * obj.singleton_methods(all=true) => array
712 * Returns an array of the names of singleton methods for <i>obj</i>.
713 * If the optional <i>all</i> parameter is true, the list will include
714 * methods in modules included in <i>obj</i>.
716 * module Other
717 * def three() end
718 * end
720 * class Single
721 * def Single.four() end
722 * end
724 * a = Single.new
726 * def a.one()
727 * end
729 * class << a
730 * include Other
731 * def two()
732 * end
733 * end
735 * Single.singleton_methods #=> [:four]
736 * a.singleton_methods(false) #=> [:two, :one]
737 * a.singleton_methods #=> [:two, :one, :three]
740 VALUE
741 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
743 VALUE recur, ary, klass;
744 st_table *list;
746 if (argc == 0) {
747 recur = Qtrue;
749 else {
750 rb_scan_args(argc, argv, "01", &recur);
752 klass = CLASS_OF(obj);
753 list = st_init_numtable();
754 if (klass && FL_TEST(klass, FL_SINGLETON)) {
755 st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
756 klass = RCLASS_SUPER(klass);
758 if (RTEST(recur)) {
759 while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
760 st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
761 klass = RCLASS_SUPER(klass);
764 ary = rb_ary_new();
765 st_foreach(list, ins_methods_i, ary);
766 st_free_table(list);
768 return ary;
771 void
772 rb_define_method_id(VALUE klass, ID name, VALUE (*func)(ANYARGS), int argc)
774 rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);
777 void
778 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
780 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC);
783 void
784 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
786 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PROTECTED);
789 void
790 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
792 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);
795 void
796 rb_undef_method(VALUE klass, const char *name)
798 rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
801 #define SPECIAL_SINGLETON(x,c) do {\
802 if (obj == (x)) {\
803 return c;\
805 } while (0)
807 VALUE
808 rb_singleton_class(VALUE obj)
810 VALUE klass;
812 if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
813 rb_raise(rb_eTypeError, "can't define singleton");
815 if (rb_special_const_p(obj)) {
816 SPECIAL_SINGLETON(Qnil, rb_cNilClass);
817 SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
818 SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
819 rb_bug("unknown immediate %ld", obj);
822 DEFER_INTS;
823 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
824 rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) {
825 klass = RBASIC(obj)->klass;
827 else {
828 klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
830 if (OBJ_TAINTED(obj)) {
831 OBJ_TAINT(klass);
833 else {
834 FL_UNSET(klass, FL_TAINT);
836 if (OBJ_UNTRUSTED(obj)) {
837 OBJ_UNTRUST(klass);
839 else {
840 FL_UNSET(klass, FL_UNTRUSTED);
842 if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
843 ALLOW_INTS;
845 return klass;
848 void
849 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
851 rb_define_method(rb_singleton_class(obj), name, func, argc);
854 void
855 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
857 rb_define_private_method(module, name, func, argc);
858 rb_define_singleton_method(module, name, func, argc);
861 void
862 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
864 rb_define_module_function(rb_mKernel, name, func, argc);
867 void
868 rb_define_alias(VALUE klass, const char *name1, const char *name2)
870 rb_alias(klass, rb_intern(name1), rb_intern(name2));
873 void
874 rb_define_attr(VALUE klass, const char *name, int read, int write)
876 rb_attr(klass, rb_intern(name), read, write, Qfalse);
879 #include <stdarg.h>
882 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
884 int n, i = 0;
885 const char *p = fmt;
886 VALUE *var;
887 va_list vargs;
889 va_start(vargs, fmt);
891 if (*p == '*') goto rest_arg;
893 if (ISDIGIT(*p)) {
894 n = *p - '0';
895 if (n > argc)
896 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, n);
897 for (i=0; i<n; i++) {
898 var = va_arg(vargs, VALUE*);
899 if (var) *var = argv[i];
901 p++;
903 else {
904 goto error;
907 if (ISDIGIT(*p)) {
908 n = i + *p - '0';
909 for (; i<n; i++) {
910 var = va_arg(vargs, VALUE*);
911 if (argc > i) {
912 if (var) *var = argv[i];
914 else {
915 if (var) *var = Qnil;
918 p++;
921 if(*p == '*') {
922 rest_arg:
923 var = va_arg(vargs, VALUE*);
924 if (argc > i) {
925 if (var) *var = rb_ary_new4(argc-i, argv+i);
926 i = argc;
928 else {
929 if (var) *var = rb_ary_new();
931 p++;
934 if (*p == '&') {
935 var = va_arg(vargs, VALUE*);
936 if (rb_block_given_p()) {
937 *var = rb_block_proc();
939 else {
940 *var = Qnil;
942 p++;
944 va_end(vargs);
946 if (*p != '\0') {
947 goto error;
950 if (argc > i) {
951 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, i);
954 return argc;
956 error:
957 rb_fatal("bad scan arg format: %s", fmt);
958 return 0;