Why is the class being used in conjunction with const_get here?

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 used to retrieve any named constant on this line:

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

      

If so, why is 'here klass

' used here? I read what is klass

used to avoid namespace conflicts with the <24> keyword. But in this example, I don't see where the conflict might come from.

+2


source to share


1 answer


The variable is called a class instead of the class, because as if class = @handlers[server]

well as class.split("::")

lead to a syntax error, because, as you said, a class is the key word in ruby.

Generally, local variables cannot be named as keywords (methods are precise, but they can only be called with an explicit receiver, so you cannot write, for example, class.name

instead self.class.name

).

Every time the parser sees a marker class

at the beginning of an expression, it interprets it as a keyword.

Edit: To clarify: the problem is not that the use of the class would be ambiguous here, so you simply cannot use keywords as local variable names. The parser will not recognize them as such.

Edit in response to second comment: klass

Used here as a local variable containing the value @handlers[server]

. The code can also be written without a variable (provided that the value @handlers[server]

cannot change between two calls):

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

      



My guess is that the author of the code storing the value @handles[server]

in the variable a) does not need to enter @handlers[server]

twice instead of one, b) clarify to the reader that this value is a class, and / or c) to avoid double calling @handlers[]

.

YAEdit: 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, class is a more descriptive variable name than foo, so (presumably) why the author chose to name the variable a class.

+5


source







All Articles