将Java移植到Ruby - 如何处理方法签名重载

时间:2015-01-02 17:50:21

标签: java ruby overloading optional-parameters

我有一些乐趣将一些java代码移植到ruby,并且我正在寻求有关如何最好地实现下面的方法签名重载的指导?

使用Ruby的可选参数,我可以容纳所有的重载,但这会导致不太理想的条件'编码以确定我正在处理哪些参数。什么是更多&#Ruby;喜欢'处理这个的方法?

  # public void set (ISOComponent c)
  # public void set(int fldno, String value)
  # public void set (String fpath, String value)
  # public void set (String fpath, ISOComponent c)
  # public void set (String fpath, byte[] value)
  # public void set (int fldno, byte[] value)
  def set(iso_component: nil, field_number: -1, string_value: '', file_path: '', byte_array: nil)

2 个答案:

答案 0 :(得分:2)

对于Ruby,我认为最好的选择是依靠不同的OOP设计原则,比如鸭子打字。而不是尝试创建一个set方法,根据您传入的参数创建6个不同的东西,如果您创建共享可以传入的一致接口的对象,您的代码可能会更清晰,更易于维护作为set方法的参数。这是一个例子:

class MyObject
  def set(obj)
    # depend on the interface: duck typing
    obj.set_the_things
  end
end

class ISOComponent
  def set_the_things
    # do ISOComponent specific stuff here
  end
end

class OtherInput
  attr_accessor :field_number, :value

  def set_the_things
    # do OtherInput specific stuff here
    # using @field_number and @value
  end
end

my_obj = MyObject.new
iso_component = ISOComponent.new
other_input = OtherInput.new

my_obj.set(iso_component)
my_obj.set(other_input)

由于MyObject#set仅依赖于可传递给它的对象中的set_the_things方法,因此只要它们实现自己的{set_the_things,就可以将任意数量的不同对象传递给此方法。 1}}执行特定于其目的的操作的方法。因此,如果您需要一个处理文件路径和ISO组件的输入,您将构建一个具有set_the_things方法的对象,该方法使用文件路径和ISO组件执行所需的操作,而不是尝试创建set 1}}方法对每个人来说都是一切(对于测试和需要理解set方法所做的事情的客户来说,这可能更令人困惑。)

文章“Duck Typing”描述了这一点。

答案 1 :(得分:0)

在Ruby中不可能重载方法,你需要重构API或者你可以做一些奇特的元编程和评估类型并调用不同的方法定义(你用类似DSL的方法定义)但是这绝对是我认为不是标准这样做的方式。

通常,如果您有一个困难的方法,您可能希望将参数作为哈希传递,并定义字段的默认值。如果您有多个应该评估为一种目标类型的类,您可以定义一个方法,将所有类型转换为您想要的目标类型。

好的,我认为我更善于使用代码表达自己:

def set(options = {})
  options[:str] = (options[:str] || "").to_s
  options[:num] = (options[:num] || 0).to_i
end

在这里,您可以使用几乎任何内容定义的to_ito_s方法,但您可以定义自己的“转换器”方法,以转换为您想要的类,然后您不必在你的方法中打扰变量的类型。

另一个很酷的事情是,在ruby parantheses中是可选的,你可以在没有花括号的情况下调用前面的方法。

 # These two are equivalent to eachother
 set({str: "Hello World", num: 123})
 set(str: "Hello World", num: 123)