命名参数可以有别名吗?

时间:2018-07-12 23:00:33

标签: ruby

我正在编写一种方法,用于评估与分布参数有关的统计信息:

def munch(data:, mean:, standard_deviation:)
  # munch the data
end

然而,standard_deviation令人a目结舌,并以其他名称(例如sigmasd)而闻名,这些名称对于最终用户而言可能更令人难忘或方便。我可以在该方法中添加更多参数,然后手动检查是否仅使用了一个替代名称,但这既乏味又丑陋。有没有办法说sdsigmastandard_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

3 个答案:

答案 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

我仍然希望使用别名,但这是可用的。