2011-04-26 58 views
16

任何人都可以告诉我为什么很多Ruby布尔方法使用这种双重否定约定吗?Ruby布尔双重否定约定

!!(boolean expression) 
+0

不是一个rubyist,但我会想要强制布尔值? – Ethan 2011-04-26 21:49:19

+1

密切相关:http://stackoverflow.com/questions/524658/what-does-mean-in-ruby – 2011-04-26 22:36:19

回答

20

的双重否定确保无论初始值,你总是会得到truefalse,从来一些神秘感值。

这很方便,因为它避免了对不再需要的对象的悬挂引用,或者需要区分两种类型的假值nilfalse

你经常会看到这样写的方法:

def logged_in? 
    [email protected]_user 
end 

这将返回truefalse,可用于要求不管出于何种目的该值。相比之下,与此:

def logged_in? 
    @session_user 
end 

在这种情况下,如果你保存的价值,你实际上是节省了整个@session_user对象,这可能是内存相当显著块。只有在您引用该内存超出范围之前,才能释放该内存。由于只有一个true和一个false,因此不需要垃圾收集。

3

假设您想定义一个返回布尔值的方法。例如,一个字符串是否与正则表达式匹配。

class String 
    def include? regex; self =~ regex end 
end 

如果你做到上面,它会返回nil当它不匹配,和一个整数它匹配时。在许多情况下,这并不重要(nil类似于false,而true可以替代整数)。但是,如果你真的想要一个布尔值作为返回值,如果你这样做

class String 
    def include? regex; !!(self =~ regex) end 
end 

它将返回true它匹配时,false当它没有。

1

在我看来,Ruby对布尔人来说太聪明了。这是巧妙导致问题的情况的解决方法。

这是过度的聪明:没有布尔类。相反,有一个约定,任何值都可以用作布尔值。在需要真值或假值的情况下,nilfalse表示“假”,而其他任何表示“真”。值truefalse不是特殊类的一部分,它们是它们各自类—的唯一成员,它们仅用于使代码更具可读性。

我想这工作得很好大部分的时间,但在每一个曾经很长一段时间,你需要一个布尔值,总是truefalse。例如,我最近需要比较两个布尔值,如果它们不同,则做一些特殊的事情;唯一的问题是,其中一个是truefalse,而另一个是1或nil。固定?利用!!nil == false!!1 == true的事实。