Ruby: псевдоним дочернего к родительскому пространству имен, так что классы могут быть созданы только с использованием родительского пространства имен - PullRequest
0 голосов
/ 18 марта 2020

Я хотел бы получить доступ к дочерним классам пространств имен, используя только родительское пространство имен в качестве префикса.

Я хочу, чтобы мои модели и контроллеры находились в отдельных дочерних папках и чтобы у них было дочернее пространство имен, но затем можно Псевдоним дочернего пространства имен, чтобы к нему можно было получить доступ через root пространство имен.

# This is the only class that is in the root namespace
provider = Cool::Provider.new

# Live in models namespace
company = Cool::Company.new
employee = Cool::Employee.new

# Live in controllers namespace
company_controller = Cool::CompanyController.new
employee_controller = Cool::EmployeeController.new

Спасибо тем, кто ответил о сопоставлении одного класса одновременно с родительским пространством имен, но я видел другой механизм это казалось более естественным в популярном GEM, и я пытаюсь найти эту технику.

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

Допустим, у меня есть список классов в этих файлах

cool/provider.rb
cool/models/company.rb
cool/models/employee.rb
cool/controllers/company_controller.rb
cool/controllers/employee_controller.rb

Вот классы

module Cool
  class Provider
  end
end

module Cool
  module Model
    class Company
    end
  end
  # The GEM I saw, did something here
end

module Cool
  module Model
    class Employee
    end
  end 
  # The GEM I saw, did something here
end

module Cool
  module Controller
    class CompanyController
    end
  end
  # The GEM I saw, did something here
end

module Cool
  module Controller
    class EmployeeController
    end
  end 
  # The GEM I saw, did something here
end

1 Ответ

0 голосов
/ 18 марта 2020

Пространства имен на самом деле не существуют в Ruby. Ruby имеет вложенность модуля - каждый модуль содержит свои собственные константы. Классы также являются модулями.

Когда вы используете ключевое слово module, 1017 * фактически делает это:

ModuleName = Module.new do
  # ... 
end

Вы связываете экземпляр модуля с константой. Так что, если вы хотите «псевдоним» от Cool::Model::Company до Company, вы просто определяете константу в модуле Company.

module Cool
  module Model
    class Company
    end
  end

  Company = Model::Company
end

Но я не понимаю, почему это так здорово с этим поскольку он просто вызовет havo c с автозагрузчиком Rails, так как он будет искать в корнях автозагрузки для cool/company.rb и ожидать, что он определит константу. Кроме того, какой смысл вложения модулей, если вы просто собираетесь использовать псевдоним во внешнем модуле и в любом случае вызвать потенциальную коллизию имен?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...