On 11/16/05, Eric Mahurin <eric.mahurin / gmail.com> wrote:
>>   class Object
>>     def replace(other)
>>       other.instance_variables.each do |name|
>>         instance_variable_set(name,
>>             other.instance_variable_get(name))
>>       end
>>     end
>>   end
> I don't like this a whole lot. It breaks encapsulation big time. If
> other is a completely different object, this could be putting this
> object into a strange state.

Obviously, I wasn't clear. I said "At a simplistic level, this is:" ...
This means that this is *essentially* what the operation would do, but
not necessarily the full scope of what would be needed. A more "safe"
operation would be:

  class Object
    def replace(other)
	  unless other.class == self.class
		raise TypeError,
		  "cannot convert #{self.class} into #{other.class}"
	  end
      other.instance_variables.each do |name|
        instance_variable_set(name,
            other.instance_variable_get(name))
      end
	end
  end

This is, by the way, exactly what:

  a = {}
  b = []
  b.replace a

does. Yes, I think it should be that restrictive -- exact match only.
This isn't #become, it's #replace. This isn't typecasting, it's
replacing the internals of one object with those of another object OF
THE EXACT SAME KIND. (Granted, singleton objects tend to confuse things,
but this is closer to the behaviour of #dup than of #clone.) The
behaviour for this is relatively well-established by the #replace
implementations on the internal objects Array, Hash, and String.

> I'm not sure if there is a good general way to do this #replace with
> breaking encapsulation. Maybe using something in Marshal may help. Or
> what's the big deal about just having each class make its own
> #replace?

1. Marshal is extremely inefficient and it creates new objects, which is
   precisely the *opposite* of the desired behaviour from this (keep the
   same object ID).

2. There are certain concerns (such as Transaction::Simple) which are
   better served by a common #replace and an optional custom #replace as
   necessary.

There are other things that I want to do, but this is, I think,
relatively non-controversial when it's all said and done.

-austin
--
Austin Ziegler * halostatue / gmail.com
               * Alternate: austin / halostatue.ca