双splat运算符**
似乎只适用于其键为符号的哈希。例如,当键是字符串时,它将不起作用。这两种方式都是如此;施工:
def foo **; end
foo(:a => 3) #=> nil
foo("a" => 3) #=> ArgumentError: wrong number of arguments (1 for 0)
和破坏:
def bar *; end
bar(**{:a => 3}) #=> nil
bar(**{"a" => 3}) #=> TypeError: wrong argument type String (expected Symbol)
为什么它仅限于符号键?
这可能与命名关键字符号a: 3
与带符号键的哈希的语法糖一致,但如上所示,双splat与普通哈希符号:a => 3
一起使用,所以我不确定这一点。
答案 0 :(得分:6)
我最近碰到了这样的事情。
如果你在Rails中并且你有一个方法接受关键字参数并且你有一个强大的params哈希要发送给它,你可以在params哈希上使用symbolize_keys
它会正确地分离出论点,不需要双重splat。
class ContactForm
def initialize(name:, email:)
@name = name
@email = email
end
# Other stuff
end
class ContactController < ApplicationController
def send_mail
@contact_form = ContactForm.new(contact_params)
if @contact_form.submit
# Do stuff
end
end
def contact_params
params.require(:contact_form).permit(:name, :email).symbolize_keys
end
end
答案 1 :(得分:5)
简短的回答:关于double-splat运算符应该捕获的关键字参数如何用Ruby表示。
答案很长:双重splat运算符用于捕获关键字,如以下答案所示:https://stackoverflow.com/a/18289218/3644699
从Ruby 2.0开始,Ruby支持真正的关键字参数。我的猜测是,在主要实现中,它们仍然表示为Hashes,其键是符号,类似于在语言正式支持它们之前模拟它们的方式。
您可能遇到的特定错误可能取决于实施情况。例如,在irb中执行后一个代码片段会显示引发TypeError的函数:
2.1.2 :001 > def bar *; end
=> :bar
2.1.2 :002 > bar(**{"a" => 3})
TypeError: wrong argument type String (expected Symbol)
from (irb):2:in `core#hash_merge_kwd'
from (irb):2
from /home/mkis/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `<main>'
2.1.2 :003 >
hash_merge_kwd
是一个内部函数,在此处定义:https://github.com/ruby/ruby/blob/d738e3e15533e0f500789faaedcef9ed9ca362b9/vm.c#L2398