summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'object.c')
-rw-r--r--object.c384
1 files changed, 283 insertions, 101 deletions
diff --git a/object.c b/object.c
index 74324b77e7..5b18835613 100644
--- a/object.c
+++ b/object.c
@@ -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");
}