2012-09-25 13 views
13

Durante el proceso de prueba de mi código Perl usando "Smart Match (~~)" me he enfrentado a este problema. ¿Habrá alguna diferencia entre 42, 42.0, "42,0", "42"¿Habrá alguna diferencia entre 42, 42.0, "42.0", "42"

$var1 = "42"; 
$var2 = "42.0"; 
$a = $var1 ~~ $var2; 

estoy recibiendo $a como 0; lo que significa $var1 y $var2 no son iguales.

Por favor, explíquelo.

+1

No, son todas LA RESPUESTA. ;) –

Respuesta

26

El operador de coincidencia inteligente "generalmente hará lo que quiera". Por favor, lea esto como "no siempre".

42 ~~ 42.0 devuelve true.

42 ~~ "42.0" devuelve true también: la cadena se compara con un número y, por lo tanto, se ve como un número. Ídem para "42" ~~ 42.0.

"42" ~~ "42.0" devuelve false: ambos argumentos son cadenas, y estas cadenas no se pueden comparar como "iguales", aunque su significado numérico sí lo haría. No querrá que Perl vea "two" ~~ "two-point-oh" como verdadero.

Una cadena puede ser forzado a que es la interpretación numérica mediante la adición de cero:

0+"42" ~~ "42.0" devuelve true de nuevo, como la primera cadena se ve obligado a 42 el número, y el segundo hace lo mismo.

El perldoc perlsyn o perldoc perlop page define cómo funciona Smart Matching:

 Object Any  invokes ~~ overloading on $object, or falls back: 
     Any  Num  numeric equality   $a == $b 
     Num  numish[4] numeric equality   $a == $b 
     undef Any  undefined    !defined($b) 
     Any  Any  string equality   $a eq $b 

se puede ver que la igualdad cadena es el valor predeterminado.

2

Escribiendo contextualmente.

$Var1 y $Var2 fueron utilizados como cadenas (en la cesión), por lo que ahora se comportan como cadenas. ~~ hará una comparación de cadenas si ambos argumentos son cadenas.

Si utiliza uno de ellos como un número - que ni siquiera tiene que asignar a la misma - a continuación, se comportará como un número y ~~ utilizará una comparación numérica.

Este guión te mostrará NO YES:

my $v1 = "42"; 
my $v2 = "42.0"; 
print (($v1 ~~ $v2) ? 'YES ' : 'NO '); 

$v1 + 0; 
print (($v1 ~~ $v2) ? 'YES ' : 'NO '); 

Reference for ~~ operator

8

Es posible que desee reconsiderar el uso de fósforo inteligente por ahora. La comunidad Perl considera que la implementación actual es un error, entre otros debido a su pregunta y a la respuesta de Amon.

Se está trabajando para una versión más "sana" y más simple pero incompatible de la compatibilidad inteligente que podría estar en la próxima versión principal de Perl (5.18). Simplemente proscribirá su ejemplo: $ a ~~ $ b no se permitirá cuando $ b sea un valor escalar simple (como 42 o "42").

Si tiene demasiado tiempo en su mano, puede leer los archivos Perl5 porters, por ejemplo this thread.

Cuestiones relacionadas