def self.get(server)
return unless server
server = server.to_s
if klass = @handlers[server]
obj = Object
klass.split("::").each { |x| obj = obj.const_get(x) }
obj
else
try_require('rack/handler', server)
const_get(server)
end
end
在上面的code中,const_get用于在此行上检索某种命名常量:
klass.split("::").each { |x| obj = obj.const_get(x) }
如果是这样,为什么'klass
'特别在这里使用?我读过klass
用于避免命名空间与“class
”关键字冲突。但在这个例子中,我没有看到可能发生冲突的地方。
答案 0 :(得分:5)
变量被称为klass而不是class,因为if class = @handlers[server]
和class.split("::")
都会导致语法错误,因为正如你所说,class是ruby中的关键字。
作为一项规则,局部变量不能像关键字一样命名(方法很好,但它们只能用显式接收器调用,这就是为什么你不能写class.name
而不是{{1 }})。
每次解析器在表达式的开头看到标记self.class.name
时,它都会将其解释为关键字。
编辑:澄清:问题不在于这里的类的使用是不明确的,而是你根本不能使用关键字作为局部变量名。解析器不会识别它们。
编辑以响应第二条评论:class
在此处用作保存klass
值的局部变量。代码也可以在没有变量的情况下编写(假设@handlers[server]
的值在两次调用之间不能改变):
@handlers[server]
我假设代码的作者将if @handlers[server]
obj = Object
@handlers[server].split("::").each { |x| obj = obj.const_get(x) }
的值存储在一个变量中a)不必键入@handles[server]
两次而不是一次,b)向读者清楚说明该值是一个类,和/或c)避免必须两次调用@handlers[server]
。
YAEdit:希望删除最后一点混淆,以下代码也是等效的:
@handlers[]
或者:
if foo = @handlers[server]
obj = Object
foo.split("::").each { |x| obj = obj.const_get(x) }
然而,klass是一个比foo更具描述性的变量名,因此(大概)是作者选择将变量命名为klass的原因。