tags:

views:

82

answers:

1
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

In the code above, const_get is being used to retrieve some kind of named constant on this line:

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

If so, why is 'klass' particularly being used here? I've read that klass is used to avoid namespace collisions with the "class" keyword. But in this example I don't see where the possible conflict could come from.

+4  A: 

The variable is called klass instead of class because both if class = @handlers[server] and class.split("::") would cause a syntax error because, as you said, class is a keyword in ruby.

As a rule local variables can't be named like keywords (methods are fine, but they may only be called with an explicit receiver, which is why you can't write e.g. class.name instead of self.class.name).

Everytime the parser sees the token class at the beginning of an expression, it interprets it as the keyword.

Edit: To clarify: The problem is not that the usage of class here would be ambiguous, it's that you simply can't use keywords as local variable names. The parser won't recognize them as such.

Edit in response to second comment: klass is used here as a local variable holding the value of @handlers[server]. The code could also be written without the variable (assuming that the value of @handlers[server] can't change between the two calls):

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

I assume that the author of the code stored the value of @handles[server] in a variable to a) not have to type @handlers[server] twice instead of once, b) make clear to the reader that that value is a class, and/or c) to avoid having to call @handlers[] twice.

YAEdit: To hopefully remove the last bit of confusion the following code is also equivalent:

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

Or:

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

However klass is a more descriptive variable name than foo, so that's (presumably) why the author chose to name the variable klass.

sepp2k
Where can the conflict arise here? Why is class/klass needed?
uzo
I guess my confusion is, what is klass being used for here? Or if class were used instead, what would it be needed for?
uzo