2009-09-13 62 views
2
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和const_get一起使用?

klass.split("::").each { |x| obj = obj.const_get(x) } 

如果是这样,为什么“klass”特别是在这里被使用?我读过klass用于避免命名空间与“class”关键字冲突。但在这个例子中,我没有看到可能的冲突可能来自哪里。

+0

我读过类似的代码。它被命名为 'class_name.split(“::”)。each {| x | klass = klass.const_get(x)}' – lulalala 2012-03-06 09:28:40

回答

5

该变量被称为klass而不是类,因为if class = @handlers[server]class.split("::")会导致语法错误,因为如您所说,class是ruby中的关键字。

作为规则的局部变量不能被命名为喜欢的关键字(方法都很好,但他们只能与一个明确的接收机,这就是为什么你不能写的如class.name代替self.class.name调用)。

解析器每次在表达式的开始处看到令牌class时,会将其解释为关键字。

编辑:澄清:问题不在于此处的类的用法不明确,而是因为您无法将关键字用作本地变量名称。解析器不会像这样识别它们。

编辑回应第二条评论:klass在这里用作一个局部变量,其值为@handlers[server]

if @handlers[server] 
    obj = Object 
    @handlers[server].split("::").each { |x| obj = obj.const_get(x) } 

我假设代码的作者存储的@handles[server]值的变量:代码也可以不变量(假设的@handlers[server]值不能在两个通话之间切换)写a)不必键入@handlers[server]而不是一次,b)向读者说明该值是一个类,和/或c)避免必须两次调用@handlers[]

YAEdit:要尽可能消除混乱的最后一点下面的代码也相当于:

if foo = @handlers[server] 
    obj = Object 
    foo.split("::").each { |x| obj = obj.const_get(x) } 

或者:

foo = @handlers[server] 
if foo 
    obj = Object 
    foo.split("::").each { |x| obj = obj.const_get(x) } 

然而克拉斯是一个更具描述性的变量名比富,所以这是(据推测)为什么作者选择命名变量klass。

+0

冲突在哪里出现?为什么需要class/klass? – uzo 2009-09-13 13:57:15

+0

我想我的困惑是,这里使用的是什么?或者如果改为使用班级,那将需要什么? – uzo 2009-09-13 15:57:47

相关问题