0
votes

I don't get this, when I try to run below code, I am getting

employee.rb:55:in `hourly_wage=': stack level too deep (SystemStackError)

class HourlyEmployee < Employee
    attr_reader :hourly_wage, :hours_per_week

    def hourly_wage=(hourly_wage)
        self.hourly_wage = hourly_wage
    end

    def hours_per_week=(hours_per_week)
        self.hours_per_week = hours_per_week
    end

    def print_pay_stub
        print_name
        pay_for_period = (hourly_wage) * (hours_per_week) * 2
        formatted_pay = format("$%.2f", pay_for_period)
        puts "Pay for this period: #{formatted_pay}"
    end
end

Isn't this basically the same in Java where I use the this keyword in the setter method?

If I replaced the def with then everything works fine.

def hourly_wage=(hourly_wage)
        @hourly_wage = hourly_wage
    end

Sorry, just started picking up Ruby

2
in your case you dont need to implement def hourly_wage= and def hours_per_week=. You can simly change attr_reader :hourly_wage, :hours_per_week to attr_accessor :hourly_wage, :hours_per_week - sig
@sig sorry..forgot to mention that there will be validations there..I just remove it for clarity. - Mark Estrada

2 Answers

3
votes

you can imagine that hourly_wage= is a method name

your code:

def hourly_wage=(hourly_wage)
  self.hourly_wage = hourly_wage
end

if you replace the name hourly_wage= with assign, it'll become:

def assign(hourly_wage)
  self.assign(hourly_wage)
end

you recursively call yourself without a break-point, so it raise stack level too deep exception.

0
votes

You are recursively calling hourly_wage= in hourly_wage=, with no termination condition, so you are recursing infinitely. Since Ruby does not have Proper Tail-Recursion, you will at some time run out of stack space.

Isn't this basically the same in Java where I use the this keyword in the setter method?

Yes, it is exactly the same as this equivalent Java code:

void setHourlyWage(BigDecimal hourlyWage) {
  this.setHourlyWage(hourlyWage);
}

This will have the exact same result: a stack overflow.

If I replaced the def with then everything works fine.

def hourly_wage=(hourly_wage)
  @hourly_wage = hourly_wage
end

This is something completely different. Here you are not recursively calling hourly_wage= but instead simply assigning to an instance variable ("field" in Java jargon).