Ruby在accessor方法中使用self会导致SystemStackError

时间:2016-12-30 13:14:38

标签: ruby

我没有得到这个,当我尝试在代码下运行时,我正在

employee.rb:55:在`hourly_wage =':堆栈级别太深(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

在我使用setter方法中的this关键字的Java中,这基本上是不一样的吗?

如果我用def替换了def,那么一切正常。

def hourly_wage=(hourly_wage)
        @hourly_wage = hourly_wage
    end

抱歉,刚刚开始选择Ruby

2 个答案:

答案 0 :(得分:3)

您可以想象hourly_wage=是方法名称

您的代码:

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

如果您将名称hourly_wage=替换为assign,则会变为:

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

你递归地称自己没有断点,所以它引发了stack level too deep例外。

答案 1 :(得分:1)

您在hourly_wage=中递归调用hourly_wage=,没有终止条件,因此您无限递归。由于Ruby没有Proper Tail-Recursion,你有时会耗尽堆栈空间。

  

这在Java中基本相同,我在setter方法中使用this关键字?

是的,它与这个等效的Java代码完全相同:

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

这将产生完全相同的结果:堆栈溢出。

  

如果我用def替换了def,那么一切正常。

def hourly_wage=(hourly_wage)
  @hourly_wage = hourly_wage
end

这是完全不同的东西。在这里,您不是递归调用hourly_wage=而是简单地分配给实例变量(&#34;字段&#34;在Java术语中)。