Página 1 de 1

Operador "||=" vs "//="

NotaPublicado: 2021-02-21 09:08 @422
por MaterazziSan
Buenas.

Tengo una duda sobre estos operadores, por saber si son sinónimos o no. Entiendo que "//=" da un valor sólo si la variable es undef. ¿Ocurre lo mismo con "||="?

Por poner esto en un ejemplo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3.  use v5.28.1;
  4.  
  5.  sub get_sum {
  6.          my ($num1, $num2) = @_;
  7.          $num1 //= 100;
  8.          $num2 //= 100;
  9.          return  $num1 + $num2;
  10.  }
  11.  
  12.  sub get_sum2 {
  13.          my ($num1, $num2) = @_;
  14.          $num1 ||= 100;
  15.          $num2 ||= 100;
  16.          return  $num1 + $num2;
  17.  }
  18.  
  19.  say 'get_sum  = ', get_sum();
  20.  say 'get_sum2 = ', get_sum2();
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


Ambas imprimen "200" por pantalla pero tengo la duda de que sean operadores idénticos.

Gracias.

Re: Operador "||=" vs "//="

NotaPublicado: 2021-02-21 11:10 @507
por explorer
No, no son lo mismo.

El operador '||' es el comparador lógico "O", igual que "or", pero con un nivel de precedencia mayor.

Así, el resultado de estas operaciones es muy distinto (debido a la precedencia):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
perl -E '$x = 0 || 4; say $x'   # 4
perl -E '$x = 0 or 4; say $x'   # 0
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El operador '//' es el comparador lógico "definido-o". Este operador prueba si los argumentos están definidos o no, y no sus valores.

Por ejemplo, supongamos que en un programa quieres ver si el usuario te ha pasado un valor por argumento, y si no, tomar tú un valor por defecto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $número_de_caras_del_dado = $caras_indicadas_por_el_usuario || 6;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

En este código, si el usuario no indica ningún valor, la variable $caras_indicadas_por_el_usurio estará indefinida, por lo que el operador '||' la convertirá en número (0), y realizará la operación lógica, dejando 6 en $número_de_caras_del_dado.

Pero... ¿qué ocurre si el usuario indicó un 0, por ejemplo, para indicar que quiere terminar el programa? Pues que el operador '||' lo toma como valor y volvería a darle 6 a la variable con la que vamos a trabajar. En esta situación no queremos probar por el valor de lo que nos pasa el usuario, sino si está definido o no. Y si está definido, nos quedamos con ese valor.

En cambio, con este código
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $número_de_caras_del_dado = $caras_indicadas_por_el_usuario // 6;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

estamos diciendo que si el usuario no ha indicado nada (ni siquiera 0), entonces debemos tomar 6 como valor por defecto.

Otro ejemplo más claro es el que se comenta en la documentación: Cómo averiguar la ruta de nuestro directorio principal.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.      my $home =  $ENV{HOME}
  2.               // $ENV{LOGDIR}
  3.               // (getpwuid($<))[7]
  4.               // die "¡Eres un sintecho!\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El operador '//' va probando todas las expresiones (empezando por la izquierda) hasta encontrar la primera que esté definida. ¡Ojo!, puede estar definida, y aún así, ser un valor vacío. En el ejemplo, si $ENV{HOME} está definida (es decir, existe una variable $HOME en el entorno de variables exportadas por la shell), entonces el operador '//' se queda con el valor de $ENV{HOME} aunque éste esté vacío.

Más información, en tu propio ordenador con el comando perldoc perlop, y en la Web (traducido al español), buscando por "Defined-Or".

Haz la prueba en tu código: cambia las dos últimas líneas por estas, y verás que no sale el mismo resultado:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. say 'get_sum  = ', get_sum(0,0);
  2. say 'get_sum2 = ', get_sum2(0,0);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Re: Operador "||=" vs "//="

NotaPublicado: 2021-02-21 11:52 @536
por MaterazziSan
¡Muchas gracias de nuevo! Estaba buscando en la documentación oficial pero no era capaz a encontrarlo.

Muy buenos ejemplos y perfectamente explicado. Super claro :)