我有一些乐趣将一些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)
答案 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_i
或to_s
方法,但您可以定义自己的“转换器”方法,以转换为您想要的类,然后您不必在你的方法中打扰变量的类型。
另一个很酷的事情是,在ruby parantheses中是可选的,你可以在没有花括号的情况下调用前面的方法。
# These two are equivalent to eachother
set({str: "Hello World", num: 123})
set(str: "Hello World", num: 123)