创建 class 的实例时有条件地传递参数

Conditional passing of parameters when creating an instance of a class

我正在重构我的代码,我想在创建 class 的实例时将一些逻辑传递给参数。为了最好地描述问题,我将分享一些代码。

我有一个接受对象作为参数的方法。

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

这是因为我的模块中有几个 classes。其中两个 class 使用相同的三个参数,即 idnamerole_id。另一个 class 有两个参数 idname。请注意这些是示例值,实施可能没有意义,但重要的是理解我遇到的问题。

这就是我使用函数的方式:

common_attributes(MyModule::Myclass)

common_attributes(MyModule::DifferentClass)

common_attributes(MyModule::AnotherDifferentClass)

我如何确保接受较少参数的另一个 class 接收所需的参数并忽略不需要的参数?

注意 我无法编辑 classes 以包含可选参数。

也许 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

您应该在您的方法中测试 klass 的 class。例如,如果只接受两个属性的 class 是 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

检查可以适当增加以涵盖更多特殊情况。