代码之家  ›  专栏  ›  技术社区  ›  pjs

命名参数可以有别名吗?

  •  0
  • pjs  · 技术社区  · 6 年前

    我正在写一个方法,它将评估与分布参数相关的统计信息:

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

    然而, standard_deviation 是一种很好的口香糖,也有其他的名字(例如, sigma , sd )这对最终用户来说可能更难忘或更方便。我可以向该方法添加更多参数,然后手动检查是否只使用了一个备选名称,但这既单调又难看。有什么办法可以这么说吗 SD 西格玛 是的别名 标准偏差 那么下面的内容就可以了?

    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 回复  |  直到 6 年前
        1
  •  2
  •   Amadan    6 年前

    如果你不想打字太多,而且真的想检查一下是否正常,这样的方法可能有效吗?

    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)
    
        2
  •  1
  •   ForeverZer0    6 年前

    直接回答你的问题,不,至少不是自动回答,我相信你的意思是你的评论。

    没有为一个选项定义多个名称的内置机制,无论您引用哪个选项,Ruby都会自动返回相同的值。根据你的评论,我认为这是预期的行为,类似于 alias 关键字,然后可以用旧名称或新名称调用。

    您唯一真正的选择是手动解析选项,通常不应该添加 多钻孔锅炉板代码:

    def blending(**options)
      @mode = options[:mode] || options[:blend_mode] 
      @function = options[:function] || options[:blend_function]
    end
    

    没有什么类似的 alias_option :mode, :blend_mode 这将允许您简单地使用这些名称中的一个,并获取值,无论使用哪个方法调用。无论您以何种方式执行此操作,都将进行一些手动检查。

        3
  •  1
  •   pjs    6 年前

    根据阿玛丹的回答,我得出的结论是。

    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
    

    产生:

    {:mu=>3, :sd=>7}
    {:mu=>5, :sd=>4}
    Use only one of mean, mu
    Use only one of standard_deviation, sd, sigma
    Missing parameter: standard_deviation
    

    我仍然希望别名是一个选项,但这是可用的。