During a recent job interview process, I submitted some sample Perl code which used the so-called "secret" !!
operator. Later, when discussing the code, one of the interviewers asked me why I chose to use that, and indicated that it was considered bad form. He didn't elaborate as to why.
My team and I have been using this operator for years, without ever realizing it was considered "bad form."
Does the "bang bang" operator have side-effects or other unexpected behavior? Why is it, or might it be, considered "bad form" by some? Is there an idiomatic alternative?
Below are a few examples where I would have considered !!
acceptable and/or desirable.
The actual code in the coding exercise, which is an example of adding booleans:
while (my $line = <$F>) {
# snip
exists $counts{lines} and $counts{lines} += !! chomp $line;
}
Using a boolean value as a hash key (clearly a simplified example):
sub foo {
my ($input) = @_;
my %responses = ( '' => "False", 1 => "True" );
return $responses{ !! $input };
}
Using a boolean in a bitwise operation, or even pack()
:
sub foo {
my ( $a, $b, $c ) = @_;
my $result = !!$a + (!! $b)<<1 + (!! $c)<<2;
return $result;
}
You need to do a typecast for use by an external library/process, such as a database, which only considers certain values to be truthy:
my $sth = $dbh->prepare("INSERT INTO table (flag,value) VALUES (?,?)")
$sth->execute("i_haz_cheeseburger", !! $cheeseburger_string)
Your !!
takes advantage of two obscure things in Perl: The specific values that !
returns, and that one of the possible values is dualvar (a scalar containing both a string and a number). Using !!
to compound these behaviors is admittedly pithy. While its pithiness can be a huge plus, it can also be a rather big minus. Don't use features that result in a project mandating that "the use of Perl is forbidden on this project."
There are lots of alternatives to $count += !! (some_expression)
to count occurrences of truthy values of that expression. One is the ternary, $count += (some_expression) ? 1 : 0
. That too is a bit obscure. There is a nice compact way to do what you want, which is to use the post-if:
$x++ if some_expression;
This says exactly what you are doing.