在Ruby中引用属性

时间:2013-11-21 12:54:08

标签: ruby

class Account
    attr_accessor :balance

    def initialize (amount=0)
        self.balance = amount
    end

    def -(x)
        self.balance -= x
    end

    def +(x)
        self.balance += x
    end 

    def to_s
        puts "Balance is #{self.balance} !!!!!!!!!"
    end


end

acc = Account.new(20)
acc -=5

有人可以解释为什么它可以写:puts acc(结果渲染15)但是这一行: puts acc.balance不起作用(它表示undefined method balance,但它不是方法,应该被视为属性/属性) 提前致谢

4 个答案:

答案 0 :(得分:4)

acc -= 5相当于acc = acc - 5

acc - 515(按Account#-方法); acc = acc - 5acc = 15类似。

现在acc是Fixnum对象。


如何实施+-如何?

def -(x)
    Account.new(self.balance - x)
end

def +(x)
    Account.new(self.balance + x)
end 

答案 1 :(得分:2)

您的错误来源是

acc -= 5

它将减法方法的结果(返回值)赋给acc变量,而这个结果是Fixnum实例,它没有定义balance方法。

如果您希望+-方法返回Account个实例,则需要指定:

def +(x)
  self.balance += x
  self
end

BTW,Ruby ARE方法中的访问器。

答案 2 :(得分:1)

您想要编辑两种方法以使+=-=正常工作,以便它们返回对象:

def -(x)
    self.balance -= x
    self
end

def +(x)
    self.balance += x
    self
end

这样,它重新分配给自己的对象。

答案 3 :(得分:1)

哎呀,这个问题有很多问题。我无法解释所有问题,但让我们看看我能走多远:

首先,您重新定义了#+#-方法,为它们提供了您期望从#+=#-=获得的语义。鉴于此:如果您在示例中使用acc-5(而不是acc-=5),行为接近您的预期,irb将显示15,因为这是你的#-方法(其副作用也是减去5的余额)。

但是,当您在示例中调用#-=时,ruby解释器最终将方法结果Fixnum 15分配给您的acc - 变量。当您尝试访问恰好在NoMethodError: undefined method 'balance' for 15:Fixnum课程中定义的#balance时,这会向您显示错误消息Account

您的#-方法应返回Account - 对象,而不是更改对象的现有状态并将结果作为Fixnum返回。有关如何重新定义运算符的示例,请参阅http://ruby.about.com/od/oo/ss/Overloading-Operators.htm。我理解这会以某种方式违背您的目的,因为您希望使用#-=来修改对象,但它只能在Ruby中创建另一个Account - 实例,因为您无法重新定义直接#-=(请参阅上面的链接)。

当然,您可以自由定义#withdraw - 方法来获取所需的语义。