为什么 Ruby 在方法调用中支持尾随逗号,但在方法定义中不支持?

问题描述 投票:0回答:1

例如,这是有效的 Ruby:

def foo(bar, baz); end
foo(1, 2,)

但这不是

def foo(bar, baz,); end # syntax error, unexpected ')' (SyntaxError)
foo(1,2,)
ruby
1个回答
0
投票

它对于对象来说是有用的语法糖,但不是方法签名

评论中,您收到了看似有效的答案。但是,它可能有助于理解为什么尾随逗号通常被认为在数组或哈希定义中有用,但在方法签名中则不然。

  1. 方法签名应该很短。方法签名中的非常长的列表被认为是反模式,因此在解析器中添加对此的支持没有多大意义。

  2. 数组或哈希可以是任意长,并且支持尾随逗号允许您重新排序元素,而无需添加或删除两个逗号,当排序或移动行已经足够麻烦时,为此用例添加了解析器支持。

考虑以下极简示例:

foo = [
  "4B1EDDEB-3B54-494A-9B79-FE864E8A4B84",
  "5AB88925-2C0F-4E26-AB12-554A0DD0BD6E",
  "F9265B1C-353E-4355-8B86-08428998EE16",
  "6E5D5D6C-A0C1-47A4-97F8-C4FF080BE1E0",
  "39D97755-7691-43F1-9446-07A10E138D93"
]

如果您想在源代码中手动移动 foo 数组的第五个元素(而不是使用 #pop 和 #unshift 以编程方式),使其成为第一个元素,您可能很容易忘记将尾随逗号添加到您刚刚移动的行,或者忘记删除数组末尾的尾随逗号。

现在假设您有 100 个这样的元素并尝试对这些行进行排序。当没有逗号的一行被埋在这样的文本墙内的某个地方时,很容易忘记需要调整的两行。当行或元素的长度不统一(例如上面的 UUID)时,更是如此。参差不齐的右边距会使发现丢失的逗号变得非常非常困难。 通过允许每行以逗号结尾,无论它是在数组还是哈希文本的末尾,尾随逗号语法都可以让您避免该问题。使用尾随逗号,您可以进行剪切和粘贴,而不必担心意外创建可能难以通过视觉发现的语法错误。 相比之下,您不应该看到带有一百个参数的方法签名。在这种情况下,您通常会传递数组或哈希,使用 splatted 位置或关键字参数,例如

def foo(*args, **kwargs); end

,甚至是选项哈希。哎呀,如果您使用实例变量或属性读取器,您可能根本不需要传递任何内容!因此,虽然您可能偶尔会在野外看到一两个方法,其中方法签名不止一行,尤其是从 Struct 继承时,但您不会发现很多编写良好的代码真正受益于尾随 -解析方法定义时支持逗号。

实际上,区分这两种不同的用例对我来说很有意义。如果这种不一致让您感到足够困扰,您可以随时搜索

bug tracker
,看看这是否是 Ruby 核心团队出于技术原因而故意做出的决定,或者仅仅是因为之前没有人费心为其提交补丁。我怀疑是前者,因为它为真正需要它的对象提供了一些有用的语法糖,而不会导致任何现实世界中理智签名的问题。我本人并不认为这种行为令人惊讶或特别不一致,因此我从未将其视为错误,因此无法向您指出决定该问题的特定问题或讨论线程,但您可以在其中找到如果有的话,请给出规范的答案。

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