2

好的,所以每个人都知道大写的标识符在 Ruby 中被视为“常量”。

但是,可以为常量分配新值,因此以下工作

class A
  def self.hi; "hi"; end
end
class B
  def self.hi; "ho"; end
end
A.hi # => "hi"
B.hi # => "ho"
A = B
#  warning: already initialized constant A
# => B
A.hi # => "ho"

并且还分配给小写标识符的工作:

a = B
a.hi # => "ho"

但是,内部名称在所有情况下都设置为“B”,并且新标识符名称也仅引用“B”。

但是,如果标识符具有小写名称在技术上是可以的,那么为什么要限制类的内部名称呢?它不可能是恒定的,因为它不是恒定的;所以另一个原因可能是小写标识符具有不同的范围。但是然后:为什么不使用小写范围的类呢?

我想知道,因为解析器甚至允许使用 unicode 等格式的方法名称,所以对于类来说它受到更多限制似乎很奇怪。

4

2 回答 2

1

正如您所说,一个类的名称是它被分配给的第一个常量的名称。您只能将常量与class关键字一起使用,因为已决定该class关键字应仅用于创建命名类。

基本原理可能是允许局部变量会混淆使用,谁会使用class lowercase_class_name,不知道小写和大写标识符之间的区别,然后想知道为什么类名在任何地方都不可见(即为什么def foo() lowercase_class_name.new end不起作用)。

通过使用默认方式来创建特定于常量的类,以这种方式定义的类将在任何地方可见,并且至少建议与该名称关联的值不应更改(即,否则您会收到警告)。

知道自己在做什么的人仍然可以local_variable = Class.new { ... }在需要时做。

于 2010-01-03T15:02:55.560 回答
-1

解释器需要一种方法来确定它是类名还是当前类/模块的成员变量。

解释器必须在全局哈希表中查找类名,而成员变量在类哈希表中。局部变量是不同的,因为它们可以由解释器解析,根本不需要查找哈希表(它们优先于成员变量)。

解释器唯一知道标识符的就是字符。因此存在符号差异。这也是为什么全局变量前面有 $ 而类变量前面有 @ 字符的原因。为此,解释器必须搜索其他哈希表。

其他脚本语言也有类似的限制,例如 PHP 需要在每个变量前面加一个美元。

于 2010-01-03T05:39:36.067 回答