Почему беспокойство по поводу Rails приводит к тому, что модуль теряет свои константы? - PullRequest
0 голосов
/ 04 мая 2018

У меня есть проблема в Rails 4.2 с константой «Complete». app/models/concerns/orderable.rb

module Orderable
  extend ActiveSupport::Concern
  COMPLETE = "Complete"
end

В консоли Rails я могу запустить Orderable.constants, что возвращает [:COMPLETE]. Тем не менее, если я изменю отношение Orderable к стилю «low-cruft», описанному в Rails относительно module , примерно так:

concern :Orderable do
  COMPLETE = "Complete"
end

затем запуск Orderable.constants в консоли Rails возвращает []. Документация Rails гласит, что «кратчайший путь для определения проблемы ... эквивалентен». Почему это единственное изменение влияет на потерю доступа к константам модуля? Нужно ли как-то их переопределять?

1 Ответ

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

Похоже, что в действительности реализована проблема "макроса":

require 'active_support/concern'

class Module
    # A low-cruft shortcut to define a concern.
    #
    #   concern :EventTracking do
    #     ...
    #   end
    #
    # is equivalent to
    #
    #   module EventTracking
    #     extend ActiveSupport::Concern
    #
    #     ...
    #   end
    def concern(topic, &module_definition)
      const_set topic, Module.new {
        extend ::ActiveSupport::Concern
        module_eval(&module_definition)
      }
    end
  end
  include Concerning
end

В этом коде передается объект ruby ​​Module для предоставления метода concern.

Ключ здесь module_eval(&module_definition), который неправильно оценивает блок в контексте определяемого нового модуля.

Что на самом деле происходит при запуске:

concern :Orderable do
  COMPLETE = "Complete"
end

::COMPLETE
# => "Complete"

Это то, что вы объявляете постоянную COMPLETE в главном объекте. По электронной почте Ой!

Для правильной работы он должен выглядеть следующим образом:

def concern(topic, &module_definition)
  const_set topic, Module.new do |m|
    extend ::ActiveSupport::Concern
    m.module_eval(&module_definition)
  end
end

Я бы не использовал синтаксис "low-cruft", пока это не исправлено.

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