在Ruby中的类范围声明“实例”变量的缺点是什么?

时间:2013-02-05 19:35:02

标签: ruby scope instance-variables

我几乎从未在Ruby代码中看到这一点,但它似乎是有效的:

class Foo
  @bar = "bar"

  def self.print_bar
    puts @bar
  end
end

我对上述内容的解释@barFoo的实例变量,它是Class的单例(?)实例。

这似乎与类变量(例如@@baz)不同,它们可以在类范围以及实例范围访问。

如果有的话,上述代码段的代码是什么?或者这是完全合理的代码吗?

4 个答案:

答案 0 :(得分:5)

是的,这完全有效。它也被广泛使用,并且通常推荐使用具有非常大范围的类变量(类,类的所有实例,所有子类,所有子类的所有实例,......)。

没有缺点。类是对象。对象可以包含实例变量。什么都没有。 Ruby的对象模型真的比人们更简单 ,甚至Ruby教程的作者都会让你想要相信。

答案 1 :(得分:2)

一个潜在的缺点是@bar的子类无法使用Foo

class Parent
  @bar = 3
  def self.print_bar
    puts @bar # nil
  end
end

class Child < Parent

end

Parent.print_bar # 3
Child.print_bar # nil

答案 2 :(得分:2)

代码有效。您正在使用类实例变量。正如Jörg所说,他们通常比班级变量更受欢迎。他们可以完成相同的目的,但类变量有一些陷阱。有关类变量与类实例变量的优缺点的详细讨论,请参阅Class and Instance Variables In Ruby

使用类实例变量的一个缺点是它们看起来与“普通”实例变量相同。这可以让新的Ruby程序员措手不及。下面的self.print_barprint_bar方法指向不同的@bar实例变量。

class Foo
  @bar = "bar"

  def initialize
    @bar = "foo"
  end

  def self.print_bar
    puts @bar #=> "bar"
  end

  def print_bar
    puts @bar #=> "foo"
  end
end

我认为这不是一个很大的缺点,但你问:)

类实例变量不可用于子类的事实不一定是缺点。这完全取决于您希望程序的行为方式。

答案 3 :(得分:1)

未初始化的实例变量将具有nil值,而未初始化的类变量将抛出错误。正如其他人所补充的那样,类变量可用于子类。

这是一个链接,讨论我发现有用的两个:

http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/