diff options
Diffstat (limited to 'object.c')
-rw-r--r-- | object.c | 871 |
1 files changed, 520 insertions, 351 deletions
@@ -6,7 +6,7 @@ $Date$ created at: Thu Jul 15 12:01:24 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -14,22 +14,18 @@ #include "st.h" #include <stdio.h> -VALUE mKernel; -VALUE cObject; -VALUE cModule; -VALUE cClass; -extern VALUE cFixnum; -VALUE cData; +VALUE rb_mKernel; +VALUE rb_cObject; +VALUE rb_cModule; +VALUE rb_cClass; +VALUE rb_cData; -static VALUE cNilClass; -static VALUE cTrueClass; -static VALUE cFalseClass; +VALUE rb_cNilClass; +VALUE rb_cTrueClass; +VALUE rb_cFalseClass; -struct st_table *new_idhash(); - -VALUE f_sprintf(); - -VALUE obj_alloc(); +VALUE rb_f_sprintf(); +VALUE rb_obj_alloc(); static ID eq, eql; static ID inspect; @@ -40,10 +36,11 @@ rb_equal(obj1, obj2) { VALUE result; + if (obj1 == obj2) return Qtrue; result = rb_funcall(obj1, eq, 1, obj2); - if (result == FALSE || NIL_P(result)) - return FALSE; - return TRUE; + if (result == Qfalse || NIL_P(result)) + return Qfalse; + return Qtrue; } int @@ -53,82 +50,98 @@ rb_eql(obj1, obj2) return rb_funcall(obj1, eql, 1, obj2); } -VALUE -obj_equal(obj1, obj2) +static VALUE +rb_obj_equal(obj1, obj2) VALUE obj1, obj2; { - if (obj1 == obj2) return TRUE; - return FALSE; + if (obj1 == obj2) return Qtrue; + return Qfalse; } static VALUE -any_to_a(obj) +rb_any_to_a(obj) VALUE obj; { - return ary_new3(1, obj); + return rb_ary_new3(1, obj); } static VALUE -obj_id(obj) +rb_obj_hash(obj) VALUE obj; { - return INT2NUM((int)obj); + return (long)obj|FIXNUM_FLAG; +} + +VALUE +rb_obj_id(obj) + VALUE obj; +{ + if (rb_special_const_p(obj)) { + return INT2NUM((long)obj); + } + return (long)obj|FIXNUM_FLAG; } static VALUE -obj_type(obj) +rb_obj_type(obj) VALUE obj; { VALUE cl = CLASS_OF(obj); - if (FL_TEST(cl, FL_SINGLETON)) { + while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) { cl = RCLASS(cl)->super; } return cl; } -static VALUE -obj_clone(obj) +VALUE +rb_obj_clone(obj) VALUE obj; { VALUE clone; if (TYPE(obj) != T_OBJECT) { - TypeError("can't clone %s", rb_class2name(CLASS_OF(obj))); + rb_raise(rb_eTypeError, "can't clone %s", rb_class2name(CLASS_OF(obj))); } - clone = obj_alloc(RBASIC(obj)->class); + clone = rb_obj_alloc(RBASIC(obj)->klass); CLONESETUP(clone,obj); if (ROBJECT(obj)->iv_tbl) { ROBJECT(clone)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl); - RBASIC(clone)->class = singleton_class_clone(RBASIC(obj)->class); - RBASIC(clone)->flags = RBASIC(obj)->flags; + RBASIC(clone)->klass = rb_singleton_class_clone(RBASIC(obj)->klass); + RBASIC(clone)->flags = RBASIC(obj)->flags; } return clone; } static VALUE -obj_dup(obj) +rb_obj_dup(obj) VALUE obj; { return rb_funcall(obj, rb_intern("clone"), 0, 0); } VALUE -any_to_s(obj) +rb_any_to_s(obj) VALUE obj; { - char buf[256]; + char *s; + char *cname = rb_class2name(CLASS_OF(obj)); + VALUE str; + + s = ALLOCA_N(char, strlen(cname)+6+16+1); /* 6:tags 16:addr 1:eos */ + sprintf(s, "#<%s:0x%x>", cname, obj); + str = rb_str_new2(s); + if (OBJ_TAINTED(obj)) OBJ_TAINT(str); - sprintf(buf, "#<%s:0x%x>", rb_class2name(CLASS_OF(obj)), obj); - return str_new2(buf); + return str; } VALUE rb_inspect(obj) VALUE obj; { - return obj_as_string(rb_funcall(obj, inspect, 0, 0)); + return rb_obj_as_string(rb_funcall(obj, inspect, 0, 0)); } static int @@ -142,29 +155,35 @@ inspect_i(id, value, str) /* need not to show internal data */ if (CLASS_OF(value) == 0) return ST_CONTINUE; + if (!rb_is_instance_id(id)) return ST_CONTINUE; if (RSTRING(str)->ptr[0] == '-') { RSTRING(str)->ptr[0] = '#'; - str_cat(str, ": ", 2); + rb_str_cat(str, ": ", 2); } else { - str_cat(str, ", ", 2); + rb_str_cat(str, ", ", 2); } ivname = rb_id2name(id); - str_cat(str, ivname, strlen(ivname)); - str_cat(str, "=", 1); - if (TYPE(value) == T_OBJECT) { - str2 = any_to_s(value); - } - else { - str2 = rb_inspect(value); - } - str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); + rb_str_cat(str, ivname, strlen(ivname)); + rb_str_cat(str, "=", 1); + str2 = rb_inspect(value); + rb_str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); return ST_CONTINUE; } static VALUE -obj_inspect(obj) +inspect_obj(obj, str) + VALUE obj, str; +{ + st_foreach(ROBJECT(obj)->iv_tbl, inspect_i, str); + rb_str_cat(str, ">", 1); + + return str; +} + +static VALUE +rb_obj_inspect(obj) VALUE obj; { if (TYPE(obj) == T_OBJECT @@ -173,19 +192,21 @@ obj_inspect(obj) VALUE str; char *b; - str = str_new2("-<"); b = rb_class2name(CLASS_OF(obj)); - str_cat(str, b, strlen(b)); - st_foreach(ROBJECT(obj)->iv_tbl, inspect_i, str); - str_cat(str, ">", 1); - - return str; + if (rb_inspecting_p(obj)) { + char *buf = ALLOCA_N(char, strlen(b)+8); + sprintf(buf, "#<%s:...>", b); + return rb_str_new2(buf); + } + str = rb_str_new2("-<"); + rb_str_cat(str, b, strlen(b)); + return rb_protect_inspect(inspect_obj, obj, str); } return rb_funcall(obj, rb_intern("to_s"), 0, 0); } VALUE -obj_is_instance_of(obj, c) +rb_obj_is_instance_of(obj, c) VALUE obj, c; { VALUE cl; @@ -196,31 +217,31 @@ obj_is_instance_of(obj, c) break; case T_NIL: - if (NIL_P(obj)) return TRUE; - return FALSE; + if (NIL_P(obj)) return Qtrue; + return Qfalse; case T_FALSE: - if (obj) return FALSE; - return TRUE; + if (obj) return Qfalse; + return Qtrue; case T_TRUE: - if (obj) return TRUE; - return FALSE; + if (obj) return Qtrue; + return Qfalse; default: - TypeError("class or module required"); + rb_raise(rb_eTypeError, "class or module required"); } cl = CLASS_OF(obj); - while (FL_TEST(cl, FL_SINGLETON)) { + while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) { cl = RCLASS(cl)->super; } - if (c == cl) return TRUE; - return FALSE; + if (c == cl) return Qtrue; + return Qfalse; } VALUE -obj_is_kind_of(obj, c) +rb_obj_is_kind_of(obj, c) VALUE obj, c; { VALUE cl = CLASS_OF(obj); @@ -230,70 +251,93 @@ obj_is_kind_of(obj, c) case T_CLASS: break; - case T_NIL: - if (NIL_P(obj)) return TRUE; - return FALSE; - - case T_FALSE: - if (obj) return FALSE; - return TRUE; - - case T_TRUE: - if (obj) return TRUE; - return FALSE; - default: - TypeError("class or module required"); + rb_raise(rb_eTypeError, "class or module required"); } while (cl) { if (cl == c || RCLASS(cl)->m_tbl == RCLASS(c)->m_tbl) - return TRUE; + return Qtrue; cl = RCLASS(cl)->super; } - return FALSE; + return Qfalse; } static VALUE -obj_dummy(obj) +rb_obj_dummy(obj) VALUE obj; { return Qnil; } +VALUE +rb_obj_tainted(obj) + VALUE obj; +{ + if (OBJ_TAINTED(obj)) + return Qtrue; + return Qfalse; +} + +VALUE +rb_obj_taint(obj) + VALUE obj; +{ + OBJ_TAINT(obj); + return obj; +} + +VALUE +rb_obj_untaint(obj) + VALUE obj; +{ + rb_secure(3); + FL_UNSET(obj, FL_TAINT); + return obj; +} + +static VALUE +nil_to_i(obj) + VALUE obj; +{ + return INT2FIX(0); +} + static VALUE nil_to_s(obj) VALUE obj; { - return str_new2(""); + return rb_str_new2(""); } static VALUE nil_to_a(obj) VALUE obj; { - return ary_new2(0); + return rb_ary_new2(0); } static VALUE nil_inspect(obj) VALUE obj; { - return str_new2("nil"); + return rb_str_new2("nil"); } static VALUE nil_type(obj) VALUE obj; { - return cNilClass; + return rb_cNilClass; } +#ifdef NIL_PLUS static VALUE nil_plus(x, y) VALUE x, y; { switch (TYPE(y)) { + case T_NIL: case T_FIXNUM: case T_FLOAT: case T_BIGNUM: @@ -301,74 +345,132 @@ nil_plus(x, y) case T_ARRAY: return y; default: - TypeError("tried to add %s(%s) to nil", - RSTRING(obj_as_string(y))->ptr, rb_class2name(CLASS_OF(y))); + rb_raise(rb_eTypeError, "tried to add %s(%s) to nil", + STR2CSTR(rb_inspect(y)), + rb_class2name(CLASS_OF(y))); } /* not reached */ } +#endif static VALUE main_to_s(obj) VALUE obj; { - return str_new2("main"); + return rb_str_new2("main"); } static VALUE true_to_s(obj) VALUE obj; { - return str_new2("true"); + return rb_str_new2("true"); +} + +static VALUE +true_to_i(obj) + VALUE obj; +{ + return INT2FIX(1); } static VALUE true_type(obj) VALUE obj; { - return cTrueClass; + return rb_cTrueClass; +} + +static VALUE +true_and(obj, obj2) + VALUE obj, obj2; +{ + return RTEST(obj2)?Qtrue:Qfalse; +} + +static VALUE +true_or(obj, obj2) + VALUE obj, obj2; +{ + return Qtrue; +} + +static VALUE +true_xor(obj, obj2) + VALUE obj, obj2; +{ + return RTEST(obj2)?Qfalse:Qtrue; } static VALUE false_to_s(obj) VALUE obj; { - return str_new2("false"); + return rb_str_new2("false"); +} + +static VALUE +false_to_i(obj) + VALUE obj; +{ + return INT2FIX(0); } static VALUE false_type(obj) VALUE obj; { - return cFalseClass; + return rb_cFalseClass; +} + +static VALUE +false_and(obj, obj2) + VALUE obj, obj2; +{ + return Qfalse; +} + +static VALUE +false_or(obj, obj2) + VALUE obj, obj2; +{ + return RTEST(obj2)?Qtrue:Qfalse; +} + +static VALUE +false_xor(obj, obj2) + VALUE obj, obj2; +{ + return RTEST(obj2)?Qtrue:Qfalse; } static VALUE rb_true(obj) VALUE obj; { - return TRUE; + return Qtrue; } static VALUE rb_false(obj) VALUE obj; { - return FALSE; + return Qfalse; } VALUE -obj_alloc(class) - VALUE class; +rb_obj_alloc(klass) + VALUE klass; { NEWOBJ(obj, struct RObject); - OBJSETUP(obj, class, T_OBJECT); + OBJSETUP(obj, klass, T_OBJECT); obj->iv_tbl = 0; return (VALUE)obj; } static VALUE -mod_clone(module) +rb_mod_clone(module) VALUE module; { NEWOBJ(clone, struct RClass); @@ -377,27 +479,28 @@ mod_clone(module) clone->super = RCLASS(module)->super; clone->iv_tbl = 0; clone->m_tbl = 0; /* avoid GC crashing */ + clone->iv_tbl = st_copy(RCLASS(module)->iv_tbl); clone->m_tbl = st_copy(RCLASS(module)->m_tbl); return (VALUE)clone; } static VALUE -mod_to_s(class) - VALUE class; +rb_mod_to_s(klass) + VALUE klass; { - return rb_class_path(class); + return rb_str_dup(rb_class_path(klass)); } static VALUE -mod_eqq(mod, arg) +rb_mod_eqq(mod, arg) VALUE mod, arg; { - return obj_is_kind_of(arg, mod); + return rb_obj_is_kind_of(arg, mod); } static VALUE -mod_le(mod, arg) +rb_mod_le(mod, arg) VALUE mod, arg; { switch (TYPE(arg)) { @@ -405,28 +508,28 @@ mod_le(mod, arg) case T_CLASS: break; default: - TypeError("compared with non class/module"); + rb_raise(rb_eTypeError, "compared with non class/module"); } while (mod) { if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl) - return TRUE; + return Qtrue; mod = RCLASS(mod)->super; } - return FALSE; + return Qfalse; } static VALUE -mod_lt(mod, arg) +rb_mod_lt(mod, arg) VALUE mod, arg; { - if (mod == arg) return FALSE; - return mod_le(mod, arg); + if (mod == arg) return Qfalse; + return rb_mod_le(mod, arg); } static VALUE -mod_ge(mod, arg) +rb_mod_ge(mod, arg) VALUE mod, arg; { switch (TYPE(arg)) { @@ -434,22 +537,22 @@ mod_ge(mod, arg) case T_CLASS: break; default: - TypeError("compared with non class/module"); + rb_raise(rb_eTypeError, "compared with non class/module"); } - return mod_lt(arg, mod); + return rb_mod_lt(arg, mod); } static VALUE -mod_gt(mod, arg) +rb_mod_gt(mod, arg) VALUE mod, arg; { - if (mod == arg) return FALSE; - return mod_ge(mod, arg); + if (mod == arg) return Qfalse; + return rb_mod_ge(mod, arg); } static VALUE -mod_cmp(mod, arg) +rb_mod_cmp(mod, arg) VALUE mod, arg; { if (mod == arg) return INT2FIX(0); @@ -459,52 +562,63 @@ mod_cmp(mod, arg) case T_CLASS: break; default: - TypeError("<=> requires Class or Module (%s given)", - rb_class2name(CLASS_OF(arg))); + rb_raise(rb_eTypeError, "<=> requires Class or Module (%s given)", + rb_class2name(CLASS_OF(arg))); break; } - if (mod_le(mod, arg)) { + if (rb_mod_le(mod, arg)) { return INT2FIX(-1); } return INT2FIX(1); } -VALUE module_new(); -VALUE class_new_instance(); +static VALUE +rb_module_s_new(klass) +{ + VALUE mod = rb_module_new(); + + RBASIC(mod)->klass = klass; + rb_obj_call_init(mod); + return mod; +} + +VALUE rb_class_new_instance(); static VALUE -class_s_new(argc, argv) +rb_class_s_new(argc, argv) int argc; VALUE *argv; { VALUE super, klass; - rb_scan_args(argc, argv, "01", &super); - if (NIL_P(super)) super = cObject; + if (rb_scan_args(argc, argv, "01", &super) == 0) { + super = rb_cObject; + } Check_Type(super, T_CLASS); if (FL_TEST(super, FL_SINGLETON)) { - TypeError("can't make subclass of virtual class"); + rb_raise(rb_eTypeError, "can't make subclass of virtual class"); } - klass = class_new(super); + klass = rb_class_new(super); /* make metaclass */ - RBASIC(klass)->class = singleton_class_new(RBASIC(super)->class); - singleton_class_attached(RBASIC(klass)->class, klass); + RBASIC(klass)->klass = rb_singleton_class_new(RBASIC(super)->klass); + rb_singleton_class_attached(RBASIC(klass)->klass, klass); + rb_obj_call_init(klass); return klass; } -VALUE mod_name(); -VALUE mod_included_modules(); -VALUE mod_ancestors(); -VALUE class_instance_methods(); -VALUE class_private_instance_methods(); +static VALUE +rb_class_s_inherited() +{ + rb_raise(rb_eTypeError, "can't make subclass of Class"); +} static VALUE -class_superclass(cl) - VALUE cl; +rb_class_superclass(klass) + VALUE klass; { - VALUE super = RCLASS(cl)->super; + VALUE super = RCLASS(klass)->super; while (TYPE(super) == T_ICLASS) { super = RCLASS(super)->super; @@ -519,79 +633,82 @@ ID rb_to_id(name) VALUE name; { + ID id; + if (TYPE(name) == T_STRING) { return rb_intern(RSTRING(name)->ptr); } - Check_Type(name, T_FIXNUM); - return FIX2UINT(name); + id = NUM2UINT(name); + if (!rb_id2name(id)) { + rb_raise(rb_eArgError, "%d is not a symbol", id); + } + return id; } static VALUE -mod_attr(argc, argv, class) +rb_mod_attr(argc, argv, klass) int argc; VALUE *argv; - VALUE class; + VALUE klass; { VALUE name, pub; rb_scan_args(argc, argv, "11", &name, &pub); - rb_define_attr(class, rb_to_id(name), 1, RTEST(pub)); + rb_attr(klass, rb_to_id(name), 1, RTEST(pub), Qtrue); return Qnil; } static VALUE -mod_attr_reader(argc, argv, class) +rb_mod_attr_reader(argc, argv, klass) int argc; VALUE *argv; - VALUE class; + VALUE klass; { int i; for (i=0; i<argc; i++) { - rb_define_attr(class, rb_to_id(argv[i]), 1, 0); + rb_attr(klass, rb_to_id(argv[i]), 1, 0, Qtrue); } return Qnil; } static VALUE -mod_attr_writer(argc, argv, class) +rb_mod_attr_writer(argc, argv, klass) int argc; VALUE *argv; - VALUE class; + VALUE klass; { int i; for (i=0; i<argc; i++) { - rb_define_attr(class, rb_to_id(argv[i]), 0, 1); + rb_attr(klass, rb_to_id(argv[i]), 0, 1, Qtrue); } return Qnil; } static VALUE -mod_attr_accessor(argc, argv, class) +rb_mod_attr_accessor(argc, argv, klass) int argc; VALUE *argv; - VALUE class; + VALUE klass; { int i; for (i=0; i<argc; i++) { - rb_define_attr(class, rb_to_id(argv[i]), 1, 1); + rb_attr(klass, rb_to_id(argv[i]), 1, 1, Qtrue); } return Qnil; } -VALUE mod_constants(); - static VALUE -mod_const_get(mod, name) +rb_mod_const_get(mod, name) VALUE mod, name; { return rb_const_get_at(mod, rb_to_id(name)); } static VALUE -mod_const_set(mod, name, value) +rb_mod_const_set(mod, name, value) VALUE mod, name, value; { rb_const_set(mod, rb_to_id(name), value); @@ -599,159 +716,201 @@ mod_const_set(mod, name, value) } static VALUE -mod_const_defined(mod, name) +rb_mod_const_defined(mod, name) VALUE mod, name; { return rb_const_defined_at(mod, rb_to_id(name)); } static VALUE -obj_methods(obj) +rb_obj_methods(obj) VALUE obj; { VALUE argv[1]; - argv[0] = TRUE; - return class_instance_methods(1, argv, CLASS_OF(obj)); + argv[0] = Qtrue; + return rb_class_instance_methods(1, argv, CLASS_OF(obj)); } -VALUE obj_singleton_methods(); +VALUE rb_obj_singleton_methods(); static VALUE -obj_private_methods(obj) +rb_obj_protected_methods(obj) VALUE obj; { VALUE argv[1]; - argv[0] = TRUE; - return class_private_instance_methods(1, argv, CLASS_OF(obj)); + argv[0] = Qtrue; + return rb_class_protected_instance_methods(1, argv, CLASS_OF(obj)); } -VALUE obj_instance_variables(); -VALUE obj_remove_instance_variable(); - static VALUE -f_integer(obj, arg) - VALUE obj, arg; +rb_obj_private_methods(obj) + VALUE obj; { - int i; + VALUE argv[1]; - switch (TYPE(arg)) { + argv[0] = Qtrue; + return rb_class_private_instance_methods(1, argv, CLASS_OF(obj)); +} + +VALUE +rb_Integer(val) + VALUE val; +{ + long i; + + switch (TYPE(val)) { case T_FLOAT: - if (RFLOAT(arg)->value <= (double)FIXNUM_MAX - && RFLOAT(arg)->value >= (double)FIXNUM_MIN) { - i = (int)RFLOAT(arg)->value; + if (RFLOAT(val)->value <= (double)FIXNUM_MAX + && RFLOAT(val)->value >= (double)FIXNUM_MIN) { + i = (long)RFLOAT(val)->value; break; } - return dbl2big(RFLOAT(arg)->value); + return rb_dbl2big(RFLOAT(val)->value); case T_BIGNUM: - return arg; + return val; case T_STRING: - return str2inum(RSTRING(arg)->ptr, 0); + return rb_str2inum(RSTRING(val)->ptr, 0); + + case T_NIL: + return INT2FIX(0); default: - i = NUM2INT(arg); + i = NUM2LONG(val); } return INT2NUM(i); } -VALUE -rb_Integer(val) - VALUE val; +static VALUE +rb_f_integer(obj, arg) + VALUE obj, arg; { - return f_integer(Qnil, val); + return rb_Integer(arg); } -static VALUE -to_flo(val) +struct arg_to { VALUE val; + char *s; +}; + +static VALUE +to_type(arg) + struct arg_to *arg; { - return rb_funcall(val, rb_intern("to_f"), 0); + return rb_funcall(arg->val, rb_intern(arg->s), 0); } static VALUE -fail_to_flo(val) +fail_to_type(arg) + struct arg_to *arg; +{ + rb_raise(rb_eTypeError, "failed to convert %s into %s", + NIL_P(arg->val) ? "nil" : + arg->val == Qtrue ? "true" : + arg->val == Qfalse ? "false" : + rb_class2name(CLASS_OF(arg->val)), + arg->s); +} + +VALUE +rb_convert_type(val, type, tname, method) VALUE val; + int type; + char *tname, *method; { - TypeError("failed to convert %s into Float", rb_class2name(CLASS_OF(val))); + struct arg_to arg1, arg2; + + if (TYPE(val) == type) return val; + arg1.val = arg2.val = val; + arg1.s = method; + arg2.s = tname; + val = rb_rescue(to_type, (VALUE)&arg1, fail_to_type, (VALUE)&arg2); + Check_Type(val, type); + return val; } -double big2dbl(); +double rb_big2dbl _((VALUE)); -static VALUE -f_float(obj, arg) - VALUE obj, arg; +VALUE +rb_Float(val) + VALUE val; { - switch (TYPE(arg)) { + switch (TYPE(val)) { case T_FIXNUM: - return float_new((double)FIX2INT(arg)); + return rb_float_new((double)FIX2LONG(val)); case T_FLOAT: - return arg; + return val; case T_BIGNUM: - return float_new(big2dbl(arg)); + return rb_float_new(rb_big2dbl(val)); default: - return rb_rescue(to_flo, arg, fail_to_flo, arg); + return rb_convert_type(val, T_FLOAT, "Float", "to_f"); } } -VALUE -rb_Float(val) - VALUE val; +static VALUE +rb_f_float(obj, arg) + VALUE obj, arg; { - return f_float(Qnil, val); + return rb_Float(arg); } double -num2dbl(val) +rb_num2dbl(val) VALUE val; { VALUE v = rb_Float(val); return RFLOAT(v)->value; } -static VALUE -f_string(obj, arg) - VALUE obj, arg; +char* +rb_str2cstr(str, len) + VALUE str; + int *len; { - return rb_funcall(arg, rb_intern("to_s"), 0); + if (TYPE(str) != T_STRING) { + str = rb_str_to_str(str); + } + if (len) *len = RSTRING(str)->len; + return RSTRING(str)->ptr; } VALUE rb_String(val) VALUE val; { - return f_string(Qnil, val); + return rb_convert_type(val, T_STRING, "String", "to_s"); } static VALUE -f_array(obj, arg) +rb_f_string(obj, arg) VALUE obj, arg; { - if (TYPE(arg) == T_ARRAY) return arg; - arg = rb_funcall(arg, rb_intern("to_a"), 0); - if (TYPE(arg) != T_ARRAY) { - TypeError("`to_a' did not return Array"); - } - return arg; + return rb_String(arg); } VALUE rb_Array(val) VALUE val; { - return f_array(Qnil, val); + if (TYPE(val) == T_ARRAY) return val; + val = rb_funcall(val, rb_intern("to_a"), 0); + if (TYPE(val) != T_ARRAY) { + rb_raise(rb_eTypeError, "`to_a' did not return Array"); + } + return val; } -VALUE -rb_to_a(val) /* backward compatibility */ - VALUE val; +static VALUE +rb_f_array(obj, arg) + VALUE obj, arg; { - return f_array(Qnil, val); + return rb_Array(arg); } static VALUE @@ -760,47 +919,36 @@ boot_defclass(name, super) VALUE super; { extern st_table *rb_class_tbl; - VALUE obj = class_new(super); + VALUE obj = rb_class_new(super); ID id = rb_intern(name); rb_name_class(obj, id); st_add_direct(rb_class_tbl, id, obj); - return (VALUE)obj; -} - -VALUE -rb_class_of(obj) - VALUE obj; -{ - if (FIXNUM_P(obj)) return cFixnum; - if (obj == Qnil) return cNilClass; - if (obj == FALSE) return cFalseClass; - if (obj == TRUE) return cTrueClass; - - return RBASIC(obj)->class; + return obj; } -VALUE TopSelf; +VALUE ruby_top_self; void Init_Object() { VALUE metaclass; - cObject = boot_defclass("Object", 0); - cModule = boot_defclass("Module", cObject); - cClass = boot_defclass("Class", cModule); + rb_cObject = boot_defclass("Object", 0); + rb_cModule = boot_defclass("Module", rb_cObject); + rb_cClass = boot_defclass("Class", rb_cModule); - metaclass = RBASIC(cObject)->class = singleton_class_new(cClass); - singleton_class_attached(metaclass, cObject); - metaclass = RBASIC(cModule)->class = singleton_class_new(metaclass); - singleton_class_attached(metaclass, cModule); - metaclass = RBASIC(cClass)->class = singleton_class_new(metaclass); - singleton_class_attached(metaclass, cClass); + metaclass = RBASIC(rb_cObject)->klass = rb_singleton_class_new(rb_cClass); + rb_singleton_class_attached(metaclass, rb_cObject); + metaclass = RBASIC(rb_cModule)->klass = rb_singleton_class_new(metaclass); + rb_singleton_class_attached(metaclass, rb_cModule); + metaclass = RBASIC(rb_cClass)->klass = rb_singleton_class_new(metaclass); + rb_singleton_class_attached(metaclass, rb_cClass); - mKernel = rb_define_module("Kernel"); - rb_include_module(cObject, mKernel); - rb_define_private_method(cClass, "inherited", obj_dummy, 1); + rb_mKernel = rb_define_module("Kernel"); + rb_include_module(rb_cObject, rb_mKernel); + rb_define_private_method(rb_cObject, "initialize", rb_obj_dummy, -1); + rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy, 1); /* * Ruby's Class Hierarchy Chart @@ -826,111 +974,132 @@ Init_Object() * + All metaclasses are instances of the class `Class'. */ - rb_define_method(mKernel, "nil?", rb_false, 0); - rb_define_method(mKernel, "==", obj_equal, 1); - rb_define_alias(mKernel, "equal?", "=="); - rb_define_alias(mKernel, "===", "=="); - rb_define_method(mKernel, "=~", rb_false, 1); - - rb_define_method(mKernel, "eql?", obj_equal, 1); - - rb_define_method(mKernel, "hash", obj_id, 0); - rb_define_method(mKernel, "id", obj_id, 0); - rb_define_method(mKernel, "type", obj_type, 0); - - rb_define_method(mKernel, "clone", obj_clone, 0); - rb_define_method(mKernel, "dup", obj_dup, 0); - - rb_define_method(mKernel, "to_a", any_to_a, 0); - rb_define_method(mKernel, "to_s", any_to_s, 0); - rb_define_method(mKernel, "inspect", obj_inspect, 0); - rb_define_method(mKernel, "methods", obj_methods, 0); - rb_define_method(mKernel, "singleton_methods", obj_singleton_methods, 0); - rb_define_method(mKernel, "private_methods", obj_private_methods, 0); - rb_define_method(mKernel, "instance_variables", obj_instance_variables, 0); - rb_define_method(mKernel, "remove_instance_variable", obj_remove_instance_variable, 0); - - rb_define_method(mKernel, "instance_of?", obj_is_instance_of, 1); - rb_define_method(mKernel, "kind_of?", obj_is_kind_of, 1); - rb_define_method(mKernel, "is_a?", obj_is_kind_of, 1); - - rb_define_global_function("sprintf", f_sprintf, -1); - rb_define_alias(mKernel, "format", "sprintf"); - - rb_define_global_function("Integer", f_integer, 1); - rb_define_global_function("Float", f_float, 1); - - rb_define_global_function("String", f_string, 1); - rb_define_global_function("Array", f_array, 1); - - cNilClass = rb_define_class("NilClass", cObject); - rb_define_method(cNilClass, "type", nil_type, 0); - rb_define_method(cNilClass, "to_s", nil_to_s, 0); - rb_define_method(cNilClass, "to_a", nil_to_a, 0); - rb_define_method(cNilClass, "inspect", nil_inspect, 0); - - rb_define_method(cNilClass, "nil?", rb_true, 0); - rb_undef_method(CLASS_OF(cNilClass), "new"); + rb_define_method(rb_mKernel, "nil?", rb_false, 0); + rb_define_method(rb_mKernel, "==", rb_obj_equal, 1); + rb_define_alias(rb_mKernel, "equal?", "=="); + rb_define_alias(rb_mKernel, "===", "=="); + rb_define_method(rb_mKernel, "=~", rb_false, 1); + + rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1); + + rb_define_method(rb_mKernel, "hash", rb_obj_hash, 0); + rb_define_method(rb_mKernel, "id", rb_obj_id, 0); + rb_define_method(rb_mKernel, "__id__", rb_obj_id, 0); + rb_define_method(rb_mKernel, "type", rb_obj_type, 0); + + rb_define_method(rb_mKernel, "clone", rb_obj_clone, 0); + rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0); + + rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0); + rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0); + rb_define_method(rb_mKernel, "untaint", rb_obj_untaint, 0); + + rb_define_method(rb_mKernel, "to_a", rb_any_to_a, 0); + rb_define_method(rb_mKernel, "to_s", rb_any_to_s, 0); + rb_define_method(rb_mKernel, "inspect", rb_obj_inspect, 0); + rb_define_method(rb_mKernel, "methods", rb_obj_methods, 0); + rb_define_method(rb_mKernel, "public_methods", rb_obj_methods, 0); + rb_define_method(rb_mKernel, "singleton_methods", rb_obj_singleton_methods, 0); + rb_define_method(rb_mKernel, "protected_methods", rb_obj_protected_methods, 0); + rb_define_method(rb_mKernel, "private_methods", rb_obj_private_methods, 0); + rb_define_method(rb_mKernel, "instance_variables", rb_obj_instance_variables, 0); + rb_define_private_method(rb_mKernel, "remove_instance_variable", + rb_obj_remove_instance_variable, 0); + + rb_define_method(rb_mKernel, "instance_of?", rb_obj_is_instance_of, 1); + rb_define_method(rb_mKernel, "kind_of?", rb_obj_is_kind_of, 1); + rb_define_method(rb_mKernel, "is_a?", rb_obj_is_kind_of, 1); + + rb_define_global_function("sprintf", rb_f_sprintf, -1); + rb_define_global_function("format", rb_f_sprintf, -1); + + rb_define_global_function("Integer", rb_f_integer, 1); + rb_define_global_function("Float", rb_f_float, 1); + + rb_define_global_function("String", rb_f_string, 1); + rb_define_global_function("Array", rb_f_array, 1); + + rb_cNilClass = rb_define_class("NilClass", rb_cObject); + rb_define_method(rb_cNilClass, "type", nil_type, 0); + rb_define_method(rb_cNilClass, "to_i", nil_to_i, 0); + rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0); + rb_define_method(rb_cNilClass, "to_a", nil_to_a, 0); + rb_define_method(rb_cNilClass, "inspect", nil_inspect, 0); + + rb_define_method(rb_cNilClass, "nil?", rb_true, 0); + rb_undef_method(CLASS_OF(rb_cNilClass), "new"); rb_define_global_const("NIL", Qnil); /* default addition */ - rb_define_method(cNilClass, "+", nil_plus, 1); - - rb_define_global_function("initialize", obj_dummy, -1); - rb_define_global_function("singleton_method_added", obj_dummy, 1); - - rb_define_method(cModule, "===", mod_eqq, 1); - rb_define_method(cModule, "<=>", mod_cmp, 1); - rb_define_method(cModule, "<", mod_lt, 1); - rb_define_method(cModule, "<=", mod_le, 1); - rb_define_method(cModule, ">", mod_gt, 1); - rb_define_method(cModule, ">=", mod_ge, 1); - rb_define_method(cModule, "clone", mod_clone, 0); - rb_define_method(cModule, "to_s", mod_to_s, 0); - rb_define_method(cModule, "included_modules", mod_included_modules, 0); - rb_define_method(cModule, "name", mod_name, 0); - rb_define_method(cModule, "ancestors", mod_ancestors, 0); - - rb_define_private_method(cModule, "attr", mod_attr, -1); - rb_define_private_method(cModule, "attr_reader", mod_attr_reader, -1); - rb_define_private_method(cModule, "attr_writer", mod_attr_writer, -1); - rb_define_private_method(cModule, "attr_accessor", mod_attr_accessor, -1); - - rb_define_singleton_method(cModule, "new", module_new, 0); - rb_define_method(cModule, "instance_methods", class_instance_methods, -1); - rb_define_method(cModule, "private_instance_methods", class_private_instance_methods, -1); - - rb_define_method(cModule, "constants", mod_constants, 0); - rb_define_method(cModule, "const_get", mod_const_get, 1); - rb_define_method(cModule, "const_set", mod_const_set, 2); - rb_define_method(cModule, "const_defined?", mod_const_defined, 1); - rb_define_private_method(cModule, "method_added", obj_dummy, 1); - - rb_define_method(cClass, "new", class_new_instance, -1); - rb_define_method(cClass, "superclass", class_superclass, 0); - rb_define_singleton_method(cClass, "new", class_s_new, -1); - rb_undef_method(cClass, "extend_object"); - rb_undef_method(cClass, "append_features"); - - rb_define_singleton_method(cClass, "new", class_s_new, -1); - - cData = rb_define_class("Data", cObject); - - TopSelf = obj_alloc(cObject); - rb_global_variable(&TopSelf); - rb_define_singleton_method(TopSelf, "to_s", main_to_s, 0); - - cTrueClass = rb_define_class("TrueClass", cObject); - rb_define_method(cTrueClass, "to_s", true_to_s, 0); - rb_define_method(cTrueClass, "type", true_type, 0); - rb_undef_method(CLASS_OF(cTrueClass), "new"); - rb_define_global_const("TRUE", TRUE); - - cFalseClass = rb_define_class("FalseClass", cObject); - rb_define_method(cFalseClass, "to_s", false_to_s, 0); - rb_define_method(cFalseClass, "type", false_type, 0); - rb_undef_method(CLASS_OF(cFalseClass), "new"); - rb_define_global_const("FALSE", FALSE); +#ifdef NIL_PLUS + rb_define_method(rb_cNilClass, "+", nil_plus, 1); +#endif + + rb_define_global_function("singleton_method_added", rb_obj_dummy, 1); + + rb_define_method(rb_cModule, "===", rb_mod_eqq, 1); + rb_define_method(rb_cModule, "<=>", rb_mod_cmp, 1); + rb_define_method(rb_cModule, "<", rb_mod_lt, 1); + rb_define_method(rb_cModule, "<=", rb_mod_le, 1); + rb_define_method(rb_cModule, ">", rb_mod_gt, 1); + rb_define_method(rb_cModule, ">=", rb_mod_ge, 1); + rb_define_method(rb_cModule, "clone", rb_mod_clone, 0); + rb_define_method(rb_cModule, "to_s", rb_mod_to_s, 0); + rb_define_method(rb_cModule, "included_modules", rb_mod_included_modules, 0); + rb_define_method(rb_cModule, "name", rb_mod_name, 0); + rb_define_method(rb_cModule, "ancestors", rb_mod_ancestors, 0); + + rb_define_private_method(rb_cModule, "attr", rb_mod_attr, -1); + rb_define_private_method(rb_cModule, "attr_reader", rb_mod_attr_reader, -1); + rb_define_private_method(rb_cModule, "attr_writer", rb_mod_attr_writer, -1); + rb_define_private_method(rb_cModule, "attr_accessor", rb_mod_attr_accessor, -1); + + rb_define_singleton_method(rb_cModule, "new", rb_module_s_new, 0); + rb_define_method(rb_cModule, "instance_methods", rb_class_instance_methods, -1); + rb_define_method(rb_cModule, "public_instance_methods", rb_class_instance_methods, -1); + rb_define_method(rb_cModule, "protected_instance_methods", rb_class_protected_instance_methods, -1); + rb_define_method(rb_cModule, "private_instance_methods", rb_class_private_instance_methods, -1); + + rb_define_method(rb_cModule, "constants", rb_mod_constants, 0); + rb_define_method(rb_cModule, "const_get", rb_mod_const_get, 1); + rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2); + rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, 1); + rb_define_private_method(rb_cModule, "remove_const", rb_mod_remove_const, 1); + rb_define_private_method(rb_cModule, "method_added", rb_obj_dummy, 1); + + rb_define_method(rb_cClass, "new", rb_class_new_instance, -1); + rb_define_method(rb_cClass, "superclass", rb_class_superclass, 0); + rb_define_singleton_method(rb_cClass, "new", rb_class_s_new, -1); + rb_undef_method(rb_cClass, "extend_object"); + rb_undef_method(rb_cClass, "append_features"); + rb_define_singleton_method(rb_cClass, "inherited", rb_class_s_inherited, 1); + + rb_cData = rb_define_class("Data", rb_cObject); + rb_undef_method(CLASS_OF(rb_cData), "new"); + + ruby_top_self = rb_obj_alloc(rb_cObject); + rb_global_variable(&ruby_top_self); + rb_define_singleton_method(ruby_top_self, "to_s", main_to_s, 0); + + rb_cTrueClass = rb_define_class("TrueClass", rb_cObject); + rb_define_method(rb_cTrueClass, "to_s", true_to_s, 0); + rb_define_method(rb_cTrueClass, "to_i", true_to_i, 0); + rb_define_method(rb_cTrueClass, "type", true_type, 0); + rb_define_method(rb_cTrueClass, "&", true_and, 1); + rb_define_method(rb_cTrueClass, "|", true_or, 1); + rb_define_method(rb_cTrueClass, "^", true_xor, 1); + rb_undef_method(CLASS_OF(rb_cTrueClass), "new"); + rb_define_global_const("TRUE", Qtrue); + + rb_cFalseClass = rb_define_class("FalseClass", rb_cObject); + rb_define_method(rb_cFalseClass, "to_s", false_to_s, 0); + rb_define_method(rb_cFalseClass, "to_i", false_to_i, 0); + rb_define_method(rb_cFalseClass, "type", false_type, 0); + rb_define_method(rb_cFalseClass, "&", false_and, 1); + rb_define_method(rb_cFalseClass, "|", false_or, 1); + rb_define_method(rb_cFalseClass, "^", false_xor, 1); + rb_undef_method(CLASS_OF(rb_cFalseClass), "new"); + rb_define_global_const("FALSE", Qfalse); eq = rb_intern("=="); eql = rb_intern("eql?"); |