waterbowl / gmail.com said:
> 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:

Here's one way.  As someone else pointed out, there is a fundamental
difference between Ruby's arrays and Lisp's lists.  But given that, here
is a way to mimic the 'macro nature' of lisp's pop function (i.e. changing
the value of "y" from withing pop):

------------------------------------------------------

require 'test/unit'

# (setq x '((a b) c)) ; => ((A B) C)
# (setq y (car x))    ; => (A B)
# (pop y)             ; => A
# y                   ; => (B)
# x                   ; => ((A B) C)

class TestPop < Test::Unit::TestCase
  def test_pop
    x = [[:a, :b], :c]
    y = x.first

    assert_equal :a, pop {:y}

    assert_equal x, [[:a, :b], :c]
    assert_equal y, [:b]
  end
end

def pop(&block)
  var = block.call.to_s
  value = eval var, block
  setter = eval "proc { |value| #{var} = value }", block
  setter.call(value[1..-1])
  value.first
end


-- 
-- Jim Weirich     jim / weirichhouse.org    http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)