2010-01-30 3 views
33

Dans le code ci-dessous, à partir d'un blog post by Alias, j'ai remarqué l'utilisation du double point d'exclamation !!. Je me demandais ce que cela signifiait et où je pourrais aller dans le futur pour trouver des explications à la syntaxe Perl comme ça. (Oui, j'ai déjà recherché !! au perlsyn).Que fait !! (double point d'exclamation) signifie?

package Foo; 

use vars qw{$DEBUG}; 
BEGIN { 
    $DEBUG = 0 unless defined $DEBUG; 
} 
use constant DEBUG => !! $DEBUG; 

sub foo { 
    debug('In sub foo') if DEBUG; 

    ... 
} 

MISE À JOUR
Merci pour toutes vos réponses.

Voici quelque chose d'autre que je viens de découvrir ce qui est lié The List Squash Operator x!!

+4

Si vous pensez que '!!' est un opérateur amusant, essayez l'opérateur '->' dans une boucle for. :) – Ether

+0

Ether, pouvez-vous poster un lien vers l'opérateur ->? Je ne sais pas comment le trouver sur google. – Geo

+0

@Geo: ici vous allez (vous allez rire, ne me détestez pas): http://stackoverflow.com/questions/1642028/what-is-the-name-of-this-operator – Ether

Répondre

47

Il est juste deux ! opérateurs booléens non assis côte à côte. La raison d'utiliser cet idiome est de s'assurer que vous recevez un 1 ou un 0. En fait, il renvoie une chaîne vide qui vaut 0. Il est généralement utilisé uniquement dans un contexte numérique ou booléen.

Vous verrez souvent cela dans Code Golf compétitions, car il est plus court que d'utiliser l'opérateur ternaire avec ? :1 et 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 
+9

En fait, j'utilise souvent '!!!!' dans mon code, parce que '!!' confond la coloration syntaxique de vim et un autre '!! 'va le restaurer! – Ether

+26

@Ether: * Évidemment *, vous devez utiliser emacs. :) –

+10

Il produit 1 ou la valeur false canonique, pas 0. Ceci est 0 dans un contexte numérique mais la chaîne vide dans un contexte de chaîne. Pour obtenir 0 ou 1, utilisez l'opérateur '1-!' :) – ysth

12

non pas.

Il convertit la valeur en une valeur booléenne (ou aussi proche que Perl obtient une telle chose).

+4

C'est aussi un idiome courant dans d'autres langages aussi comme Javascript. – mpeters

+0

@David Dorward Merci pour votre réponse! –

-1

parce que trois autres réponses affirment que la gamme est « 0 » ou « 1 », je pensais juste que je mentionne que booléens en Perl (comme retourné par les opérateurs comme ==, not, etc.) sont undef et 1, et non 0 et 1.

+3

Ce n'est pas correct. Lorsqu'un opérateur doit générer une valeur false, il utilise une valeur magique qui évalue comme la chaîne vide dans le contexte de chaîne ou 0 dans un contexte numérique. (Les exceptions sont des opérateurs comme 'and' et' or', qui retournent simplement l'opérande qui les a renvoyés faux.) (Voir http://perldoc.perl.org/perlsyn.html#Truth-and-Falsehood) – cjm

+2

undef est aussi une valeur magique qui évalue comme '' dans un contexte de chaîne et 0 dans un contexte numérique - la seule différence est que lorsque les avertissements sont activés, utiliser undef pour sa chaîne ou sa valeur numérique est susceptible de produire un avertissement, alors que 'la valeur false' ne le fait pas;) – hobbs

+2

@hobbs: Eh bien, une autre différence est que 'defined (undef)' est faux , mais 'defined (1 == 2)' est vrai. – cjm