在Ruby 2.6 / 2.7中`public_send`的不同行为

问题描述 投票:1回答:1
class A
  def a
    1
  end
end

a = A.new
x = {}

a.a(**x) # => 1 in both Ruby 2.6 and 2.7

a.public_send(:a, **x) # => 1 in Ruby 2.7

但是在Ruby 2.6中:

ArgumentError: wrong number of arguments (given 1, expected 0) 

这是2.7public_send/send/ __send__之前的错误吗?您建议如何克服这种差异?

您可以检查失败的实时here

ruby kwargs ruby-2.5 ruby-2.6 ruby-2.7
1个回答
0
投票

[在Ruby 2.6及更低版本中,**argument语法主要(但不完全)是用于传递的哈希的语法糖。这样做是为了保持约定,以将变量哈希作为最后一个参数传递给方法有效。

然而,在Ruby 2.7中,关键字参数已在语义上进行了更新,不再映射到哈希参数。这里,关键字参数是从位置参数处理的。

在Ruby 2.6及更低版本中,以下两个方法定义(至少在许多方面是等效的):

def one(args={})
  #...
end

def two(**args)
  #...
end

在两种情况下,您都可以传递逐字散列或散列散列,但结果相同:

arguments = {foo: :bar}

one(arguments)
one(**arguments)

two(arguments)
two(**arguments)

但是,对于Ruby 2.7,您应该这样传递关键字参数(以前的行为仍然有效,但已过警告,但已弃用)。因此,对two(arguments)的调用将在2.7中导致弃用警告,并且在Ruby 3.0中将变得无效。

内部,散列的散列参数(将关键字参数传递给方法)因此在Ruby 2.7中导致关键字参数列表为空,而在2.6中导致位置参数的哈希值为空。

© www.soinside.com 2019 - 2024. All rights reserved.