+10  A: 

not-not.

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

David Dorward
It's also a common idiom in other languages too like Javascript.
mpeters
@David Dorward Thanks for your answer!
molecules
+21  A: 

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
I actually often use `!!!!` in my code, because `!!` confuses vim's syntax highlighting and another `!!` will restore it!
Ether
@Ether: *Obviously*, you need to use emacs. :)
Paul Nathan
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
@Brad: -1 to get your attention on ysth's comment, will revoke upon fix.
j_random_hacker
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
@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".
molecules
A: 

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
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
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
@hobbs: Well, another difference is that `defined(undef)` is false, but `defined(1==2)` is true.
cjm
Actually it returns a zero length string.
Brad Gilbert
+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.
molecules