【问题标题】:Should a method ending in ? (question mark) return only a boolean?方法应该以 结尾吗? (问号)只返回一个布尔值?
【发布时间】:2012-05-18 16:06:33
【问题描述】:

我认为这样做只是常识和 Ruby 约定,但我有这个方法:

def is_subscribed?(feed_url)
  Subscription.find_by_user_id_and_feed_id(self[ :id ], Feed.find_by_feed_url(feed_url))
end

我得到的唯一困惑是,这不会像我最初预期的那样返回布尔值,方法是在方法名称的末尾加上问号。我的印象是,当评估一个有条件的对象时,如果不是nil,它会返回true

显然我在这里错过了重点,它没有像我想象的那样评估它。

所以,我的问题是,最好只做一个if (condition) true else false 吗?或者有更优雅的方法吗?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    另一种选择是使用三元/条件运算符来强制返回布尔值。

     if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this
    

    我同意其他人将您的方法名称更改为

     def subscribed? 
    

    【讨论】:

      【解决方案2】:

      其他答案很好地涵盖了返回值。

      我要补充一点,现代风格指南不鼓励布尔方法使用 is_ 前缀。尾随的问号涵盖了语义糖。

      来自https://github.com/rubocop-hq/ruby-style-guide

      布尔方法问号

      谓词方法的名称(methods 返回布尔值)应以问号结尾(即 数组#empty?)。不返回布尔值的方法不应以 问号。

      布尔方法前缀

      避免在谓词方法前加上 助动词,例如 is、does 或 can。这些话是多余的 并且与Ruby核心中布尔方法的风格不一致 图书馆,如空?并包括?。

      【讨论】:

        【解决方案3】:

        在方法名称的末尾添加? 不会以任何方式改变方法的返回值,而只是表明它是一个谓词方法。也就是说,方法的返回值应该被视为布尔值,但不需要是严格的布尔值(即truefalse)。

        许多其他答案表明它应该返回一个真值或假值。这是相当多余的,因为 everything 可以是真值或假值,并且由于 Ruby 中的所有方法都会返回一些东西(除非它们引发异常),因此返回值是 always 真值或假的。

        考虑附加? 作为在其他语言中附加is_ 的更好选择;例如我会选择subscribed?is_subscribed

        【讨论】:

          【解决方案4】:

          实际上,具体来说——以问号结尾的方法应该返回可以测试为truefalse 的值。

          rails 中有很多方法可以从 '?' 返回非布尔值方法。

          事实上,最近有一个 pull request 提交给 rails 项目,该请求将注意力集中在这个确切的问题上:

          https://github.com/rails/rails/pull/5582

          基本上,讨论是围绕这个确切的问题进行的——方法只需要返回可以测试为真或假的值,如下所示:

          if (condition)
            # do 'truthy option
          else
            # do non-truthy option
          end
          

          从这个角度来说,我相信你的方法很好。

          【讨论】:

            【解决方案5】:

            它应该是一个 'truthy' 或 'falsy' 值,可以在谓词中安全使用,但不必返回文字 truefalse。标准库中甚至还有这样的方法,例如File.size?

            【讨论】:

              【解决方案6】:

              以 ? 结尾的方法应该返回一个可以评估为真或假的值。如果您想确保返回布尔值,您可以通过在查找器中添加双键来实现。

              def is_subscribed?(feed_url)
                !!Subscription.find_by_user_id_and_feed_id(self[ :id ], Feed.find_by_feed_url(feed_url))
              end
              

              【讨论】:

              • 顺便说一句,也许该方法应该命名为“订阅?”。 “?”已经传达了“是”的意思。
              • “一个可以评估为真或假的值”,但 Ruby 中的任何值都会评估为 truefalse...
              • 除了 nil 和 false 之外,ruby 中的所有内容都评估为 true
              • 你是对的,安德鲁。它应该是“返回一个可以有意义地被评估为真或假的值”。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2010-12-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-04-18
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多