Условная передача параметров при создании экземпляра класса
Я выполняю рефакторинг своего кода и хочу, чтобы некоторая логика передавалась параметру при создании экземпляра класса. Чтобы лучше описать проблему, я поделюсь некоторым кодом.
У меня есть этот метод, который принимает объект в качестве аргумента.
def common_attributes(klass)
klass.new(id: some_id, name: some_name, role_id: some_role.id)
end
Я хочу иметь возможность использовать это, чтобы сделать что-то вроде:
def common_attributes(klass)
klass.new(id: some_id,
name: some_name
role_id: some_role.id unless Module::class)
end
Это потому, что у меня есть несколько классов внутри моего модуля. Два из этих классов принимают те же три аргумента, т.е. id
а также name
, role_id
, Другой класс принимает два аргумента id
а также name
, Обратите внимание, что это примерные значения, и реализация может не иметь смысла, проблема I, но важно понять проблему, которая у меня есть.
Вот как я бы использовал функцию:
common_attributes(MyModule::Myclass)
common_attributes(MyModule::DifferentClass)
common_attributes(MyModule::AnotherDifferentClass)
Как я буду гарантировать, что другой класс, который принимает меньше аргументов, получает требуемые параметры и оставляет то, что ему не нужно?
NB Я не могу редактировать классы, чтобы включить дополнительные параметры.
2 ответа
Вы должны проверить для класса klass
внутри вашего метода. Если, например, класс, который принимает только два атрибута, MyModule::Myclass
, а все остальное принимает атрибуты дерева, тогда любое из этих решений должно работать:
def common_attributes(klass)
case klass
when MyModule::Myclass
klass.new(id: some_id, name: some_name)
else
klass.new(id: some_id, name: some_name, role_id: some_role.id)
end
end
или же:
def common_attributes(klass)
options = { id: some_id, name: some_name }
if klass.is_a?(MyModule::Myclass)
options[:role_id] = some_role.id
end
klass.new(**options)
end
Проверки могут расти, чтобы охватить больше особых случаев по мере необходимости.
Может быть arity
это то, что вы ищете
def common_attributes(klass)
args = { id: some_id, name: some_name }
args[:role_id] = some_role.id if klass.instance_method(:initialize).arity == 3
klass.new args
end