为什么在Ruby中必须将关键字参数作为带有符号键的哈希传递,而不是字符串键?

8

我们不能使用字符串键的哈希传递关键字参数,关键字参数仅能与符号键的哈希一起使用。

一个简单的例子:

def my_method(first_name:, last_name: )
  puts "first_name: #{first_name} | last_name: #{last_name}"
end

my_method( {last_name: 'Sehrawat', first_name: 'Manoj'}) 
#=> first_name: Manoj | last_name: Sehrawat

my_method( {first_name: 'Bob', last_name: 'Marley'})
#=> first_name: Bob | last_name: Marley

my_method( {'first_name' => 'Kumar', 'last_name' => 'Manoj'})
#=> Error: missing keywords: first_name, last_name (ArgumentError)

这背后的原因是什么?

我认为这个想法类似于https://dev59.com/SWsy5IYBdhLWcg3w-i_h - freemanoid
@freemanoid 我不这么认为。在这种情况下,语法是关于如何接受一个局部变量的。没有涉及任何符号。 - sawa
3个回答

4
短而简单的答案是因为Matz这样说 - 在这个rubymine问题 issue 上,他评论道:“我对这个提议持反对意见。我的观点是您不应该(或不再)使用字符串作为关键字。” 实际问题是由此引起的某些后果,但如果Matz说不,那就不太可能发生。我不知道他是否进一步阐述了他为什么反对这种做法。

3
实现***可能是相关的:
def gather_arguments(*arguments, **keywords)
  puts "arguments: #{arguments.inspect}"
  puts " keywords: #{keywords.inspect}"
end

gather_arguments('foo' => 1, bar: 2, 'baz' => 3, qux: 4)

输出:

arguments: [{"foo"=>1, "baz"=>3}]
 keywords: {:bar=>2, :qux=>4}

你是说字符串键被保留,以便它们可以与关键字参数区分开来,并解释为哈希参数的一部分吗?如果是这样,我不同意。 - sawa
1
@sawa 我并不是在说这是原因。只是如果允许使用字符串作为关键字参数,那么***的当前行为将会改变(并且可能会破坏现有的代码)。 - Stefan

0

尽管可以在哈希内传递关键字参数,但我认为主要预期的用法是直接使用key: value语法:

my_method(first_name: 'Bob', last_name: 'Marley')

就这个表单而言,这里没有符号键(或数组键)。key: value语法是直接表示关键字参数的方式。
我的猜测是,由于这种语法与带有符号键和省略大括号的散列相重合,因此也有必要通过带有符号键的散列接受关键字值对。而且很可能它被设计成与传递带有符号键的哈希的技巧兼容,这个技巧在引入这种语法之前已经被使用了。

1
在1.9中的symbol: key语法确实是专门为迁移到“真正”的关键字参数而引入的。 - Jörg W Mittag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接