【发布时间】: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