Подтвердить что ты не робот

Какая разница между этими соглашениями пространства имен 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?

4b9b3361

Ответ 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 смешивает оба подхода: первый, второй.