Ruby 类名大写的真正原因是什么?
好吧,大家都知道大写标识符在 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 等形式的方法名称,所以对于类来说它受到如此多的限制似乎很奇怪。
Ok, so everyone knows that capitalised identifiers are seen to be ‘constant’ in Ruby.
However, it is possible to assign a new value to constants, so the following works
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"
and also does assigning to a lowercase identifier work:
a = B
a.hi # => "ho"
However, the internal name is set to ‘B’ in all cases and the new identifier names are also only referencing ‘B’.
But if it’s technically okay for the identifier to have a lowercase name, why is this restriction on the internal name for the class? It can’t be that it needs to be constant, because it isn’t constant; so the other reason could be that lowercase identifiers have a different scope. But then: why not having a class with lowercase scope?
I’m wondering because the parser even allows for method names in unicode and such, so it seems strange that for classes it’s so much more restricted.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如您所说,类的名称是它被分配到的第一个常量的名称。您只能将常量与
class
关键字一起使用,因为已决定class
关键字只能用于创建命名类。理由可能是允许局部变量会混淆用户,他们会使用
class lowercase_class_name
,不知道小写和大写标识符之间的区别,然后想知道为什么类名不是到处可见(即为什么< code>def foo() lowercase_class_name.new end 不起作用)。通过采用默认方式创建特定于常量的类,以这种方式定义的类将在任何地方都可见,并且至少建议与该名称关联的值不应更改(即,否则您会收到警告)。
知道自己在做什么的人仍然可以在需要时执行
local_variable = Class.new { ... }
。As you said, the name of a class is that of the first constant it has been assigned to. You can only use constants with the
class
keyword because it has been decided that theclass
keyword should only be used to create named classes.The rationale probably being that allowing local variables would confuse uses, who would use
class lowercase_class_name
, not knowing the difference between lower case and upper case identifiers and then wonder why the classname was not visible everywhere (i.e. whydef foo() lowercase_class_name.new end
did not work).By making the default way to create classes specific to constants, classes defined this way will be visible everywhere and there is at least a suggestion that the value associated with that name should not change (i.e. you get a warning otherwise).
People who know what they're doing can still do
local_variable = Class.new { ... }
if they need to.解释器需要一种方法来确定它是类名还是当前类/模块的成员变量。
解释器必须在全局哈希表中查找类名,而成员变量位于类哈希表中。局部变量是不同的,因为它们可以由解释器解析而根本不需要查找哈希表(它们优先于成员变量)。
解释器对标识符唯一了解的是字符。因此存在符号上的差异。这也是全局变量前面有 $ 和类变量前面有 @ 字符的原因。为此,解释器必须搜索其他哈希表。
其他脚本语言也有类似的限制,例如 PHP 需要在每个变量前面加一个美元。
The interpreter needs one way to find out if it is a Class name or a member variable of the current class/module.
The interpreter has to lookup class names in a global hash table while the member variables are in the class hash table. Local variables are different as they can be resolved by the interpreter without looking up hash tables at all (they have precedence over member variables).
And the only thing the interpreter knows about an identifier are the characters. Therefore there is the notational difference. Thats also the reason why global variables have a preceding $ and class variables an @ character. For this the interpreter has other hash tables it has to search.
Other script languages have similar restrictions, for example PHP needs a dollar in front of each variable.