RPN Calculator: use of @stack variable

I am having quite a bit of trouble passing the last spec on RPN calculator. I looked at the solution and realized that they used an instance variable @stack throughout the solution, where I had used class inheritance instead, and used self everywhere they used @stack. I’m wondering if I the only way to solve this problem is to go back and refactor my code to use the @stack variable, or if it’s OK to continue the way that I set it up. Here’s where I’m at:

class RPNCalculator < Array
OPERATORS = ["+", “-”, “*”, “/”]

def value
@value = self.last
end

def plus
  perform_operation(:+)
end

def minus
  perform_operation(:-)
end

def divide
  perform_operation(:/)
end

def times
  perform_operation(:*)
end

def perform_operation(operand_sym)
  raise "calculator is empty" if self.count < 2
  second_num = self.pop.to_f
  first_num = self.pop.to_f

  case operand_sym
  when :+
    result = first_num + second_num
    self << result
  when :-
    result = first_num - second_num
    self << result
  when :*
    result = first_num * second_num
    self << result
  when :/
    result = first_num / second_num
    self << result
  end
end

def tokens(string)
  string.split.map do |el|
    if OPERATORS.include?(el)
      el.to_sym
    else
      el.to_i
    end
  end
end

def evaluate(string)
  result = RPNCalculator.new
  list = tokens(string)

  list.each.with_index do |el, i|
    # iterate through arr until I reach a symbol. Then do that operation
    # on the two elements that precede it.
    if i == list.length - 1
      return result[0]
    elsif el.class == Integer
      result << el
    elsif el.class == Symbol
      result.perform_operation(el)
    end
  end
end

end

I also solved it by inheriting from Array so it’s definitely possible. What’s the error/failure you’re getting?

When I run my evaluate method it gives the “calculator is empty” error. I thought adding the “if i == list.length - 1” part of the if statement would prevent it from calling perform_operation on the result when it has less than 2 elements, thus preventing the error, but that didn’t work and I’m not sure why.

Whenever you are check if something is from a certain class don’t ever do
thing.class == SomeClass
instead use
thing.is_a?(SomeClass)
because is_a? will work if the object is an instance of a class that inherits from SomeClass. == will not work for subclass objects. is_a? is just a built in method that you can use on any object.

I don’t think you should do this

if i == list.length - 1
      return result[0]

If you do that I think you’ll always be skipping the last operation. Instead just return result[0] or result.value at the bottom. Let the loop finish completely.