在Ruby中使用关键字参数来处理proc [英] Currying a proc with keyword arguments in Ruby

查看:89
本文介绍了在Ruby中使用关键字参数来处理proc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个通用的ProcLambdamethod,它带有一个可选的第二个参数:

Say I have a generic Proc, Lambda or method which takes an optional second argument:

pow = -> (base, exp: 2) { base**exp }

现在,我想使用此函数,将它的exp设置为3.

Now I want to curry this function, giving it an exp of 3.

cube = pow.curry.call(exp: 3)

这里有一个歧义,这是由关键字参数和新的哈希语法引起的,其中Ruby将exp: 3解释为作为第一个参数base传递的哈希.这样会导致立即调用该函数,并在将#**发送到哈希时呈现NoMethodError.

There's an ambiguity here, arising from the keyword arguments and the new hash syntax, where Ruby interprets exp: 3 as a hash being passed as the first argument, base. This results in the function immediately being invoked, rendering a NoMethodError when #** is sent to the hash.

为第一个参数设置默认值将类似地导致在进行currying时立即调用该函数,并且如果我根据需要将第一个参数标记为未提供默认值,则为

Setting a default value for the first argument will similarly result in the function being immediately invoked when currying, and if I mark the first argument as required, without providing a default:

pow = -> (base:, exp: 2) { base**exp }

当我尝试咖喱Proc时,解释器会抱怨我缺少参数base.

the interpreter will complain that I'm missing argument base when I attempt to curry the Proc.

如何使用第二个参数来咖喱函数?

How can I curry a function with the second argument?

推荐答案

您可以构建自己的带有关键字风味的咖喱方法,该方法将收集关键字参数,直到出现所需的参数为止.像这样:

You could build your own keyword-flavored curry method that collects keyword arguments until the required parameters are present. Something like:

def kw_curry(method)
  -> (**kw_args) {
    required = method.parameters.select { |type, _| type == :keyreq }
    if required.all? { |_, name| kw_args.has_key?(name) }
      method.call(**kw_args)
    else
      -> (**other_kw_args) { kw_curry(method)[**kw_args, **other_kw_args] }
    end
  }
end

def foo(a:, b:, c: nil)
  { a: a, b: b, c: c }
end

proc = kw_curry(method(:foo))
proc[a: 1]              #=> #<Proc:0x007f9a1c0891f8 (lambda)>
proc[b: 1]              #=> #<Proc:0x007f9a1c088f28 (lambda)>
proc[a: 1, b: 2]        #=> {:a=>1, :b=>2, :c=>nil}
proc[b: 2][a: 1]        #=> {:a=>1, :b=>2, :c=>nil}
proc[a: 1, c: 3][b: 2]  #=> {:a=>1, :b=>2, :c=>3}

上面的示例仅限于关键字参数,但是您可以将其扩展为同时支持关键字参数和位置参数.

The example above is limited to keyword arguments only, but you can certainly extend it to support both, keyword arguments and positional arguments.

这篇关于在Ruby中使用关键字参数来处理proc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆