Los diversos operadores lógicos no devuelven una cadena vacía, devuelven un valor falso o verdadero en los tres tipos escalares simples. Sólo se ve como que devuelve una cadena vacía porque print
fuerza un contexto de cadena en sus argumentos:
#!/usr/bin/perl
use strict;
use warnings;
use Devel::Peek;
my $t = 5 > 4;
my $f = 5 < 4;
Dump $t;
Dump $f;
Salida:
SV = PVNV(0x100802c20) at 0x100827348
REFCNT = 1
FLAGS = (PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 1
NV = 1
PV = 0x100201e60 "1"\0
CUR = 1
LEN = 16
SV = PVNV(0x100802c40) at 0x100827360
REFCNT = 1
FLAGS = (PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x100208ca0 ""\0
CUR = 0
LEN = 16
Para aquellos que no están familiarizados con los Perl 5 partes internas, un PVNV
es un escalar estructura que contiene los tres tipos escalares simples (número entero IV
, flotador de precisión doble NV
y cadena PV
). Los indicadores IOK
, NOK
y POK
significan que los valores enteros, dobles y de cadena están todos sincronizados (para alguna definición de sincronización) por lo que cualquiera de ellos puede usarse (es decir, no es necesario realizar conversiones si lo usa como un entero, doble o cadena).
Supongo que se eligió la cadena vacía para la cadena falsa porque
es más pequeña y
es más acorde con la idea de una cadena falsa que "0"
. Ignore mi afirmación de que es más pequeño, tanto ""
como "1"
tienen el mismo tamaño: dieciséis caracteres. Dice tan bien en el basurero. Perl 5 agrega espacio extra a las cadenas para permitirles crecer rápidamente.
Oh, y te odio. Al investigar esto, he descubierto que he mentido en perlopquick
y ahora tendré que encontrar la manera de solucionarlo. Si solo hubieras sido como todas las otras ovejas y hubieras aceptado la rareza superficial de Perl 5 como un hecho, tendría menos trabajo que hacer.
Las respuestas a las preguntas en la sección EDIT:
¿Cómo sería el uso de cuerdas que es verdadero ("falsa", por ejemplo) como una representación de cadena de falsos valores cambian el significado del código existente?
Las únicas cosas especiales acerca de acerca de PL_sv_yes y PL_sv_no (los valores verdaderos y falsos canónicamente devueltos por los operadores de comparación) son que son de sólo lectura y son creados por perl
no el programa que se está ejecutando. Si los modifica, no cambia la prueba de veracidad, por lo que un PL_sv_no que se establece en "false"
se tratará como verdadero. Incluso se puede hacer esto por sí mismo (el código deja de funcionar en algún punto entre Perl 5.18 y la última Perl) con características no documentadas de perl
:
#!/usr/bin/perl
use strict;
use warnings;
use Scalar::Util qw/dualvar/;
BEGIN {
# use the undocumented SvREADONLY function from Internals to
# modify a reference to PL_sv_no's readonly flag
# note the use of & to make the compiler not use SvREADONLY's
# prototype, yet another reason prototypes are bad and shouldn't
# be used
&Internals::SvREADONLY(\!!0, 0);
# set PL_sv_no to a dualvar containing 0 and "false"
${\!!0} = dualvar 0, "false";
}
if (5 < 4) {
print "oops\n";
}
salidas
opps
Esto se debe a las miradas de prueba truthiness en cuerdas primero.
¿Podríamos decir que el código que cambia la semántica después de dicho cambio es menos robusto/correcto de lo que podría haber sido?
Será directamente roto. Incluso si se limita a configurarlo en un int 0 o en una cadena "0" (ambos son falsos), romperá algún código válido.
supongo contexto de cadena es tan penetrante en Perl que la única opción que lleva a la semántica cuerdo es si el valor booleano preservar su valor después de la ida y vuelta hacia y desde una cadena ...
Sí.
Posible duplicado de [¿Por qué! 1 no me da nada en Perl?] (Http://stackoverflow.com/questions/1134962/why-does-1-give-me-nothing-in-perl) – Thilo