Условная передача параметров при создании экземпляра класса

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

У меня есть этот метод, который принимает объект в качестве аргумента.

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
Другие вопросы по тегам