diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-08-27 08:31:08 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-08-27 08:31:08 +0000 |
commit | c45908e41f47c88674b73a754ecd0535449b667a (patch) | |
tree | a27bb0f2ca80fa80b9582ddcb8312eee673b0bd5 /object.c | |
parent | cd3d4a01f248fad1a73ff0b66b7a8d1653f64c19 (diff) |
* file.c (rb_find_file): $LOAD_PATH must not be empty.
* file.c (rb_find_file_ext): ditto.
* range.c (range_eq): class check should be based on range.class,
instead of Range to work with Range.dup.
* range.c (range_eql): ditto.
* class.c (rb_mod_dup): need to preserve metaclass and flags.
* object.c (rb_cstr_to_dbl): had a buffer overrun.
* marshal.c (w_class): integrate singleton check into a funciton
to follow DRY principle.
* marshal.c (w_uclass): should check singleton method.
* object.c (rb_obj_dup): dmark and dfree functions must be match
for T_DATA type.
* object.c (rb_obj_dup): class of the duped object must be match
to the class of the original.
* re.c (rb_reg_quote): do not escape \t, \f, \r, \n, for they are
not regular expression metacharacters.
* time.c (time_s_alloc): use time_free instead of free (null check,
also serves for type mark).
* time.c (time_s_at): check dfree function too.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2748 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'object.c')
-rw-r--r-- | object.c | 49 |
1 files changed, 33 insertions, 16 deletions
@@ -33,7 +33,7 @@ VALUE rb_cSymbol; static ID eq, eql; static ID inspect; -static ID clone; +static ID become; static ID alloc; VALUE @@ -95,15 +95,18 @@ rb_obj_clone(obj) VALUE obj; { VALUE clone; + int frozen; if (rb_special_const_p(obj)) { rb_raise(rb_eTypeError, "can't clone %s", rb_class2name(CLASS_OF(obj))); } clone = rb_obj_alloc(rb_class_real(RBASIC(obj)->klass)); - CLONESETUP(clone,obj); - if (TYPE(clone) == T_OBJECT && ROBJECT(obj)->iv_tbl) { - ROBJECT(clone)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl); - } + CLONESETUP(clone, obj); + frozen = OBJ_FROZEN(obj); + FL_UNSET(clone, FL_FREEZE); /* temporarily remove frozen flag */ + rb_funcall(clone, become, 1, obj); + if (frozen) OBJ_FREEZE(clone); /* restore frozen status */ + OBJ_INFECT(clone, obj); return clone; } @@ -117,18 +120,31 @@ rb_obj_dup(obj) if (rb_special_const_p(obj)) { rb_raise(rb_eTypeError, "can't dup %s", rb_class2name(CLASS_OF(obj))); } - dup = rb_funcall(obj, clone, 0, 0); - if (TYPE(dup) != TYPE(obj)) { - rb_raise(rb_eTypeError, "dupulicated object must be same type"); + dup = rb_obj_alloc(rb_class_real(RBASIC(obj)->klass)); + DUPSETUP(dup, obj); + rb_funcall(dup, become, 1, obj); + OBJ_INFECT(dup, obj); + + return dup; +} + +VALUE +rb_obj_become(obj, orig) + VALUE obj, orig; +{ + long type; + + if ((type = TYPE(obj)) != TYPE(orig) || + rb_obj_class(obj) != rb_obj_class(orig)) { + rb_raise(rb_eTypeError, "become should take same class object"); } - if (!SPECIAL_CONST_P(dup)) { - OBJSETUP(dup, rb_obj_class(obj), BUILTIN_TYPE(obj)); - OBJ_INFECT(dup, obj); - if (FL_TEST(obj, FL_EXIVAR)) { - FL_SET(dup, FL_EXIVAR); + if (type == T_OBJECT) { + if (ROBJECT(obj)->iv_tbl) st_free_table(ROBJECT(obj)->iv_tbl); + if (ROBJECT(orig)->iv_tbl) { + ROBJECT(obj)->iv_tbl = st_copy(ROBJECT(orig)->iv_tbl); } } - return dup; + return obj; } static VALUE @@ -1009,7 +1025,7 @@ rb_cstr_to_dbl(p, badcheck) return d; } if (*end) { - char *buf = ALLOCA_N(char, strlen(p)); + char *buf = ALLOCA_N(char, strlen(p)+1); char *n = buf; while (p < end) *n++ = *p++; @@ -1267,6 +1283,7 @@ Init_Object() 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, "become", rb_obj_become, 1); rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0); rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0); @@ -1402,5 +1419,5 @@ Init_Object() eq = rb_intern("=="); eql = rb_intern("eql?"); inspect = rb_intern("inspect"); - clone = rb_intern("clone"); + become = rb_intern("become"); } |