【问题标题】:what's difference between @ and @@ in a module?模块中的@ 和@@ 有什么区别?
【发布时间】:2023-03-28 10:15:01
【问题描述】:

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

我看不出两者有什么区别。

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

我一直在模块中使用@ 作为@@,最近我看到其他代码在模块中使用@@。然后我想我可能是用错了。

既然我们不能实例化一个模块,那么对于一个模块来说@和@@之间一定没有区别。我错了吗?

----------------------- 添加了以下内容 --------------------

为了回答一些关于cmets和posts的问题,我还测试了以下。

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

当您在类中包含模块时,模块类变量和类方法不会在类中定义。

【问题讨论】:

  • 我对 Ruby 还很陌生,但是为什么要定义一个返回实例变量的类/模块级别的方法呢?如果方法处理实例变量,不应该是实例方法,因此定义为“def foo”而不是“def self.foo”吗?
  • 不要使用类变量。最好甚至不学习学习它们。它们本质上是错误的,并且不提供任何你不能用实例变量做的事情。我真诚地希望它们从 Ruby 2.0 中删除
  • @JoshuaCheek:这将如何运作? Ruby 2.0 应该向后兼容 Ruby 1.9,那么您如何建议在不破坏向后兼容性的情况下删除现有功能?
  • @JörgWMittag 不知道他们正在计划向后兼容。我希望他们能借此机会删除和添加。事实上,如果您向后兼容,为什么还要制作 2.0?那不只是 1.10 或 1.11 吗?
  • 他们现在无法制作 1.10,原因与上次无法制作 1.10 的原因相同:因为太多脚本依赖于 RUBY_VERSION > '1.6'(或类似的东西)才能工作。近十年来,神话般的“Ruby 2.0”的特性集已经被广泛讨论,以任何不同的版本号发布该特性集都会导致巨大的混乱。在 1.9 开发周期中已经记录了 2.0 将向后兼容。 Matz 明确表示,他希望在 1.9 中最大化破坏,以便在 2.0 中最小化破坏。

标签: ruby


【解决方案1】:

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

module A
  @@a = 5
end

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

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

module A
  @a = 5
end

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

【讨论】:

  • 这是一个很好的答案。所以 @@ 可以从包含模块的实例中访问。但是@不可访问,对吧?
  • 是的,您还可以注意到继承的相同行为,例如父/子类可以共享@@,而不是@(如果我们谈论的是类的范围,而不是它的对象)。
【解决方案2】:

@@ 指类变量,@ 指实例变量。虽然将它与模块一起使用会产生很大的不同。当您包含一个模块时,您将类方法添加到您的类,同时将添加实例方法扩展到您的类

下面是一篇不错的文章

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-04-10
      • 2013-01-11
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多