summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-08-27 08:31:08 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-08-27 08:31:08 +0000
commitc45908e41f47c88674b73a754ecd0535449b667a (patch)
treea27bb0f2ca80fa80b9582ddcb8312eee673b0bd5 /object.c
parentcd3d4a01f248fad1a73ff0b66b7a8d1653f64c19 (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.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/object.c b/object.c
index c223c5861d..cbc37944f3 100644
--- a/object.c
+++ b/object.c
@@ -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");
}