В Ruby определение вложенного класса похоже на определение класса в модуле. На самом деле он не вызывает ассоциации между классами, он просто создает пространство имен для констант. (Имена классов и модулей являются константами.)
Принятый ответ ни в чем не был правильным. В приведенном ниже примере я создаю экземпляр лексически замкнутого класса без когда-либо существовавшего экземпляра включающего класса.
class A; class B; end; end
A::B.new
Преимущества те же, что и для модулей: инкапсуляция, группировка кода, используемого только в одном месте, и размещение кода ближе к тому месту, где он используется. В большом проекте может быть один внешний модуль, который повторяется снова и снова в каждом исходном файле и содержит множество определений классов. Когда все различные фреймворки и библиотечные коды делают это, тогда они вносят только одно имя на верхний уровень, уменьшая вероятность конфликтов. Прозаика, конечно, но они поэтому и используются.
Использование класса вместо модуля для определения внешнего пространства имен может иметь смысл в однофайловой программе или скрипте, или если вы уже используете для чего-то класс верхнего уровня, или если вы действительно собираетесь добавить код для связывания классов вместе в истинном стиле внутреннего класса . Ruby не имеет внутренних классов, но ничто не мешает вам создать примерно такое же поведение в коде. Ссылка на внешние объекты из внутренних по-прежнему потребует расставления точек в экземпляре внешнего объекта, но вложенность классов предполагает, что это то, что вы могли бы делать. Тщательно модульная программа всегда может сначала создавать включающие классы, и их можно разумно разложить на вложенные или внутренние классы. Вы не можете вызвать new
модуль.
Вы можете использовать общий шаблон даже для сценариев, где пространство имен не очень необходимо, просто для развлечения и практики ...
class A
class Realwork_A
...
end
class Realwork_B
...
end
def run
...
end
self
end.new.run
Car.new
иCar::Wheel.new
. Вам определенно не нужно инициализироватьCar
объект для инициализацииCar::Wheel
объекта в Ruby, ноCar
класс должен быть загружен и выполнен,Car::Wheel
чтобы его можно было использовать.