Требовать / расширить ClassMethod из отдельного файла - PullRequest
0 голосов
/ 25 мая 2018

У меня есть модуль с некоторыми методами "class" или "DSL", который на данный момент выглядит следующим образом:

module Things
  module ClassMethods
    def thing id, title, **options
      # ... create and register a thing ...
    end

    # ... more DSL methods ...
  end
  extend ClassMethods

  # define project things
  thing :ruby, "Ruby programming language"
  thing :rails, "Ruby on Rails web framework"
  thing :active_support, "ActiveSupport library"
end

Поэтому я определяю методы DSL в ClassMethods, расширяю Thingsс помощью ClassMethods затем используйте DSL в теле модуля.Я выбрал имя ClassMethods в соответствии с соглашением, которое я вижу, несмотря на то, что модуль не является активной записью Концерна.

Теперь я хотел бы отделить определение DSL от его использования, поэтому я разделил код на

lib/things/class_methods.rb:

module Things
  module ClassMethods
    def thing id, title, **options
      # ... create and register a thing ...
    end

    # ... more DSL methods ...
  end
end

и lib/things.rb:

require_relative "things/class_methods"

module Things
  extend ClassMethods

  # define project things
  thing :ruby, "Ruby programming language"
  thing :rails, "Ruby on Rails web framework"
  thing :active_support, "ActiveSupport library"
end

Но после этого что-то ломается: код работает в первый раз после перезапуска сервера rails, как и предполагалось, но последующие запросы, использующие этот модуль, вызывают неясные ошибки или жалуются на то, что методы DSL не определены или ведут себя иначекак будто звонки DSL не делали то, что они должны были.Такое ощущение, что строка extend ClassMethods обнаруживает неправильный модуль ClassMethod, но тогда я не понимаю, почему я работаю изначально.

Есть идеи, что именно не так с моим подходом и как лучше всего решить проблему?Должен ли я переименовать модуль DSL, чтобы он не конфликтовал с ClassMethods, определенным в другом месте в структуре?Или я могу еще что-нибудь сделать, чтобы продолжать использовать имя ClassMethods без конфликта?

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Вы пытались добавить каталог /lib в файл application.rb, используя метод .autoload_paths?

0 голосов
/ 25 мая 2018

Rails иногда теряет отслеживание констант во время автозагрузки и перезагрузки и нуждается в некоторой помощи.

Это может быть явная зависимость:

# lib/things.rb
require_dependency 'things/class_methods' # <- tells Rails that we depend on this
require_relative 'things/class_methods'

module Things
  extend ClassMethods

  # ...
end

Или с помощьюполная квалификация:

# lib/things.rb
require_relative 'things/class_methods'

module Things
  extend ::Things::ClassMethods

  # ...
end

Возможно, будет достаточно использовать extend Things::ClassMethods, при условии, что у вас нет другого Things модуля, вложенного в Things.

Какой подходработает, похоже, зависит от вашей структуры классов и конфигурации автозагрузки.

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