Rails разделяет константы с использованием method_missing в режиме DRY
Я написал класс:
module SharedConstants
class Stage
CONST = {
created: 0,
prepared: 1,
shadowed: 2,
vmxed: 3,
sbooted: 4,
booted: 5,
saved: 6,
dontknowen: 7
}
def self.method_missing(method_name, *args, &block)
fail "Constant not defined: #{name}.#{method_name}" if CONST[method_name].nil?
CONST[method_name]
end
def self.respond_to?(method_name, include_private = false)
CONST[method_name].nil? ? super : true
end
end
end
... который прекрасно работает, когда мы хотим получить доступ к такой константе:
Stage.created # => 0
Теперь я хочу представить еще один набор констант под названием Foo, но я хочу высушить код.
Я попытался переместить оба метода класса в модуль SharedConstant и "расширить" этот модуль. Попытка создать базовый класс и извлечь из него, но я не могу получить ни один подход к работе.
Вот мой пример спецификации:
require 'rails_helper'
RSpec.describe SharedConstants::Stage, type: :lib do
[:created, :prepared, :shadowed, :vmxed, :sbooted,
:booted, :saved, :dontknowen].each do |const|
it "defines #{const}" do
expect(described_class.send(const)).to be >= 0
end
it "responds to #{const}" do
expect(described_class.respond_to?(const)).to eq(true)
end
end
end
Любые идеи приветствуются. Заранее спасибо.
1 ответ
Решение
Я бы использовал подклассы и метод класса вместо фактической константы.
class ConstantAccessor
def self.method_missing(method_name, *args, &block)
super unless const[method_name]
const[method_name]
end
def self.respond_to?(method_name, include_private = false)
super unless const[method_name]
true
end
end
class State < ConstantAccessor
def self.const
@const ||= {
created: 0,
prepared: 1,
shadowed: 2,
vmxed: 3,
sbooted: 4,
booted: 5,
saved: 6,
dontknowen: 7
}
end
end
class AnotherSetOfConstants < ConstantAccessor
def self.const
@const ||= {
something: 0,
somethingelse: 1,
another: 2
}
end
end