为什么klass与const_get一起使用?

时间:2009-09-13 06:30:57

标签: ruby

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”关键字冲突。但在这个例子中,我没有看到可能发生冲突的地方。

1 个答案:

答案 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的原因。