Ruby: 用参数定义方法

Ruby: define method with args

我正在尝试通过使用 args 动态定义方法来重构代码。我尝试使用 Define_method 但它抛出错误,我被迫定义 define_singleton_method.

这是我的代码,我想删除所有带有 call_* 前缀的方法。

def construct_payload(id, file_name, type)
    case type
    when 'Radio' then call_radio(id, file_name)
    when 'Pan' then call_pan(id, file_name)
    end
  end


  def call_radio(_id, _file_name)
    base(_id).merge(radio(_file_name))
  end

  def call_pan(_id, _file_name)
    base(_id).merge(pan(_file_name))
  end

  def base(_id)
    {
      "id": _id,
    }
  end

 def radio(file)
   { 
      "mode": "ds",
      "file": file
    }
 end

 def pan(file)
   { 
      "mode": "pr",
      "file": file
    }
 end

#enter code here

有没有办法动态定义 call_radiocall_pan 方法?

case (type) 通常是一个强烈的信号,你需要创建子classes 而不是拥有一个 omniclass 只是假装是不同的 classes。

例如:

class Radio < BaseClass
  def call(id, _file_name)
    # ...
  end
end

class Pan < BaseClass
  def call(id, _file_name)
    # ...
  end
end

然后您只需实例化正确的 class 并调用正确的方法。

这是面向对象设计的原则之一,您可以在适当的地方对 class 进行专门化,而不是让一个非专门化的 class 做许多不同的、通常是相互矛盾的事情。

您可以使用 method_missing 或调用 define_method 来做一些小动作,但与在这种情况下定义子 class 相比,这需要大量工作。

我认为 eval 是编写更少代码的更好选择

def construct_payload(id, file_name, type)
  eval("base(id).merge(#{type}(file_name))")
end

def base(_id)
    {
      "id": _id,
    }
  end

 def radio(file)
   { 
      "mode": "ds",
      "file": file
    }
 end

 def pan(file)
   { 
      "mode": "pr",
      "file": file
    }
 end