How does Ruby Object # const_get work?

I recently discovered that Ruby (2.2.1) has some "interesting" behavior.

module Foo
  class Foo
  end
  class Bar
  end
end

Foo.const_get('Foo') #=> Foo::Foo
Foo.const_get('Bar') #=> Foo::Bar
Foo.const_get('Foo::Foo') #=> Foo
Foo.const_get('Foo::Bar') #=> NameError: uninitialized constant Foo::Foo::Bar
Foo.const_get('Foo::Foo::Bar') #=> Foo::Bar
Foo.const_get('Foo::Foo::Foo::Bar') #=> NameError: uninitialized constant Foo::Foo::Bar
Foo.const_get('Foo::Foo::Foo::Foo::Bar') #=> Foo::Bar
Foo.const_get('Foo::Foo::Foo') #=> Foo::Foo
Foo.const_get('Foo::Foo::Foo::Foo') #=> Foo
Foo.const_get('Foo::Foo::Foo::Foo::Foo') #=> Foo::Foo
Foo.const_get('Foo::Foo::Foo::Foo::Foo::Foo') #=> Foo

This is a bit surprising. I realized that I const_getfirst looked for a constant in the collection of constant recipients, and then looked at the constants of the object. Good. Why then the fourth Foo#const_getabove does not work, and the third does not?

I am also curious why the call Foo#const_getalternates between module and class depending on how many are added ::Foo.

+4
source share
1 answer

The docs say :

This method will recursively look for constant names if a class name with names is provided.

, Foo.const_get('Foo::Bar') Foo.const_get('Foo').const_get('Bar'). , .

:

Foo.const_get('Foo::Foo')

Foo.const_get('Foo').const_get('Foo')

const_get , Foo (), . , :

Foo::Foo.const_get('Foo')

, ( ), . Object Foo , .

::Foo s. const_get , , , .

Foo.const_get('Foo::Bar'), .

Foo.const_get('Foo').const_get('Bar')

Foo.const_get('Foo') , Foo::Foo, :

Foo::Foo.const_get('Bar')

Foo Bar , Object, NameError.

+5

All Articles