0

这是我做 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

我在网上找不到其他人面临这个问题。

有人可以指出我的错误吗?

4

3 回答 3

3

In a_var = x,a_var被视为局部变量,因为它缺少适当的@符号,并且出现在 assignment 的左侧。因此,赋值在初始化方法的范围之外没有任何影响。

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

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使用实例变量@x,因此@a_var直接使用(即用于赋值)也可以。

于 2013-10-19T18:22:39.990 回答
1

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

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

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

于 2013-10-19T18:36:43.027 回答
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
于 2013-10-19T18:22:34.217 回答