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

问题描述

我正在研究我的 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

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

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

我在互联网上搜索了如何修复这种类型的错误,并得到了一些在我的情况下无法使用的有趣想法。例如,我发现一篇帖子说我应该将 def initialize(version,default = false) 替换为 def initialize(version,default: false),它通过了 rubocop 测试,但随后我收到了一个内部服务器错误,但出现异常:ArgumentError: wrong number of arguments (given 2,expected 1)

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

解决方法

首先:如果您不同意 linter 中的特定规则,则将其关闭。特别是,this rule"Style" category 中,因此它不是正确性或安全问题,而是样式问题。

其次,布尔参数是 code smell,因为它们通常是 Flag Parameters。带有标志参数的方法通常会根据布尔参数的值做两种不同的事情,因为……否则为什么会有标志参数?

然而,一个做两种不同事情的方法应该是两种方法。

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

好吧,顺便说一下,R​​ubocop 的好处在于它通常会告诉您如何解决它所抱怨的任何问题。在这种情况下,它建议使用关键字参数。这并不能解决该方法可能仍在做两种不同的事情的问题,但至少,它为这种差异提供了一个名称,因此您可以在调用站点上看到它。

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

def initialize(version,default: false)

现在,很明显,当您在定义站点更改参数列表时,您还需要在每个调用站点更改每个参数列表。因此,如果您接到这样的电话 (remember that #initialize gets called by ::new):

ApiVersion.new('1.2.3',true)

您需要将其替换为

ApiVersion.new('1.2.3',default: true)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...