Ruby - 在调用 function/method 时何时应该使用括号

Ruby - when I should use parenthesis or not when calling a function/method

在调用 function/method 时是否有明确的标准或指南来使用或不使用括号?

例如下面的代码:

class List < Jets::Stack
  sqs_queue(:dead_letter)
end

我应该还是不应该使用括号?其他示例:

class ExampleJob < ApplicationJob
  def sqs_event ref(:dead_letter)
  end
end

对比

class ExampleJob < ApplicationJob
  def sqs_event ref :dead_letter
  end
end

是否有我可以遵循的官方指南?

在Ruby中通常是可选的。

Ruby倾向于极简主义,所以他们经常被避免。

有时它们是必需的,例如 rspec expect where

expect a.to be true

必须

expect(a).to be true

在调用具有参数的方法时不使用括号或空括号会导致 ArgumentError,除非您为参数设置默认值,即

def a(x=1)

另一个考虑因素是当你想对某事的结果调用一个方法时,当你需要让该方法清楚地出现在最终结果上时,即

"br" + "own".upcase 

brOWN

但是

("br" + "own").upcase

BROWN

最后,正如我所说的清晰度,有时拥有它们可能会更好,即使不是严格需要。这通常是在复合表达式中,而不是依赖于运算符优先级等。或者如果您想要一个特定的不按标准运算符优先级执行的表达式,并且您想要自己的分组和运算顺序,例如:

irb(main):007:0> 5 + 6 * 2
=> 17
irb(main):008:0> (5 + 6) * 2
=> 22

正如 Nick 指出的那样,一个复杂的问题是 super,其中 supersuper() 传递参数,但 super(a,b) 调用 super... a,b 作为参数

Yes there is

我想您正在寻找社区指南,因为 Ruby 核心团队没有风格指南。

嗯,调用方法的时候一定要用括号,否则就不清楚了

# bad
x = Math.sin y
# good
x = Math.sin(y)

# bad
array.delete e
# good
array.delete(e)

# bad
temperance = Person.new 'Temperance', 30
# good
temperance = Person.new('Temperance', 30)

但是建议在没有参数时跳过它们。

注意 supersuper() 它们是不同的。 super 不带括号隐式传递所有参数。 super() 带空括号省略所有参数

我想到的唯一例外是某种自定义 DSL,DSL 本身必须有一些规则或偏好,例如

validates :name, presence: true

对于带有关键字参数的方法也是如此:

attr_reader :name, :age

Ruby 代码最佳实践没有官方标准。但是,Ruby 社区已经形成了一组首选样式。遵循那些偏好的风格是个好主意,只是因为它使您的代码更容易被其他 Ruby 程序员阅读。

Nick Roz 已为您提供 link 风格指南。我还建议您考虑安装和使用 rubocop。它会就何时和何时不给参数加上括号、许多其他格式设置问题(例如正确缩进)以及在特定情况下通常有几种不同的语法选项中选择哪一种提供反馈。

要回答关于是否对方法参数使用括号的具体问题,一般来说答案是肯定的。正如指南所说,例外情况是 "methods that have 'keyword' status in Ruby." 一个例子是 puts(实际上是 Kernel.puts 方法)。大多数人在这里不使用括号,但指南指出它们是可选的。

另一个例子,正如 Nick 所说(虽然 "methods with keyword arguments" 不太正确;在那种情况下,参数是表示方法而不是关键字的符号),是 attr_accessor,它实际上是Module.attr_accessor.

因此,作为一般规则,如果它看起来像 "command"(如果您愿意,则为 "keyword,"),但实际上是一个方法,请省略括号。否则,请使用它们。如果您不确定其中的区别,请养成使用 rubocop 的习惯。

根据Matz

If arguments are given to a method, they are generally surrounded by parentheses,

object.method(arg1, arg2)

but they can be omitted if doing so does not cause ambiguity.

object.method arg1, arg2