David Vallner
2/7/2006 8:39:00 PM
That's because Fixnums are immediate values, and thus they compare by value.
You can't possibly have two distinct Fixnum objects representing for example
123 short of doing some very sick core interpreter hacks.
The comparing of the objects fails, because by default, objects compare by
reference unless overridden.
Also, Marshal also has completely no way of telling if the object is a
constant or not. For that matter, I don't think there even is such a thing as
a constant object in Ruby, you can only design objects as immutable, and have
constant object _references_.
I also don't think Marshal is even supposed at all to return completely the
same object if possible on loading, it's supposed to recreate an object with
the same structure (optionally between two runs of an interpreter). If
anything, the change you propose might end up breaking code that could use
Marshal for simple deep copying of Objects as is common in Java / .NET. (I
don't recall at the moment if there's any Ruby-specific deep-copy
functionality)
David Vallner
Dna Utorok 07 Február 2006 20:38 Brian Buckley napísal:
> Hello,
>
> When one marshals a constant and later unmarshals it, a brand new object
> appears to be created during unmarshalling. This seems wasteful,
> especially in cases when constants are large (contain many attributes). Is
> it possible to customize marshal for a class (or for singleton objects of
> the class) so that unmarshalling a constant simply returns the already
> existing constant rather than creating a new one? I've noticed Fixnum's
> exhibit this behavior.
>
> --Brian
>
> class A;
> A1 = A.new
> end
>
> before = A::A1
> after = Marshal.load(Marshal.dump(before)) #marshal and back
> puts before == after #darn -- it is false
> puts before.object_id == after.object_id #same here
>
> # it works for Fixnums
> before = 123
> after = Marshal.load(Marshal.dump(before))
> puts before == after # true
> puts before.object_id == after.object_id #also true