1

This is my main code. I am using rspec

require_relative "rpn_calculator"
describe RPNCalculator do
let(:calculator) {RPNCalculator.new}

it "adds two numbers" do
    calculator.push(1)
    calculator.push(3)
    calculator.plus
    expect(calculator.value).to eq 4
end

And this is my code in rpn_calculator

class RPNCalculator
@arr=[]
@ans=0
def push(val)
    @arr.push(val)
end
def plus
    while @arr.size>=1 do
        @ans=@[email protected]
    end
end
def value
    return @ans
end
end

And this is the error I am getting

RPNCalculator adds two numbers Failure/Error: calculator.push(1) NoMethodError: undefined method push' for nil:NilClass # ./rpn_calculator.rb:5:inpush' # ./spec.rb:7:in `block (2 levels) in '

But I think Push is a method for arrays

1 Answer 1

3

Those variables needs to be in initialize method:

class RPNCalculator
  def initialize
    @arr=[]
    @ans=0    
  end

  def push(val)
    @arr.push(val)
  end

  def plus
    while @arr.size>=1 do
      @ans=@[email protected]
    end
  end

  def value
    return @ans
  end
end

Explanation: initialize is private by default and is called as obj.send(:initialize, *args, &block) in Class#new method's implementation. Have a look at this answer for more information.

So, when you define an initialize method in your class to override or overwrite its implementation according to yours. Ruby will invoke and run your defined version of initialize method instead. Since, initialize is an instance method, whatever variables(variables with @) you have defined, will also be shared/accessible in other instance methods, in this case: @arr, and @ans. In your case they are class variables and not instance variables, and that's why @arr is nil in push instance method and @arr in plus instance method.

It would be perfectly fine if you do not want to put those variables in initialize and instead write them in your own defined method, let's call it initialize_variables:

class RPNCalculator
  def initialize_variables
    @arr=[]
    @ans=0    
  end

  ....
  ..
end

It's just that now you have to always call initialize_variables after initializing the class object. Which is an extra overhead in your code, and not considered as a good practice. Hence use initialize method instead.

Sign up to request clarification or add additional context in comments.

3 Comments

Oh thanx this worked :).But can you tell me why they need to be in the initialize method?
@Legendary_Hunter : I added the explanation for more clarification why initialize method is needed.
@Legendary_Hunter as for what happens when you define those variables outside of initialize (or any method definition), they are defined on the object that is currently self - the class RPNCalculator - rather than instances of the class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.