我想将save_form_data
方法与新签名一起使用。但是目前我的服务器在其队列中有很多工作依赖于旧签名 - 服务器知道该方法有2个参数,但新签名只接受一个参数。
# new signature
# params: Hash
def save_form_data(params)
process(params['catcher_token'], params['form_data'])
end
# old signature
# catcher_token: String, form_data: Array
def save_form_data(catcher_token, form_data)
process(catcher_token, form_data)
end
我认为我需要使用必须接受2个参数的版本来更改新签名方法。然后在其中我可以检查params
是否为Hash
类型,如果是,则忽略foobar
。但它只能解决问题的一半,因为类型为save_form_data(params)
的新调用现在将失败(我认为),因为方法接受2个参数,而不是1 ...
# modified new signature method
def save_form_data(params, foobar)
if params.class == Hash
process(params['catcher_token'], params['form_data'])
else
process(params, foobar)
end
end
答案 0 :(得分:3)
只需为第二个参数设置默认值:
def save_form_data(params, foobar = nil)
case params
when Hash
process(params['catcher_token'], params['form_data'])
else
process(params, foobar)
end
end
答案 1 :(得分:2)
正确。您需要制作兼容的签名。并区分方法内部的新旧格式。一段时间后,您将能够删除此compat图层(完成所有旧作业后)。
另外,不要使用具体的班级检查。做"是"检查。
if params.is_a?(Hash)
此代码也适用于哈希的子类(例如HashWithIndifferentAccess
),而您的代码则不行。
答案 2 :(得分:2)
我使用*args
和case
语句来显式处理不同数量的参数。像这样:
def save_form_data(*args)
case args.size
when 1
process(args[0]['catcher_token'], args[0]['form_data'])
when 2
process(args[0], args[1])
else
raise ArgumentError, "wrong number of arguments (#{args.size} for 1..2)"
end
end
您还可以添加弃用警告:
when 2
ActiveSupport::Deprecation.warn(<<-MSG.squish)
Passing `catcher_token` and `form_data` separately to `save_form_data` is
deprecated, please pass the `params` Hash instead.
MSG
process(args[0], args[1])
或输入验证:
when 1
raise TypeError, "expected Hash, got #{args[0].class}" unless args[0].is_a?(Hash)