Вы правы, что запутались ... В документе не указывалось, что Ruby делает особый случай поиска констант в Modules
и был изменен для явного указания этого . Если константа не была найдена в нормальной иерархии, Ruby перезапускает поиск с Object
, как это может быть в источнике .
Постоянный поиск может немного сбить с толку. Возьмите следующий пример:
module M
Foo = :bar
module N
# Accessing Foo here is fine:
p Foo # => bar
end
end
module M::N
# Accessing Foo here isn't
p Foo # => uninitialized constant M::N::Foo
end
p M::N.const_get :Foo # => uninitialized constant M::N::Foo
В обоих местах, однако, доступ к константам уровня Object
, таким как Array
, в порядке (слава богу!). Что происходит, так это то, что Ruby поддерживает список «определений открытых модулей». Если константа имеет явную область видимости, скажем, LookHereOnly::Foo
, то only LookHereOnly
и ее включенные модули будут найдены. Если область не указана (например, Foo
в приведенном выше примере), Ruby просматривает определения открытого модуля, чтобы найти константу Foo
: M::N
, затем M
и, наконец, Object
. Определение самого открытого открытого модуля всегда Object
.
Таким образом, M::N.const_get :Foo
эквивалентно доступу к Foo
, когда открытые классы только M::N
и Object
, как в последней части моего примера.
Надеюсь, я все понял, потому что я все еще смущен постоянными поисками: -)