为什么这些方法不能解决?

时间:2011-05-30 03:24:14

标签: ruby

鉴于此代码:

class Something
  attr_accessor :my_variable

  def initialize
    @my_variable = 0
  end

  def foo
    my_variable = my_variable + 3
  end
end

s = Something.new
s.foo

我收到此错误:

test.rb:9:in `foo': undefined method `+' for nil:NilClass (NoMethodError)
    from test.rb:14:in `<main>'

如果attr_accessor创建了一个名为my_variable(和.. =)的方法,为什么foo找不到该方法?如果我将其更改为self.my_variable,它会起作用,但为什么呢? self不是默认收件人吗?

4 个答案:

答案 0 :(得分:7)

你没有在那里调用方法,实际上你正在引用你正在定义的同一个变量!这是Ruby中的一个小问题。

如果您引用并设置实例变量,那会更好:

@my_variable = @my_variable + 3

或更短:

@my_variable += 3

或者你可以调用setter方法,就像你找到的那样(和Jits pointed):

self.my_variable += 3

最后一个将调用my_variable=定义的attr_accessor方法,其他两个方法只会修改变量。如果你这样做,你可以覆盖my_variable=来做与传入的值不同的东西:

def my_variable=(value)
  # do something here
  @my_variable = value
end

<强>奖金

或者你可以通过传递一组空参数来显式调用方法:

my_variable = my_variable() + 3

这不是“红宝石之路”,但是如果你有一个同名的局部变量,你仍然可以通过这种方式调用方法,这仍然很有趣。

答案 1 :(得分:5)

my_variable = my_variable + 3

...是一个局部变量赋值,它优先。

因此需要self - 以便将其范围扩展到对象。

答案 2 :(得分:3)

如果您在my_variable中执行了foo,那就是分配给本地变量 my_variable,而不是调用方法my_variable=

要根据需要分配值,您需要在发现时使用self

另请参阅此问题:Why do ruby setters need “self.” qualification within the class?

答案 3 :(得分:2)

我认为在这种情况下,变量的范围仅在函数内,除非您使用self.的{​​{1}}作为前缀。