40

In the code below, from a blog post by Alias, I noticed the use of the double exclamation mark !!. I was wondering what it meant and where I could go in the future to find explanations for Perl syntax like this. (Yes, I already searched for !! at perlsyn).

package Foo;
 
use vars qw{$DEBUG};
BEGIN {
    $DEBUG = 0 unless defined $DEBUG;
}
use constant DEBUG => !! $DEBUG;
 
sub foo {
    debug('In sub foo') if DEBUG;
 
    ...
}

UPDATE
Thanks for all of your answers.

Here is something else I just found that is related The List Squash Operator x!!

jonypera
  • 446
  • 2
  • 13
  • 23
Christopher Bottoms
  • 11,218
  • 8
  • 50
  • 99
  • 4
    If you think `!!` is a fun operator, try out the `-->` operator in a for loop. :) – Ether Jan 30 '10 at 16:53
  • Ether, can you post a link to the --> operator? I don't know how to find it on google. – Geo Jan 30 '10 at 16:59
  • @Geo: here you go (you'll laugh; don't hate me): http://stackoverflow.com/questions/1642028/what-is-the-name-of-this-operator – Ether Jan 30 '10 at 17:20
  • Awesome! I wasn't aware C had lolcat operators :) – Geo Jan 30 '10 at 18:07
  • javascript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT#double_not_!! – gawkface Oct 29 '21 at 18:33

3 Answers3

54

It is just two ! boolean not operators sitting next to each other.

The reason to use this idiom is to make sure that you receive a 1 or a 0. Actually it returns an empty string which numifys to 0. It's usually only used in numeric, or boolean context though.

You will often see this in Code Golf competitions, because it is shorter than using the ternary ? : operator with 1 and 0 ($test ? 1 : 0).

!! undef  == 0
!! 0      == 0
!! 1      == 1
!! $obj   == 1
!! 100    == 1

undef ? 1 : 0  == 0
0     ? 1 : 0  == 0
1     ? 1 : 0  == 1
$obj  ? 1 : 0  == 1
100   ? 1 : 0  == 1
Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
  • 14
    I actually often use `!!!!` in my code, because `!!` confuses vim's syntax highlighting and another `!!` will restore it! – Ether Jan 30 '10 at 16:55
  • 31
    @Ether: *Obviously*, you need to use emacs. :) – Paul Nathan Jan 30 '10 at 19:14
  • 10
    It produces 1 or the canonical false value, not 0. This is 0 in numeric context but the empty string in string context. To get 0 or 1, use the `1-!` operator :) – ysth Jan 31 '10 at 07:27
  • 2
    @Brad: -1 to get your attention on ysth's comment, will revoke upon fix. – j_random_hacker Jan 31 '10 at 09:28
  • 3
    Speaking as the guy that wrote the same code, it's there because I want anything odd in that variable normalised away at compile time. It's just a sort of quality protection mechanism. – Adam Kennedy Feb 01 '10 at 00:14
  • 1
    @Brad Thanks for your answer. I just started reading a draft of chromatic's new book and I like how he says that `!!` "forces boelean context". – Christopher Bottoms May 11 '10 at 15:58
12

not-not.

It converts the value to a boolean (or as close as Perl gets to such a thing).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

Because three other answers claim that the range is "0" or "1", I just thought I'd mention that booleans in Perl (as returned by operators like ==, not, and so on) are undef and 1, not 0 and 1.

jrockway
  • 42,082
  • 9
  • 61
  • 86
  • 3
    This is not correct. When an operator has to generate a false value, it uses a magic value that evaluates as the empty string in string context or 0 in numeric context. (The exceptions are operators like `and` and `or`, which simply return the operand that caused them to return false.) (See http://perldoc.perl.org/perlsyn.html#Truth-and-Falsehood) – cjm Jan 31 '10 at 07:17
  • 2
    undef is also a magic value that evaluates as '' in string context and 0 in numeric context -- the only difference is that when warnings are enabled, using undef for its string or numeric value is apt to produce a warning, while 'the false value' does no such thing ;) – hobbs Jan 31 '10 at 07:55
  • 2
    @hobbs: Well, another difference is that `defined(undef)` is false, but `defined(1==2)` is true. – cjm Jan 31 '10 at 10:52
  • Actually it returns a zero length string. – Brad Gilbert Feb 01 '10 at 16:42
  • +1 You obviously had an influence on the other answers. Brad modified his answer after yours. Also, at least one of those you mentioned ended up deleting his or her answer as well. – Christopher Bottoms Apr 12 '10 at 16:40
  • @molecules Actually I modified my answer based on the comment from [ysth](http://stackoverflow.com/users/17389/ysth). – Brad Gilbert Oct 09 '12 at 23:38