Ruby 区别于;甲级;B类“;及;A类::B类“;
这两者之间的区别是什么:Ruby 区别于;甲级;B类“;及;A类::B类“;,ruby,Ruby,这两者之间的区别是什么: class A class B end end 及 更新:这两种方法并不完全相同 在第二种方法中,B无法访问A中定义的常量 此外,正如Matheus Moreira正确指出的那样,在第二种方法中,A必须先定义,然后才能定义A::B 还有什么区别呢?它们是一样的。它们是书写同一事物的不同方式。第一种是编写它的简单方法,但通常情况下,一旦类/模块变大,就很难跟踪嵌套。使用第二种方式,可以避免在外观上嵌套。两种不同的方式来表达相同的内容。这是因为类B是一个内部类或
class A
class B
end
end
及
更新:这两种方法并不完全相同 在第二种方法中,
B
无法访问A
中定义的常量
此外,正如Matheus Moreira正确指出的那样,在第二种方法中,A
必须先定义,然后才能定义A::B
还有什么区别呢?它们是一样的。它们是书写同一事物的不同方式。第一种是编写它的简单方法,但通常情况下,一旦类/模块变大,就很难跟踪嵌套。使用第二种方式,可以避免在外观上嵌套。两种不同的方式来表达相同的内容。这是因为类B是一个内部类或嵌套类,只能通过A接口访问
> class A
.. def say
.... "In A"
....end
..
.. class B
.... def say
...... "In B"
......end
....end
..end
=> nil
> A.new.say
=> "In A"
> B.new.say
=> #<NameError: uninitialized constant B>
> A::B.new.say
=> "In B"
>A类
.. 戴夫说
.... “在一个
……结束
..
.. B类
.... 戴夫说
...... “在B中”
……结束
……结束
……结束
=>零
>新的
=>“在A中”
>新的
=> #
>A::B.新的。是的
=>“在B中”
对
> class A
.. def say
.... "In A"
....end
..end
=> nil
> class A::B
.. def say
.... "In B"
....end
..end
=> nil
> A.new.say
=> "In A"
> B.new.say
=> #<NameError: uninitialized constant B>
> A::B.new.say
=> "In B"
>
>A类
.. 戴夫说
.... “在一个
……结束
……结束
=>零
>A类::B类
.. 戴夫说
.... “在B中”
……结束
……结束
=>零
>新的
=>“在A中”
>新的
=> #
>A::B.新的。是的
=>“在B中”
>
在Ruby中,模块和类分别是和类的实例。它们的名称是从分配给它们的常量派生出来的。当你写作时:
class A::B
# ...
end
class A
class B
# ...
end
end
你实际上是在写:
A::B ||= Class.new do
# ...
end
这是有效的常量赋值语法,并假设A
常量已正确初始化,并且它引用了模块
或类
例如,考虑如何定义类:
class A
# ...
end
实际发生的情况是:
Object::A ||= Class.new do
# ...
end
现在,当你写作时:
class A::B
# ...
end
class A
class B
# ...
end
end
实际发生的情况如下所示:
(Object::A ||= Class.new).class_eval do
(A::B ||= Class.new).class_eval do
# ...
end
end
以下是正在发生的事情,顺序如下:
类
实例被分配到对象
的常量,除非它已经初始化
类
实例被分配到A
的B
常量,除非它已经初始化a
的常量。比较:
class A
MESSAGE = "I'm here!"
end
# Scope of Object
class A::B
# Scope of B
puts MESSAGE # NameError: uninitialized constant A::B::MESSAGE
end
# Scope of Object
class A
# Scope of A
class B
# Scope of B
puts MESSAGE # I'm here!
end
end
据介绍,Ruby核心团队将“当前类”称为cref
。不幸的是,作者没有详细说明,但正如他所指出的,它与self
的上下文是分离的
,cref是一个链表,表示某个时间点的模块嵌套 当前的
cref
用于常量和类变量查找和
对于def
、undef
和alias
正如其他人所说,它们是表达同一事物的不同方式 然而,有一个微妙的区别。在编写
class A::B
时,假设A
类已经定义。如果没有,您将得到一个namererror
,而B
将根本不被定义
正确编写嵌套模块:
class A
class B
end
end
在尝试定义
B
之前,确保A
类存在。我已更新问题,以显示这两种方法不相同。我已更新问题,以显示这两种方法不相同。@nickh,您无需编辑问题以包含答案。你应该这样做。对常数是如何定义的很好的解释。谢谢当使用class A::B
定义B
时,您知道为什么B
不能访问A
中的常量吗?解释得很好。这是很多Ruby开发人员都不会花时间学习的重要内容。谢谢我已经更新了这个问题,以表明这两种方法是不同的。@nickh我认为这些差异是微不足道的,是预先假定的,所以我没有提到它们。指出它们与说“嗯,字符串class B
看起来与class A::B
不同”没有太大区别,但您没有提到这一点。