我正在编写一种方法,用于评估与分布参数有关的统计信息:
def munch(data:, mean:, standard_deviation:)
# munch the data
end
然而,standard_deviation
令人a目结舌,并以其他名称(例如sigma
,sd
)而闻名,这些名称对于最终用户而言可能更令人难忘或方便。我可以在该方法中添加更多参数,然后手动检查是否仅使用了一个替代名称,但这既乏味又丑陋。有没有办法说sd
和sigma
是standard_deviation
的别名,以便下面的代码可以工作?
result1 = munch(data: my_data, mean: 20.0, standard_deviation: 3.0)
result2 = munch(data: my_data, mean: 20.0, sd: 3.0)
p result1 == result2 # => true
答案 0 :(得分:2)
如果您不想输入太多,而真的想进行健全性检查,那么类似的事情可能会起作用?
def alias_param(opts, *keys, **args)
supplied = opts.select { |k, _| keys.include?(k) }
if supplied.size > 1
raise ArgumentError, "Multiple aliases supplied: #{supplied.keys.inspect}"
elsif supplied.size < 1
raise ArgumentError, "Missing argument: one of #{keys.inspect}"
end
opts.values.first
end
def fn(data:, mean:, **opts)
sd = alias_param(opts, :sd, :sigma, :standard_deviation)
end
fn(data: 1, mean:3)
答案 1 :(得分:1)
要直接回答您的问题,不,至少不是以自动方式,我相信您的意思是我的意思。
没有内置的机制可以为一个选项定义多个名称,并且无论您引用哪个选项,Ruby都会自动返回相同的值。根据您的评论,我认为这是预期的行为,类似于alias
关键字,然后具有按旧名称或新名称进行调用的功能。
您唯一的真实选择是手动解析这些选项,通常不应添加太多太乏味的样板代码
:def blending(**options)
@mode = options[:mode] || options[:blend_mode]
@function = options[:function] || options[:blend_function]
end
没有什么与alias_option :mode, :blend_mode
相似的东西,无论使用哪种方法调用,都可以简单地使用这些名称之一并获取值。无论您采用哪种方式,都将需要进行一些手动检查。
答案 2 :(得分:1)
根据Amadan的回答,这就是我最后要做的事情。
mov dword [esp], dword [0x80486b2]
产生:
def check4aliases(opts, *keys)
supplied = opts.select { |k, _| keys.include?(k) }
return supplied.values.first if supplied.size == 1
msg = supplied.empty? ?
"Missing parameter: #{keys.first}" : "Use only one of #{keys.join(', ')}"
raise ArgumentError, msg
end
def munch(data:, **opts)
parameters = {
mu: check4aliases(opts, :mean, :mu),
sd: check4aliases(opts, :standard_deviation, :sd, :sigma)
}
# do actual work with data, mu, and sd
end
test_cases = [
{mean: 3, sd: 7},
{mu: 5, sigma: 4},
{mean: 3, mu: 3, sd: 7, sigma: 7, standard_deviation: 7},
{mean: 3, sd: 7, sigma: 8},
{mean: 3},
]
test_cases.each do |parms|
begin
p munch(data: 1, **parms)
rescue ArgumentError => msg
puts msg
end
end
我仍然希望使用别名,但这是可用的。