Hi --

On Thu, 6 Oct 2005, Kevin Brown wrote:

> On Wednesday 05 October 2005 18:41, waterbowl / gmail.com wrote:
>> Is it possible to write a method in Ruby that acts like pop does in
>> Lisp? Array#shift is an obvious candidate but there's a difference. For
>> example:
>>
>> Ruby:
>>
>> irb(main):001:0> x = [[:a, :b], :c]
>> => [[:a, :b], :c]
>> irb(main):002:0> y = x.first
>> => [:a, :b]
>> irb(main):003:0> y.shift
>> => :a
>> irb(main):004:0> y
>> => [:b]
>> irb(main):005:0> x
>> => [[:b], :c]
>> irb(main):006:0>
>>
>> Lisp:
>>
>> [2]> (setq x '((a b) c))
>> ((A B) C)
>> [3]> (setq y (car x))
>> (A B)
>> [4]> (pop y)
>> A
>> [5]> y
>> (B)
>> [6]> x
>> ((A B) C)
>>
>> y.shift causes x to be modified whereas Lisp's (pop y) does not modify
>> x.
>
> You could force a deep copy:
>
> y = Marshal.load(Marshal.dump(x.first))
>
>> If Ruby had macros we could use them to define pop. Given that it does
>> not, is there some other way to define a method to do this?
>
> It's getting modified because both are just references to the original.
> (shallow copy)

Actually there's no copying at all in the original example -- it's
just a reference to the same object.  dup will give you a shallow copy
(i.e., a different array, but containing the same objects).


David

-- 
David A. Black
dblack / wobblini.net