样式/可选布尔参数:在使用布尔参数定义方法时使用关键字参数

Cla*_*iby 10 ruby ruby-on-rails internal-server-error rails-api rubocop

我正在开发 Rails RESTful API,并在某些端点上设置了版本控制功能。我有一个类ApiVersion,负责根据初始化时传递给它的参数确定要渲染哪些控制器。

类定义如下:

 class ApiVersion
  attr_reader :version, :default

  def initialize(version, default = false)
    @version = version
    @default = default
  end

  # check whether version is specified or is default
  def matches?(request)
    check_headers(request.headers) || default
  end

  private

  def check_headers(headers)
    # check version from Accept headers; expect custom media type 'suits'
    accept = headers[:accept]
    accept&.include?("application/vnd.suits.#{version}+json")
  end
end
Run Code Online (Sandbox Code Playgroud)

这些请求工作得很好,但是当我运行时,rubocop -A我收到一条错误消息:

 Style/OptionalBooleanParameter: Use keyword arguments when defining method with boolean argument.
  def initialize(version, default = false)
Run Code Online (Sandbox Code Playgroud)

我在互联网上搜索了如何修复此类错误并得到了一些有趣的想法,但这些想法不适用于我的情况。例如,我发现一篇文章说我应该交替def initialize(version, default = false)通过def initialize(version, default: false)rubocop 测试,但随后我收到一个内部服务器错误,但有一个例外:ArgumentError: wrong number of arguments (given 2, expected 1)

有谁知道如何解决这个问题,或者如何改变类定义来解决这个问题?谢谢

Jör*_*tag 16

首先:如果您不同意 linter 中的特定规则,请将其关闭。特别是,这条规则属于“样式”类别,因此它不是正确性或安全性问题,而是样式问题。

\n

其次,布尔参数是一种代码味道,因为它们通常是标志参数。带有标志参数的方法通常会根据布尔参数的值做两件不同的事情,因为 \xe2\x80\xa6 为什么它会有标志参数?

\n

但是,执行两种不同操作的方法可能应该是两种方法。

\n

或者,在这种特殊情况下,由于它具体是一个对象初始化方法,因此暗示应该有两个类。

\n

好吧,除此之外,Rubocop 的好处在于它通常会告诉您如何解决它所抱怨的任何问题。在这种情况下,建议使用关键字参数。这并不能解决该方法可能仍然在执行两种不同操作的问题,但至少,它为这种差异提供了名称以便您可以在调用站点看到它。

\n

因此,Rubocop 建议将位置参数更改为关键字参数,如下所示:

\n
def initialize(version, default: false)\n
Run Code Online (Sandbox Code Playgroud)\n

现在,显然,当您在定义站点更改参数列表时,您还需要更改每个调用站点的每个参数列表。因此,如果您有这样的调用(请记住,#initialize调用者是::new):

\n
ApiVersion.new(\'1.2.3\', true)\n
Run Code Online (Sandbox Code Playgroud)\n

你需要将其替换为

\n
ApiVersion.new(\'1.2.3\', default: true)\n
Run Code Online (Sandbox Code Playgroud)\n