我有一个包含一长串可选参数的方法,例如:

def foo(foo = nil, bar = nil, baz = nil, qux = nil)
    # no-op
end

我认为调用该方法并将拆分散列作为参数传递将通过将键与方法参数匹配来将散列项映射到参数:
params = { bar: 'bar', foo: 'foo' }
foo(*params)

不幸的是,当我在使用拆分散列调用方法后检查局部变量时,如果我传入拆分数组,我得到的结果正是我所期望的,但这不是我所希望的:
foo == [:bar, 'bar'] # hoped: foo == 'foo'
bar == [:foo, 'foo'] # hoped: bar == 'bar'

我在这里缺少什么?

最佳答案

(此答案是指提出问题时当前的 Ruby 版本。请参阅编辑以了解今天的情况。)

Ruby 不支持按名称传递参数。 splat operator ( * ) 通过调用 to_ary 扩展任意可枚举并将结果拼接到参数列表中。在您的情况下,您传入的枚举是一个散列,它被转换为键值对数组:

[2] pry(main)> params.to_a
=> [[:bar, "bar"], [:foo, "foo"]]

因此该函数的前两个参数将是值 [:bar, "bar"][:foo, "foo"](不管它们的参数名称是什么!)。

如果你想在 Ruby 中使用类似于关键字参数的东西,你可以利用这样一个事实,即在将散列作为最后一个参数传递给函数时不需要大括号:
def foo(opts = {})
    bar = opts[:bar] || <default>
    foo = opts[:foo] || <default>
    # or with a lot of parameters:
    opts = { :bar => <default>, :foo => <default>, ... }.merge(opts)
end

foo(foo: 3)  # equivalent to foo({ foo: 3 })

编辑 :

从 2.0 版开始,Ruby 现在支持具有专用语法的 named arguments。感谢用户 jgoyon 指出这一点。

关于ruby - 如何将哈希项映射到方法参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12129496/

10-14 14:07
查看更多