[#3726] Fixnum#clone and Float#clone raise different exceptions — "David A. Black" <dblack@...>

Hi --

15 messages 2004/11/12
[#3749] Re: Fixnum#clone and Float#clone raise different exceptions — "David A. Black" <dblack@...> 2004/11/16

Hi --

[#3751] Re: Fixnum#clone and Float#clone raise different exceptions — Yukihiro Matsumoto <matz@...> 2004/11/16

Hi,

[#3752] Re: Fixnum#clone and Float#clone raise different exceptions — "David A. Black" <dblack@...> 2004/11/16

Hi --

[#3785] The latest 1.8.2 cvs prints parse error when starting extension compiling — Yukihiro Matsumoto <matz@...>

Hi,

13 messages 2004/11/23
[#3787] Re: The latest 1.8.2 cvs prints parse error when starting extension compiling — Johan Holmberg <holmberg@...> 2004/11/23

Re: Fixnum#clone and Float#clone raise different exceptions

From: Mauricio Fern疣dez <batsman.geo@...>
Date: 2004-11-27 10:04:16 UTC
List: ruby-core #3833
On Fri, Nov 26, 2004 at 10:17:57AM +0900, Florian Growrote:
> >Do you accept the following behavior?
> >
> >  a = 4
> >  a.instance_eval{@a=5}
> >  b = a.clone		# b = 4
> >  b.instance_eval{@a=10}
> >  a.instance_eval{@a}   # @a = 10
> >
> >Similar thing can happen for a Float and singleton methods.
> 
> I think this is okay. I think getting an exception when doing obj.clone 
> is a thing that would be against expected behavior more frequently than 
> sharing instance variables on immediate Objects. (Instance variables on 
> those are not used frequently anyway.)

Why is the attached patch unacceptable? I can see two problems, but
I'm not sure they justify discarding this option:
* conceptually, Float objects are immutable so it'd make sense to have only
  one for a given value. However, they are not truly immediate, and in the
  current implementation there can be several Float objects with the
  same value.
* somebody could redefine Float#initialize_copy in Ruby, and he wouldn't be
  able to set the value. But this isn't any worse than in the case of Regexp
  or Time.

I am probably missing more.

> I also think that the above change would bring back consistency between 
> obj.clone and Marshal.load(Marshal.dump(obj)).
> 
> Maybe a note stating that you don't actually get a new object could be 
> attached to the documentation of the clone and dup methods of Fixnum, 
> Symbol, TrueClass, FalseClass and NilClass.

These classes differ from Float: whereas they are truly immediate,
Float VALUEs do point to a RFloat structure...
Only an implementation issue (32 bits are not enough) or deliberate?

I guess the first applies, in which case the following is inconsistent
with that choice:

>> 3.0.instance_eval{@a = 1}
=> 1
>> 3.0.instance_eval{@a}
(irb):2: warning: instance variable @a not initialized

If Ruby cannot be consistent given the current implementation, why not
choose a convenient inconsistency? :-)


--- numeric.c.orig      2004-11-27 10:33:30.000000000 +0100
+++ numeric.c   2004-11-27 10:38:10.000000000 +0100
@@ -475,6 +475,34 @@
     return (VALUE)flt;
 }

+static VALUE float_alloc _((VALUE));
+static VALUE
+float_alloc(klass)
+    VALUE klass;
+{
+    NEWOBJ(flt, struct RFloat);
+    OBJSETUP(flt, klass, T_FLOAT);
+    /* set value to 0.0? */
+    return (VALUE)flt;
+}
+
+static VALUE
+float_init_copy(x, y)
+    VALUE x, y;
+{
+    if(x == y) return x;
+    rb_check_frozen(x);
+
+    switch (TYPE(y)) {
+      case T_FLOAT:
+        RFLOAT(x)->value = RFLOAT(y)->value;
+        return x;
+      default:
+        rb_raise(rb_eTypeError, "can't copy %s", rb_obj_classname(x));
+    }
+    return Qnil;               /* not reached */
+}
+
 /*
  *  call-seq:
  *     flt.to_s    => string
@@ -2868,8 +2896,8 @@

     rb_cFloat  = rb_define_class("Float", rb_cNumeric);

-    rb_undef_alloc_func(rb_cFloat);
-    rb_undef_method(CLASS_OF(rb_cFloat), "new");
+    rb_define_alloc_func(rb_cFloat, float_alloc);
+    rb_define_method(rb_cFloat, "initialize_copy", float_init_copy, 1);

     rb_define_singleton_method(rb_cFloat, "induced_from", rb_flo_induced_from, 1);
     rb_include_module(rb_cFloat, rb_mPrecision);


-- 
Hassle-free packages for Ruby?
RPA is available from http://www.rubyarchive.org/

In This Thread