lenguaje - perl logo
¿Qué devuelven realmente las funciones de Perl que devuelven Boolean? (4)
Como esa es la página de manual del hombre, diría que no se especifica su valor de retorno exacto. Si la documentación de Perl habla de un valor booleano, entonces casi siempre se trata de evaluar dicho valor en un contexto booleano: if (defined ...)
o print while <>
etc. En tales contextos, varios valores se evalúan a un valor falso: 0
, undef
, ""
(cadenas vacías), incluso cadenas que equivalen a "0"
.
Todos los demás valores se evalúan como verdaderos en un contexto booleano, incluido el infame ejemplo "0 but true"
.
Como la documentación es tan vaga, nunca confié en que defined()
devuelva ningún valor específico para el caso indefinido. Sin embargo, siempre estará bien si simplemente usa defined()
en un contexto booleano sin compararlo con un valor específico.
OK: print "yes/n" if defined($var)
No portátil / a prueba de futuro: print "yes/n" if defined($var) eq ''''
o algo similar
La función definida de Perl (y muchas otras) devuelve "un valor booleano".
Dado que Perl en realidad no tiene un tipo booleano (y usa valores como 1 para verdadero y 0 o undef para falso ), ¿el lenguaje Perl especifica exactamente qué se devuelve para los valores booleanos? Por ejemplo, ¿ defined(undef)
return 0 o undef , y está sujeto a cambios?
Devuelven un valor falso especial que es "" en contexto de cadena pero 0 en contexto numérico (sin una advertencia no numérica). El verdadero valor no es tan especial, ya que es 1 en cualquier contexto. defined () no devuelve undef.
(Usted mismo puede crear valores similares con, por ejemplo, Scalar::Util::dualvar(0,"")
.
En casi todos los casos (es decir, a menos que haya una razón para hacer lo contrario), Perl devuelve uno de los dos escalares asignados estáticamente: &PL_sv_yes
(para verdadero) y &PL_sv_no
(para falso). Esto es ellos en detalle:
>perl -MDevel::Peek -e"Dump 1==1"
SV = PVNV(0x749be4) at 0x3180b8
REFCNT = 2147483644
FLAGS = (PADTMP,IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK)
IV = 1
NV = 1
PV = 0x742dfc "1"/0
CUR = 1
LEN = 12
>perl -MDevel::Peek -e"Dump 1==0"
SV = PVNV(0x7e9bcc) at 0x4980a8
REFCNT = 2147483647
FLAGS = (PADTMP,IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x7e3f0c ""/0
CUR = 0
LEN = 12
yes
es una var triple (IOK, NOK y POK). Contiene un entero con signo (IV) igual a 1, un número de punto flotante (NV) igual a 1 y una cadena (PV) igual a 1.
no
es también una var triple (IOK, NOK y POK). Contiene un entero con signo (IV) igual a 0, un número de punto flotante (NV) igual a 0 y una cadena vacía (PV). Esto significa que stringifica a la cadena vacía, y se numera a 0. No es equivalente a una cadena vacía
>perl -wE"say 0+(1==0);"
0
>perl -wE"say 0+'''';"
Argument "" isn''t numeric in addition (+) at -e line 1.
0
ni a 0
>perl -wE"say ''''.(1==0);"
>perl -wE"say ''''.0;"
0
No hay garantía de que este siempre sea el caso. Y no hay razón para confiar en esto. Si necesita valores específicos, puede usar algo como
my $formatted = $result ? ''1'' : ''0'';
Probablemente nunca cambie, pero perl no especifica el valor booleano exacto que defined(...)
.
Al usar valores booleanos, el código correcto no debe depender del valor real utilizado para verdadero y falso.
Ejemplo:
# not so great code:
my $bool = 0; #
...
if (some condition) {
$bool = 1;
}
if ($bool == 1) { ... }
# better code:
my $bool; # default value is undef which is false
$bool = some condition;
if ($bool) { ... }
99.9% de las veces no hay ninguna razón para preocuparse por el valor utilizado para boolean. Dicho esto, hay algunos casos en los que es mejor usar un 0 o 1 explícito en lugar de la booleanidad de un valor. Ejemplo:
sub foo {
my $object = shift;
...
my $bool = $object;
...
return $bool;
}
la intención es que foo()
se undef
con una referencia o undef
y devuelva false si $object
no está definido. El problema es que si se define $object
foo()
devolverá el objeto en sí y creará así otra referencia al objeto, lo que puede interferir con su recolección de elementos no utilizados. Entonces aquí sería mejor usar un valor booleano explícito aquí, es decir:
my $bool = $object ? 1 : 0;
Por lo tanto, tenga cuidado al usar una referencia para representar su veracidad (es decir, su definición) debido a la posibilidad de crear referencias no deseadas a la referencia.