daremkd
daremkd

Reputation: 8424

Ruby, stack level too deep (SystemStackError)

I have the following code:

class BookPrice
  attr_accessor :price
  def initialize(price)
    @price = price
  end

  def price_in_cents
    Integer(price*100 + 0.5)
  end
end

b = BookPrice.new(2.20)
puts b.price_in_cents

This all works well and produces 220. But when I replace the second line attr_accessor :price with:

def price
  @price = price
end

I get stack level too deep (SystemStackError) error. What's going on? I know I can replace Integer(price*100 + 0.5) with @price instead of the method call price, but I want to keep it the way it is for OOP reasons. How can I make this code work the way it is without attr_accessor?

Upvotes: 28

Views: 92675

Answers (4)

stevec
stevec

Reputation: 52328

One general reason this can happen is if you have some method that calls itself recursively (i.e. calls itself inside itself, which causes an infinite loop).

That's the problem I had that led to the error message.

In your case that's what's happening here:

def price
  @price = price
end

Upvotes: 2

Maged Makled
Maged Makled

Reputation: 1986

read_attribute is what you are looking for

def price 
  @price = read_attribute(:price)
end

Upvotes: 1

Arup Rakshit
Arup Rakshit

Reputation: 118271

Your below code

def price
  @price = price # <~~ method name you just defined with `def` keyword.
end

Creates never stopable recursion,.

How can I make this code work the way it is without attr_accessor?

You need to write as

def price=(price)
  @price = price
end
def price
  @price 
end

Upvotes: 40

Translunar
Translunar

Reputation: 3816

You need to do:

@price = self.price

to differentiate between your object attribute price and your method parameter price.

Upvotes: 5

Related Questions