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) irb(main):001:0> x = [[:a, :b], :c] => [[:a, :b], :c] irb(main):002:0> y = Marshal.load(Marshal.dump(x.first)) => [:a, :b] irb(main):003:0> y.shift => :a irb(main):004:0> y => [:b] irb(main):005:0> x => [[:a, :b], :c]