初始化的类成员变量在ruby中丢失值

时间:2013-10-19 18:20:33

标签: ruby

这是我做ruby的第三天,我遇到了这个问题:

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方法时该值会丢失。

我找不到其他人在线面对此问题。

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

3 个答案:

答案 0 :(得分:3)

a_var = x中,a_var被视为本地变量,因为它lacks the appropriate @ sigil并且出现在作业的左侧。因此,赋值在initialize方法的范围之外没有任何影响。

让我们看看一些不同但相似的案例:

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 :(得分:1)

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

更正后的代码:

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

答案 2 :(得分:1)

您只能在实例内部的方法之间携带实例(在它们之前有@)变量。 本地变量(前面没有符号)仅限于他们的方法或其他匿名附件(块等)

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

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