#!/usr/bin/ruby -w

class Module
  def abstract(*ids)
    for id in ids
      name = id.id2name # 1.4.x specific
      class_eval %Q{
        def #{name}(*a)  
          raise NotImplementedError, "#{name} not implemented"
        end
      }
    end
  end

  alias implements include
end

module Stack
  abstract :push, :pop
end

class ConcreteStack; implements Stack
  def initialize
    @stack = []
  end

  def push e
    @stack.push(e)
  end

  def pop
    @stack.pop
  end
end

class FooStack; implements Stack
end

s = ConcreteStack.new
s.push("cs")
p s.pop                                 # -> "cs"

s = FooStack.new
s.push("fs")                            # -> push not implemented
