Какая разница между этими соглашениями пространства имен Ruby?
Итак, Module
может использоваться в Ruby для обеспечения пространства имен в дополнение к mixins, так:
module SomeNamespace
class Animal
end
end
animal = SomeNamespace::Animal.new
Но я также видел следующее:
module SomeNamespace
end
class SomeNamespace::Animal
end
animal = SomeNamespace::Animal.new
Мой вопрос в том, как они разные (если они есть), а какие более идиоматические Ruby?
Ответы
Ответ 1
Разница заключается в размещении.
В приведенном ниже примере вы можете видеть, что прежний метод с использованием класса Foo может получить внешние переменные константы BAR_A без ошибок.
Между тем класс Baz будет бомбить с ошибкой неинициализированной константы A:: B:: Baz:: BAR_A. Поскольку он не содержит A:: * неявно, явно только A:: B:: *.
module A
BAR_A = 'Bar A!'
module B
BAR_B = 'Bar B!'
class Foo
p BAR_A
p BAR_B
end
end
end
class A::B::Baz
p BAR_A
p BAR_B
end
Оба поведения имеют свое место. По моему мнению, в сообществе нет реального консенсуса относительно того, что такое One True Ruby Way (tm). Я лично использую первую, большую часть времени.
Ответ 2
Единственное различие между двумя подходами заключается в том, что второй будет бросать uninitialized constant Object::SomeNamespace
, если пространство имен ранее не было объявлено.
Когда объявлено в одном файле, я бы выбрал первый, потому что вам не нужно повторять SomeNamespace
.
При использовании нескольких файлов я также использую второй, чтобы избежать следующей проблемы:
# in a.rb
require 'b'
module SomeNamespace
def self.animal
Animal.new
end
end
# in b.rb
class SomeNamespace::Animal
end
# irb
require 'a' # explodes with the uninitialized constant error
Этот пример может быть изобретен, но его легко вызвать, если ваша база кода немного больше. Обычно я использую явный способ (ваш первый), чтобы избежать этого.
Одна вещь, которая может быть полезна при использовании второй формы, заключается в том, что она обнаружит опечатки в пространстве имен.
Не существует установленного способа создания пространств имен, например Devise смешивает оба подхода: первый, второй.