2013-10-19 78 views
0

这是我第三天做的红宝石和我坚持这个问题:初始化类的成员变量失去价值红宝石

2.0.0-p0 :001 > class SomeClass 
2.0.0-p0 :002?> attr_accessor:a_var 
2.0.0-p0 :003?> def initialize 
2.0.0-p0 :004?>  a_var = Hash.new 
2.0.0-p0 :005?>  puts "Initialized #{a_var.class}" 
2.0.0-p0 :006?>  end 
2.0.0-p0 :007?> def a_fun 
2.0.0-p0 :008?>  puts "Initialized #{a_var.class}" 
2.0.0-p0 :009?>  end 
2.0.0-p0 :010?> end 
=> nil 
2.0.0-p0 :011 > some_obj = SomeClass.new 
Initialized Hash 
=> #<SomeClass:0x007f9d1d809118> 
2.0.0-p0 :012 > some_obj.a_fun 
Initialized NilClass 
=> nil 
2.0.0-p0 :013 > 

正如你所看到的,成员变量a_var被里面的initialize方法初始化,但是当调用a_fun方法时,该值将丢失。

我在网上找不到其他人。

有人能请我指出我的错误吗?

+0

谢谢。这确实是一个愚蠢的错误。 –

回答

3

a_var = xa_var是因为它lacks the appropriate @ sigil和它在左手侧出现在赋值视为本地变量。因此,赋值不在初始化方法的范围之外。

让我们来看看一些不同,但类似的情况:

a_var = x  # assign to local/lexical variable 
self.a_var = x # invoke a_var= method ("setter") 
a_var   # access local variable if it exists in scope 
       # OR invoke self.a_var method ("getter") 
@a_var = x  # assign to instance variable 

因为attr_accessor时,我怀疑下面需要..

def initialize 
    self.a_var = Hash.new 
    .. 
end 

..和离开每隔a_var访问相同的(请参阅上面的规则表)。

现在,作为“众所周知的”实现细节,attr_accessor :x uses the instance variable @x internally,因此直接使用@a_var(即用于分配)也可以工作。

1

在您的#initialize方法中将此a_var = Hash.new更改为@a_var = Hash.new

更正代码:

class SomeClass 
    attr_accessor:a_var 
    def initialize 
    @a_var = Hash.new 
    puts "Initialized #{a_var.class}" 
    end 
    def a_fun 
    puts "Initialized #{a_var.class}" 
    end 
end 
some_obj = SomeClass.new 
some_obj.a_fun 
# >> Initialized Hash 
# >> Initialized Hash 
1

您只能在实例内部从方法到方法执行实例(拥有@之前的变量)变量。 局部变量(面前有没有符号),但仅限于他们的方法或其他匿名外壳(块等)

attr_accessor访问实例变量。不是局部变量。

而你的ruby变量命名需要一些工作。尽量让你的变量名称与你所做的相匹配。即在这种情况下,您只是试图发现红宝石结构的抽象属性。尝试使用@x & @y所以我们其他人不会被你的难以理解的命名方案抛出