Ответ 1
Вы правы, чтобы вас путали... Док не указал, что 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
, тогда только LookHereOnly
и ее включенные модули будут найдены. Если область не указана (например, Foo
в приведенном выше примере), Ruby рассмотрит определения открытого модуля, чтобы найти константу Foo
: M::N
, затем M
и, наконец, Object
. Определение самого верхнего открытого модуля всегда Object
.
Итак, M::N.const_get :Foo
эквивалентно доступу Foo
, когда открытые классы являются только M::N
и Object
, как в последней части моего примера.
Надеюсь, я понял это правильно, потому что меня все еще смущает постоянный поиск: -)