一个方法应该结束吗? (问号)只返回一个布尔值?

时间:2012-05-10 05:28:35

标签: ruby

我认为这只是常识和Ruby惯例,但我有这个方法:

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

我得到的唯一困惑是,这并不像我最初预期的那样通过将问号放在方法名称的末尾来返回布尔值。我的印象是,在将对象评估为条件时,如果不是true则返回nil

显然我在这里忽略了这一点,并没有像我想的那样对它进行评估。

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

6 个答案:

答案 0 :(得分:34)

以?结尾的方法?应返回一个可以评估为true或false的值。如果你想确保一个布尔返回,你可以通过向finder添加双重爆发来实现。

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

答案 1 :(得分:16)

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

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

考虑添加?作为在其他语言中添加is_的更好的替代方案;例如我会subscribed?is_subscribed

答案 2 :(得分:5)

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

答案 3 :(得分:2)

实际上,具体而言 - 以问号结尾的方法应返回可以作为truefalse进行测试的值。

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

事实上,最近提交给rails项目的拉取请求集中了对这个问题的关注:

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

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

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

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

答案 4 :(得分:0)

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

我将添加现代样式指南,不建议将is_前缀用作布尔方法。末尾的问号覆盖了语义糖。

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

  

布尔方法问号

     

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

     

布尔方法前缀

     

避免在谓词方法前加上前缀   辅助动词,例如is,do或can。这些话是多余的   且与Ruby核心中的boolean方法风格不一致   库如空?并包含?。

答案 5 :(得分:0)

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

 if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this

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

 def subscribed?