模块中@和@@的区别是什么?

时间:2012-09-10 19:19:25

标签: ruby

假设包含一个模块,而不是扩展,模块实例变量和类变量之间有什么区别?

我认为两者之间没有任何区别。

module M
  @foo = 1
  def self.foo
    @foo
  end
end
p M.foo

module M
  @@foo = 1
  def self.foo
    @@foo
  end
end
p M.foo

我一直在模块中使用@ as @@,我最近看到其他代码在模块中使用@@。然后我以为我可能错误地使用它了。

由于我们无法实例化模块,因此模块的@和@@之间必须没有区别。我错了吗?

-----------------------添加以下内容-------------------- < / p>

为了回答有关评论和帖子的一些问题,我还测试了以下内容。

module M
  @foo = 1
  def self.bar
    :bar
  end

  def baz
    :baz
  end
end

class C
  include M
end

p [:M_instance_variabies, M.instance_variables] # [@foo]
p [:M_bar, M.bar] # :bar

c = C.new
p c.instance_variables
p [:c_instance_variabies, c.instance_variables] # []
p [:c_baz, c.baz] :baz
p [:c_bar, c.bar] # undefined method

在类中包含模块时,模块类变量和类方法未在类中定义。

3 个答案:

答案 0 :(得分:5)

类变量可以在包含这些模块的模块和类之间共享。

module A
  @@a = 5
end

class B
  include A
  puts @@a # => 5
end

同时,实例变量属于self。当您将模块A包含到类B中时,self的{​​{1}}对象与B的A对象不同,因此您将无法在它们之间共享实例变量。

self

答案 1 :(得分:3)

@@指的是类变量,@指的是实例变量。使用它与模块有很大的不同。当您包含一个模块时,您可以将类方法添加到您的类中,同时将实例方法扩展到您的类

以下是关于此

的好文章

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

答案 2 :(得分:0)

我发现this SO post讨论了如何在模块中创建类变量,“本机支持它们。” One commenter甚至说“类变量”这个名称具有误导性,因为类只是具有一些额外权限的模块。

我确信几乎所有关于类变量的文章都认为它们是邪恶的并且不惜一切代价避免它们,因为你可能会遇到奇怪的继承问题。