On 11/16/05, Mauricio FernŠŌdez <mfp / acm.org> wrote:
> On Thu, Nov 17, 2005 at 02:51:47AM +0900, Austin Ziegler wrote:
>> On the Sydney list, Daniel Berger has been asking about a generic
>> Object#replace call to work similarly to Hash#replace,
>> String#replace, and Array#replace. I see no reason that this could
>> not be implemented for all objects. At a simplistic level, this is:

>>     class Object
>>       def replace(other)
>>         other.instance_variables.each do |name|
>>           instance_variable_set(name, other.instance_variable_get(name))
>>         end
>>       end
>>     end
> What about singleton methods?
> Will Sydney relax the rebinding rules?

Why?

  a = Hash.new { |h, k| raise "I am default proc for a" }
  b = Hash.new { |h, k| raise "I am default proc for b" }

  class << b
    def x; puts "I am b.x"; end
  end

  b[:x] = "foo"
  a.replace b
  puts b[:x].object_id
  puts a[:x].object_id
  a.x   # => NoMethodError
  a[:y] # => RuntimeError: ...default proc for b

Singleton methods aren't transferred with Hash#replace now. Why should
they be with Object#replace?

On 11/16/05, Ara.T.Howard <ara.t.howard / noaa.gov> wrote:
[...]
>    class SpecialFile < ::File
>    end
>
>    a = SpecialFile::new '4.txt', 'w'
>    b = SpecialFile::new '2.txt', 'w'
>
>    b.replace a
>
>    a.close
>
>    b << 42 # exception!
>
> i see where you are coming from, but wouldn't this more accurately be called
> something like Object#refer since all instance vars will then be shared?

It *is* sharing, but it's not just a reference. Typically, when I call
#replace, I "forget" about the item that I used to replace the original
value. However, I would suggest that File (well IO, actually) have
something *equivalent* to the following:

  class IO
    def replace; end
    remove_method :replace
  end

The blank define is done because Module.remove_method does not allow you
to remove a method from a class that has never had it defined in the
first place.

On 11/16/05, David A. Black <dblack / wobblini.net> wrote:
> On Thu, 17 Nov 2005, Trans wrote:
[...] (in response to Ara)
>>  class Object
>>      def replace(other)
>>        other.instance_variables.each do |name|
>>          o = other.instance_variable_get(name)
>>          if o.respond_to? :clone
>>            instance_variable_set(name, o.clone)
>>          end
>>        end
>>      end
>>    end
>
> How does instance variable duplication qualify as the general meaning
> of "replace"? It's not even part of the existing replace methods.

It doesn't and it explicitly breaks what I wanted -- keeping the same
#object_id. I'll freely admit that #replace is *dangerous*, but under
controlled circumstances, it can be better and more efficient (at least
memory-wise) than other methods.

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