# frozen_string_literal: true

# A generic stack: a class that mixes in Enumerable, uses blocks,
# and raises a custom error.
class Stack
  include Enumerable

  class EmptyError < StandardError; end

  def initialize
    @items = []
  end

  def push(item)
    @items.push(item)
    self
  end

  def pop
    raise EmptyError, "stack is empty" if @items.empty?

    @items.pop
  end

  def each(&block)
    @items.reverse_each(&block)
  end

  def size
    @items.size
  end
end

stack = Stack.new
%w[alpha beta gamma].each { |word| stack.push(word) }

puts "top: #{stack.pop}"
puts "remaining: #{stack.map(&:upcase).join(', ')}"
puts "size: #{stack.size}"
