diff options
Diffstat (limited to 'object.c')
-rw-r--r-- | object.c | 384 |
1 files changed, 283 insertions, 101 deletions
@@ -6,7 +6,7 @@ $Date: 1995/01/12 08:54:49 $ created at: Thu Jul 15 12:01:24 JST 1993 - Copyright (C) 1993-1995 Yukihiro Matsumoto + Copyright (C) 1993-1996 Yukihiro Matsumoto ************************************************/ @@ -18,24 +18,39 @@ VALUE cKernel; VALUE cObject; VALUE cModule; VALUE cClass; -VALUE cNil; +VALUE cFixnum; VALUE cData; +static VALUE cNil; +static VALUE cTrue; +static VALUE cFalse; + struct st_table *new_idhash(); VALUE f_sprintf(); VALUE obj_alloc(); -static ID eq; - -static ID init; +static ID eq, eql; +static ID inspect; -VALUE +int rb_equal(obj1, obj2) VALUE obj1, obj2; { - return rb_funcall(obj1, eq, 1, obj2); + VALUE result; + + result = rb_funcall(obj1, eq, 1, obj2); + if (result == FALSE || NIL_P(result)) + return FALSE; + return TRUE; +} + +int +rb_eql(obj1, obj2) + VALUE obj1, obj2; +{ + return rb_funcall(obj1, eql, 1, obj2); } static VALUE @@ -67,11 +82,13 @@ krn_id(obj) return obj | FIXNUM_FLAG; } +char *rb_class2path(); + static VALUE krn_type(obj) struct RBasic *obj; { - return obj->class; + return rb_class_path(obj->class); } static VALUE @@ -81,7 +98,7 @@ krn_clone(obj) VALUE clone; if (TYPE(obj) != T_OBJECT) { - Fail("can't clone %s", rb_class2name(CLASS_OF(obj))); + TypeError("can't clone %s", rb_class2name(CLASS_OF(obj))); } clone = obj_alloc(RBASIC(obj)->class); @@ -89,6 +106,7 @@ krn_clone(obj) 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; return clone; } @@ -111,6 +129,13 @@ krn_to_s(obj) } VALUE +rb_inspect(obj) + VALUE obj; +{ + return rb_funcall(obj, inspect, 0, 0); +} + +static VALUE krn_inspect(obj) VALUE obj; { @@ -126,8 +151,11 @@ inspect_i(id, value, str) VALUE str2; char *ivname; + /* need not to show internal data */ + if (TYPE(value) == T_DATA) return ST_CONTINUE; if (str->ptr[0] == '-') { str->ptr[0] = '#'; + str_cat(str, ": ", 2); } else { str_cat(str, ", ", 2); @@ -135,7 +163,12 @@ inspect_i(id, value, str) ivname = rb_id2name(id); str_cat(str, ivname, strlen(ivname)); str_cat(str, "=", 1); - str2 = rb_funcall(value, rb_intern("inspect"), 0, 0); + if (TYPE(value) == T_OBJECT) { + str2 = krn_to_s(value); + } + else { + str2 = rb_inspect(value); + } str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); return ST_CONTINUE; @@ -145,25 +178,20 @@ static VALUE obj_inspect(obj) struct RObject *obj; { - VALUE str; - char buf[256]; + if (TYPE(obj) == T_OBJECT && obj->iv_tbl) { + VALUE str; + char buf[256]; - switch (TYPE(obj)) { - case T_OBJECT: - case T_MODULE: - case T_CLASS: - if (obj->iv_tbl) break; - /* fall through */ - default: - return krn_inspect(obj); - } + sprintf(buf, "-<%s", rb_class2name(CLASS_OF(obj))); + str = str_new2(buf); + st_foreach(obj->iv_tbl, inspect_i, str); + str_cat(str, ">", 1); + if (RSTRING(str)->ptr[0] == '-') /* no instance-var */ + return krn_inspect(obj); - sprintf(buf, "-<%s: ", rb_class2name(CLASS_OF(obj))); - str = str_new2(buf); - st_foreach(obj->iv_tbl, inspect_i, str); - str_cat(str, ">", 1); - - return str; + return str; + } + return krn_inspect(obj); } VALUE @@ -177,10 +205,10 @@ obj_is_instance_of(obj, c) case T_CLASS: break; default: - Fail("class or module required"); + TypeError("class or module required"); } - while (FL_TEST(class, FL_SINGLE)) { + while (FL_TEST(class, FL_SINGLETON)) { class = class->super; } if (c == (VALUE)class) return TRUE; @@ -198,7 +226,7 @@ obj_is_kind_of(obj, c) case T_CLASS: break; default: - Fail("class or module required"); + TypeError("class or module required"); } while (class) { @@ -234,14 +262,21 @@ static VALUE nil_to_s(obj) VALUE obj; { + return str_new2(""); +} + +static VALUE +nil_inspect(obj) + VALUE obj; +{ return str_new2("nil"); } static VALUE -nil_type(nil) - VALUE nil; +nil_type(obj) + VALUE obj; { - return cNil; + return str_new2("Nil"); } static VALUE @@ -256,10 +291,10 @@ nil_plus(x, y) case T_ARRAY: return y; default: - Fail("tried to add %s(%s) to nil", - RSTRING(obj_as_string(y))->ptr, rb_class2name(CLASS_OF(y))); + TypeError("tried to add %s(%s) to nil", + RSTRING(obj_as_string(y))->ptr, rb_class2name(CLASS_OF(y))); } - return Qnil; /* not reached */ + /* not reached */ } static VALUE @@ -273,29 +308,38 @@ static VALUE true_to_s(obj) VALUE obj; { - return str_new2("t"); + return str_new2("TRUE"); } -VALUE -obj_alloc(class) - VALUE class; +static VALUE +true_type(obj) + VALUE obj; { - NEWOBJ(obj, struct RObject); - OBJSETUP(obj, class, T_OBJECT); + return str_new2("TRUE"); +} - return (VALUE)obj; +static VALUE +false_to_s(obj) + VALUE obj; +{ + return str_new2("FALSE"); } static VALUE -mod_new(argc, argv, class) - int argc; - VALUE *argv; +false_type(obj) + VALUE obj; +{ + return str_new2("FALSE"); +} + +VALUE +obj_alloc(class) VALUE class; { - VALUE obj = obj_alloc(class); + NEWOBJ(obj, struct RObject); + OBJSETUP(obj, class, T_OBJECT); - rb_funcall2(obj, init, argc, argv); - return obj; + return (VALUE)obj; } static VALUE @@ -311,8 +355,6 @@ mod_clone(module) return (VALUE)clone; } -char *rb_class2path(); - static VALUE mod_to_s(class) VALUE class; @@ -320,6 +362,20 @@ mod_to_s(class) return rb_class_path(class); } +VALUE class_s_new(); /* moved to eval.c */ + +static VALUE +class_superclass(class) + struct RClass *class; +{ + struct RClass *super = class->super; + + while (TYPE(super) == T_ICLASS) + super = super->super; + + return (VALUE)super; +} + ID rb_to_id(name) VALUE name; @@ -327,7 +383,8 @@ rb_to_id(name) if (TYPE(name) == T_STRING) { return rb_intern(RSTRING(name)->ptr); } - return NUM2INT(name); + Check_Type(name, T_FIXNUM); + return FIX2INT(name); } static VALUE @@ -360,8 +417,82 @@ mod_private_attr(class, name) return Qnil; } -static -VALUE boot_defclass(name, super) +static VALUE +f_integer(obj, arg) + VALUE obj, arg; +{ + int i; + + switch (TYPE(arg)) { + case T_FLOAT: + if (RFLOAT(arg)->value <= (double)FIXNUM_MAX + && RFLOAT(arg)->value >= (double)FIXNUM_MIN) { + i = (int)RFLOAT(arg)->value; + break; + } + return dbl2big(RFLOAT(arg)->value); + + case T_BIGNUM: + return arg; + + case T_STRING: + return str2inum(RSTRING(arg)->ptr, 0); + + default: + i = NUM2INT(arg); + } + return INT2NUM(i); +} + +static VALUE +to_flo(val) + VALUE val; +{ + return rb_funcall(val, rb_intern("to_f"), 0); +} + +static VALUE +fail_to_flo(val) + VALUE val; +{ + TypeError("failed to convert %s into Float", rb_class2name(CLASS_OF(val))); +} + +double big2dbl(); + +VALUE +f_float(obj, arg) + VALUE obj, arg; +{ + + switch (TYPE(arg)) { + case T_FLOAT: + return arg; + + case T_BIGNUM: + return float_new(big2dbl(arg)); + + default: + return rb_rescue(to_flo, arg, fail_to_flo, arg); + } +} + +static VALUE +f_string(obj, arg) + VALUE obj, arg; +{ + return rb_funcall(arg, rb_intern("to_s"), 0); +} + +static VALUE +f_array(obj, arg) + VALUE obj, arg; +{ + return rb_funcall(arg, rb_intern("to_a"), 0); +} + +static VALUE +boot_defclass(name, super) char *name; VALUE super; { @@ -371,19 +502,53 @@ VALUE boot_defclass(name, super) rb_name_class(obj, id); st_add_direct(rb_class_tbl, id, obj); - rb_set_class_path(obj, 0, name); return (VALUE)obj; } +VALUE +rb_class_of(obj) + VALUE obj; +{ + if (FIXNUM_P(obj)) return cFixnum; + if (obj == Qnil) return cNil; + if (obj == FALSE) return cFalse; + if (obj == TRUE) return cTrue; + + return RBASIC(obj)->class; +} + +int +rb_type(obj) + VALUE obj; +{ + if (FIXNUM_P(obj)) return T_FIXNUM; + if (obj == Qnil) return T_NIL; + if (obj == FALSE) return T_FALSE; + if (obj == TRUE) return T_TRUE; + + return BUILTIN_TYPE(obj); +} + +int +rb_special_const_p(obj) + VALUE obj; +{ + if (FIXNUM_P(obj)) return TRUE; + if (obj == Qnil) return TRUE; + if (obj == FALSE) return TRUE; + if (obj == TRUE) return TRUE; + + return FALSE; +} + VALUE TopSelf; -VALUE TRUE = INT2FIX(1); void Init_Object() { VALUE metaclass; - cKernel = boot_defclass("Kernel", Qnil); + cKernel = boot_defclass("kernel", 0); cObject = boot_defclass("Object", cKernel); cModule = boot_defclass("Module", cObject); cClass = boot_defclass("Class", cModule); @@ -396,39 +561,40 @@ Init_Object() /* * Ruby's Class Hierarchy Chart * - * +-------nil +---------------------+ - * | ^ | | - * | | | | - * | Kernel----->(Kernel) | - * | ^ ^ ^ ^ | - * | | | | | | - * | +---+ +----+ | +---+ | - * | | +-----|----+ | | - * | | | | | | - * +->Nil->(Nil) Object---->(Object) | - * ^ ^ ^ ^ | - * | | | | | - * | | +-------+ | | - * | | | | | - * | +---------+ +------+ | - * | | | | | - * +---------+ | Module--->(Module) | - * | | ^ ^ | - * OtherClass-->(OtherClass) | | | - * Class---->(Class) | - * ^ | - * | | - * +----------------+ + * +------------------------+ + * | | + * kernel----->(kernel) | + * ^ ^ ^ ^ | + * | | | | | + * +---+ +----+ | +---+ | + * | +-----|----+ | | + * | | | | | + * Nil->(Nil) Object---->(Object) | + * ^ ^ ^ ^ | + * | | | | | + * | | +-----+ +---------+ | + * | | | | | + * | +-----------+ | | + * | | | | | + * +------+ | Module--->(Module) | + * | | ^ ^ | + * OtherClass-->(OtherClass) | | | + * Class---->(Class) | + * ^ | + * | | + * +----------------+ * * + All metaclasses are instances of the class `Class'. */ - rb_define_method(cKernel, "nil?", krn_nil_p, 0); rb_define_method(cKernel, "==", krn_equal, 1); rb_define_alias(cKernel, "equal?", "=="); + rb_define_alias(cKernel, "===", "=="); rb_define_alias(cKernel, "=~", "=="); + rb_define_method(cKernel, "eql?", rb_equal, 1); + rb_define_method(cKernel, "hash", krn_id, 0); rb_define_method(cKernel, "id", krn_id, 0); rb_define_method(cKernel, "type", krn_type, 0); @@ -440,14 +606,32 @@ Init_Object() rb_define_method(cKernel, "to_s", krn_to_s, 0); rb_define_method(cKernel, "inspect", krn_inspect, 0); + rb_define_method(cKernel, "instance_of?", obj_is_instance_of, 1); + rb_define_method(cKernel, "kind_of?", obj_is_kind_of, 1); + rb_define_method(cKernel, "is_a?", obj_is_kind_of, 1); + rb_define_private_method(cKernel, "sprintf", f_sprintf, -1); rb_define_alias(cKernel, "format", "sprintf"); + rb_define_private_method(cKernel, "Integer", f_integer, 1); + rb_define_private_method(cKernel, "Float", f_float, 1); + + rb_define_private_method(cKernel, "String", f_string, 1); + rb_define_private_method(cKernel, "Array", f_array, 1); + + cNil = rb_define_class("nil", cKernel); + rb_define_method(cNil, "type", nil_type, 0); + rb_define_method(cNil, "to_s", nil_to_s, 0); + rb_define_method(cNil, "inspect", nil_inspect, 0); + + rb_define_method(cNil, "nil?", nil_nil_p, 0); + + /* default addition */ + rb_define_method(cNil, "+", nil_plus, 1); + rb_define_private_method(cObject, "initialize", obj_initialize, -1); rb_define_private_method(cObject, "singleton_method_added", obj_s_added, 1); - rb_define_method(cObject, "is_instance_of?", obj_is_instance_of, 1); - rb_define_method(cObject, "is_kind_of?", obj_is_kind_of, 1); rb_define_method(cObject, "inspect", obj_inspect, 0); rb_define_method(cModule, "to_s", mod_to_s, 0); @@ -455,29 +639,27 @@ Init_Object() rb_define_private_method(cModule, "attr", mod_attr, -1); rb_define_private_method(cModule, "public_attr", mod_public_attr, -1); rb_define_private_method(cModule, "private_attr", mod_private_attr, -1); + rb_define_private_method(cModule, "object_extended", obj_s_added, 1); - rb_define_method(cClass, "new", mod_new, -1); - - cNil = rb_define_class("Nil", cKernel); - rb_define_method(cNil, "to_s", nil_to_s, 0); - rb_define_method(cNil, "type", nil_type, 0); - - rb_define_method(cNil, "nil?", nil_nil_p, 0); - - /* default addition */ - rb_define_method(cNil, "+", nil_plus, 1); + rb_define_method(cClass, "new", class_s_new, -1); + rb_define_method(cClass, "superclass", class_superclass, -1); cData = rb_define_class("Data", cKernel); - eq = rb_intern("=="); - - Qself = TopSelf = obj_alloc(cObject); + TopSelf = obj_alloc(cObject); rb_define_singleton_method(TopSelf, "to_s", main_to_s, 0); - TRUE = obj_alloc(cObject); - rb_define_singleton_method(TRUE, "to_s", true_to_s, 0); - rb_define_const(cKernel, "TRUE", TRUE); - rb_define_const(cKernel, "FALSE", FALSE); + cTrue = rb_define_class("true", cKernel); + rb_define_method(cTrue, "to_s", true_to_s, 0); + rb_define_method(cTrue, "type", true_type, 0); + rb_define_global_const("TRUE", TRUE); - init = rb_intern("initialize"); + cFalse = rb_define_class("false", cKernel); + rb_define_method(cFalse, "to_s", false_to_s, 0); + rb_define_method(cFalse, "type", false_type, 0); + rb_define_global_const("FALSE", FALSE); + + eq = rb_intern("=="); + eql = rb_intern("eql?"); + inspect = rb_intern("inspect"); } |