Ruby (и направляющие) вложенный синтаксис модуля

Я задаюсь вопросом, что различие между следующими двумя модулями

# First Example
module Parent
  module Child
  end
end

и

# Second Example
module Parent::Child
end

Используя 2-й метод, появляется, как будто Родительский модуль должен быть ранее определен, иначе я получаю 'неинициализированную постоянную' ошибку

Учитывая это, каков предпочтительный способ определить модули, такие как это и затем добавить вложенных детей относительно синтаксиса и файловой структуры (т.е. папки и т.д.). Ссылка на направляющие путь значительно ценилась бы.

Эти два примера, во всех отношениях, эквивалентны?

29
задан brad 19 May 2010 в 19:44
поделиться

3 ответа

В первом примере определяется модуль Parent , а затем модуль Child . Во втором примере, как вы сами говорите, должен быть заранее определен модуль Parent . За счет еще одной строчки кода вы гарантируете, что модуль, в который вы встраиваете, используя свой первый пример, всегда будет определен.

Для примера с Rails заглянем в файл railties / lib / rails / engine.rb , который повторно открывает модуль Rails , а затем ] определяет внутри себя класс Engine . Это можно было сделать просто:

class Rails::Engine

Но вместо этого, возможно, по причинам, указанным выше, а также, возможно, для ясности, сначала был определен модуль, а затем класс внутри.

31
ответ дан 28 November 2019 в 01:30
поделиться

Я предпочитаю второй метод (если уверен, что Parent уже определен), потому что он выглядит чище, особенно когда вложенность очень глубокая.

Однако у первого метода есть несколько преимуществ, одно из которых пока не обсуждалось: вложенный модуль получает доступ к любым лексически доступным константам в объемлющем модуле.

13
ответ дан 28 November 2019 в 01:30
поделиться

Вообще говоря, вы не хотите определять модуль, используя синтаксис модуля Parent :: Child, если вы не можете быть абсолютно уверены, что Parent уже существует. Подмодуль можно определить только с помощью синтаксиса ::, если определен родительский модуль. В вашем примере, если вы сделаете следующее, вы не получите неинициализированную постоянную ошибку.

module Parent
end

module Parent::Child
end
7
ответ дан 28 November 2019 в 01:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: