60 votos

¿Qué significa "0 pero cierto" en Perl?

¿Alguien puede explicar lo que exactamente la cadena "0 pero cierto" significa en Perl? En cuanto a lo entiendo, es igual a cero en una comparación de enteros, pero se evalúa como verdadera cuando se utiliza como un valor booleano. ¿Es correcto? ¿Este es un comportamiento normal de la lengua o un especial cadena tratado como un caso especial en el intérprete?

57voto

Chris Jester-Young Puntos 102876

Es el comportamiento normal de la lengua. Citando perlsyn manual:

El número 0, las cadenas de caracteres '0' y ", la lista vacía "()", y "undef" son todos falsos en un contexto booleano. Todos los demás valores son true. La negación de un verdadero valor "!" o "no" devuelve un especial valor false. Cuando se evaluó como una cadena es tratada como ", sino como un número, es considera 0.

Debido a esto, debe haber una forma de devolver el 0 de un sistema de llamada que espera devolver 0 como (con éxito) el valor de retorno, y se deja un camino a la señal de un fracaso caso por el hecho de devolver un valor false. "0 but true" cumple ese propósito.

52voto

geekosaur Puntos 26170

Porque es codificados en el núcleo de Perl para tratar como un número. Este es un hack para hacer Perl convenios y ioctl's convenios de jugar juntos; a partir de perldoc -f ioctl:

El valor de retorno ioctl (y fcntl) es la siguiente:

if OS returns:      then Perl returns:

    -1              undefined value
     0              string "0 but true"
anything else       that number

Así Perl devuelve true en caso de éxito y false en caso de error, sin embargo, todavía puede determinar fácilmente el valor real devuelto por la sistema operativo:

$retval = ioctl(...) || -1;
printf "System returned %d\n", $retval;

El especial de la cadena "0 but true" está exento de -wquejas sobre inadecuado conversiones numéricas.

45voto

moritz Puntos 6295

Además de lo que otros dijeron, "0 but true" es especial con grafía en eso no advierte en contexto numérico:

$ perl -wle 'print "0 but true" + 3'
3
$ perl -wle 'print "0 but crazy" + 3'
Argument "0 but crazy" isn't numeric in addition (+) at -e line 1.
3

32voto

David W. Puntos 49436

El valor 0 but true es un caso especial en Perl. A pesar de su simple mortal ojos, no se ve como un número, sabio y omnisciente Perl entiende lo que realmente es un número.

Tiene que ver con el hecho de que cuando un Perl subrutina devuelve un valor de 0, se supone que la rutina de error o devuelve un valor false.

Imagine que tiene una subrutina que devuelve la suma de dos números:

die "You can only add two numbers\n" if (not add(3, -2));
die "You can only add two numbers\n" if (not add("cow", "dog"));
die "You can only add two numbers\n" if (not add(3, -3));

La primera declaración no se van a morir porque la subrutina devolverá 1. Eso es bueno. La segunda declaración se va a morir porque la subrutina no será capaz de agregar vaca para perro.

Y, el tercer estado?

Hmmm, me puede agregar 3 a -3. Acabo de llegar de 0, pero luego mi programa va a morir aunque la add subrutina de trabajo!

Para evitar esto, Perl considera 0 but true a ser un número. Si mis agregar subrutina devuelve no sólo 0, pero 0 pero cierto, mi tercera declaración de voluntad de trabajo.

Pero es 0 pero cierto, un cero? Pruebe estos:

my $value = "0 but true";
print qq(Add 1,000,000 to it: ) . (1_000_000 + $value) . "\n";
print "Multiply it by 1,000,000: " . 1_000_000 * $value . "\n";

Sí, es cero!!!

El índice de subrutina es una muy vieja pieza de Perl y existía antes de que el concepto de 0 pero cierto era de alrededor. Se supone que debe volver a la posición de la subcadena encuentra en la cadena:

index("barfoo", "foo");   #This returns 3
index("barfoo", "bar");   #This returns 0
index("barfoo", "fu");    #This returns ...uh...

La última declaración devuelve un -1. Lo que significa que si yo hice esto:

if ($position = index($string, $substring)) {
   print "It worked!\n";
}
else {
   print "If failed!\n";
}

Como hago normalmente con las funciones estándar, no funcionaría. Si he utilizado "barfoo" y "bar" como yo lo hice en la segunda declaración, La else cláusula de ejecutar, pero si he utilizado "barfoo" y "fu" como en la tercera, la if cláusula de ejecutar. No lo quiero.

Sin embargo, si el index subrutina devuelve 0 pero cierto para la segunda instrucción y undef para la tercera declaración, mi if/else cláusula de haber trabajado.

24voto

Andy Lester Puntos 34051

También puede ver la cadena "0E0" utilizado en código Perl, y significa la misma cosa, donde 0E0 significa 0 escritas en notación exponencial. Sin embargo, puesto que Perl sólo considera "0", '' o undef como falsa, se evalúa como true en un contexto booleano.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X