mSL – Sentencias if-then-else y el método $iif(…)

Este pequeño tutorial es para inducir al mIRC Scripter novato a equilibrar el uso de sentencias if-then-else junto al método $iif(…) cuando sea conveniente y\o posible, o quizás sencillamente cuando quede mas prolijo por el bien de la legibilidad de su script o la simple estética… XD.
Podemos “ahorrar” unos cuantos bytes e innecesarias { } que pueden consumir CPU injustificadamente reduciendo la efectividad del Script.
A continuación un repaso de la sintaxis y el uso para la Sentencia y el Método…

Sentencia If-Then-Else


Las Estructuras de Control If-Then-Else, son bifurcaciones, también llamadas Sentencias Condicionales o de Lógica Booleana, y forman parte de los principios de la Programación Estructurada moderna. Son una de las cosas mas útiles en mSL, y mejor dicho en cualquier lenguaje de programación.
Gracias a estas Sentencias podemos modificar el flujo de ejecución de las instrucciones en nuestro Script tanto en rutinas como en eventos, hay que destacar también que estas Sentencias se pueden encestar infinitamente una adentro de otra.
Otro tipo de Estructura de Bifurcación seria Case Switch pero no es nativa en mSL.
Si bien la sintaxis puede variar de lenguaje en lenguaje yo voy a hacer referencia aquí a la sintaxis en mSL que es el tema que nos concierne…

-Sintaxis de una Sentencia If-Then-Else:

.En Teoria:

IfSi la condición se cumple…
ThenEjecutar instrucciones
ElseSino ejecutar otras instrucciones

En Practica:

 if ( Condición 1 ) {
    /*
    [Instrucciones 1]
    -Se ejecutan en caso de que se cumpla la Condición 1
    -Luego de ejecutarse... el Script ignora los demás Else IF y el Else para continuar su curso...
    NOTA: NO IGNORA otros If, a estos también los verifica en caso de que hubieran
    */
  }
  else if ( Condición 2 ) {
    /*
    [Instrucciones 2]
    -Se ejecutan en caso de que se cumpla la Condición 2
    -Ocurre lo mismo que en If...
    */
  }
  else {
    /*
    [Instrucciones 3]
    -Se ejecutan en caso de que no se cumpla ninguna Condición anterior
    -Luego de ejecutarse... el Script continua su curso...
    */
  }

Ahora veamos mas de cerca de que trata una Condición en una Sentencia If-Then-Else…

-Condición simple o ideal:
… ( Esto es una Condición ) { … }
… ( Valor1 Operador Valor2 ) { … }

… ( 1 == 0 ) { … }
Tenemos solo una Condición: comparamos un valor con otro utilizando lo que se llama un Operador Relacional.

Operadores Relacionales mas usados:

Operador En Sintaxis Resulta Verdadero
== (V1 == V2) si V1 es igual a V2
=== (V1 === V2) si V1 es igual a V2 (Caso sensitivo)
!= (V1 != V2) si V1 no es igual a V2
!== (V1 !== V2) si V1 no es igual a V2 (Caso sensitivo)
< (V1 < V2) si V1 es menor que V2
<= (V1 <= V2) si V1 es menor o igual que V2
> (V1 > V2) si V1 es mayor que V2
>= (V1 >= V2) si V1 es mayor o igual que V2
isIn (V1 isIn V2) si V1 esta comprendido en V2
isInCS (V1 isInCS V2) si V1 esta comprendido en V2 (Caso sensitivo)
isWm (V1 isWm V2) si *V1* comodin esta comprendido en V2
isWmCS (V1 isWmCS V2) si *V1* comodin esta comprendido en V2 (Caso sensitivo)
isOn (V1 isOn V2) si V1 esta en canal #V2
isOp (V1 isOp V2) si V1 es operador en canal #V2

Nota:
* Se puede usar el prefijo “!” para negar un Operador Relacional y lograr el resultado inverso, Ejemplo: !isIn
* El sulfijo “CS” en un Operador Relacional indica Caso sensitivo, Ejemplo: isWmCS
* Hay muchos mas… pero estos son los mas usados y sencillos de usar.

-Condición multiple u compleja:
… ( Esto es una Condición ) Operador ( Esto es otra Condición ) { … }
… ( Valor1 Operador Valor2 ) Operador ( Valor3 Operador Valor4 ) { … }

… ( ( 1 == 0 ) || ( 2 > 3 ) ) { … }
… ( ( 1 == 0 ) && ( 2 > 3 ) ) { … }

… ( ( 1 == 0 ) && ( 2 > 3 || 4 < 5 ) ) { … }

Podemos declarar una Sentencia con multiples Condiciones pero aquí entran en juego los Operadores Lógicos. Incluso podemos usar multiples Operadores Relacionales entre multiples y diversos Operadores Lógicos.

Operadores Lógicos:

Operador Nombre En Sintaxis Resultado
&& AND (y…) ( (V1 Op1 V2) && (V1 Op2 V2)) Sentencia verdadera solo si Op1 y Op2 son TRUE
|| OR (ó…) ( (V1 Op V2) || (V1 Op V2)) Sentencia verdadera si Op1 u Op2 son TRUE

.Ejemplos:

-Sentencia con Condición simple:

  if ( Nick isOn #Channel ) {
    ;notificamos que Nick esta en el canal #Channel
    echo -a ***Nick esta en #Channel
  }
  else if ( Nick isOn #Channel2 ) {
    ;notificamos que Nick esta en el canal #Channel2
    echo -a ***Nick esta en #Channel2
  }
  else {
    ;notificamos que Nick no esta ni en #Channel ni en #Channel2
    echo -a ***Nick no esta en #Channel o en #Channel2 !
  }

-Sentencia con Condición multiple tipica:

  if ( ( Nick isOn #Channel ) && ( Nick isOp #Channel ) ) {
    ;notificamos que Nick esta en el canal #Channel solo si es operador
    echo -a ***Nick esta en #Channel
  }
  else if ( ( Nick isOn #Channel2 ) && ( Nick isVoice #Channel2 ) ) {
    ;notificamos que Nick esta en el canal #Channel2 solo si tiene voz
    echo -a ***Nick esta en #Channel2
  }
  else {
    ;notificamos que Nick no no esta ni en en #Channel ni en #Channel2 porque no tiene privilegios
    ;*...Sin embargo puede estar en alguno de esos canales como usuario normal...*
    echo -a ***Nick no esta en #Channel o en #Channel2 !
  }

-Sentencia con Condición multiple y Multiples Operadores Lógicos:

  if ( ( Nick isOn #Channel ) && ( Nick isOp #Channel || Nick isVoice #Channel ) ) {
    ;notificamos que Nick esta en el canal #Channel solo si es operador o si tiene voz
    echo -a ***Nick esta en #Channel
  }
  else if ( ( Nick isOn #Channel2 ) && ( Nick isOp #Channel2 || Nick isVoice #Channel2 ) ) {
    ;notificamos que Nick esta en el canal #Channel2 solo si es operador o si tiene voz
    echo -a ***Nick esta en #Channel2
  }
  else {
    ;notificamos que Nick no no esta ni en en #Channel ni en #Channel2 porque no tiene privilegios
    ;*...sin embargo puede estar en alguno de esos canales como usuario normal...*
    echo -a ***Nick no esta en #Channel o en #Channel2 !
  }

En estos tres ejemplos considerados vemos que son similares, pero NO IGUALES, y vemos que el uso de los Operadores Lógicos como el “&&” o el “||” entre múltiples Condiciones puede alterar, y mucho, el resultado de una Sentencia y por ende el comportamiento de tu Script. Lo cual puede terminar siendo objeto de errores (BUGS!).

Suficiente de If-Then-Else para ser solo un repaso… vamos a pasar a lo siguiente…

Método\Identificador $iif(…)


Anteriormente vimos lo que podemos llamar: forma estándar o convencional de una Sentencia If-Then-Else.
Ahora vamos a conocer lo que yo denomino Método $iif(…) en mSL, que debería de llamar Identificador, el cual no es en realidad un Método (en términos de programación general), de hecho su significado nos dice todo: $iif = Inmediate If. Traduscamoslo en nuestro Español como Sentencia If-Then-Else Inmediata.
Esta presente en varias ediciones del lenguaje Visual Basic donde se le clasifica como “Función”, y también esta en lenguajes basados en C. Su sintaxis es idéntica en mSL como en VB.
Como conclusión es simplemente una forma alternativa de invocar una Sentencia If-Then-Else en una sintaxis mas corta y practica, voy a referirme a la misma con el termino “método” simplemente porque es breve y me gusta….

-Sintaxis del método $iif(…):

En Teoria:

IfSi la condición se cumple…
ThenEjecutar parte verdadera
ElseSino ejecutar parte falsa

.En Practica:

$iif( Condición, Parte Verdadera, Parte Falsa)

Veamos de cerca como es una Condición para el método $IIf…

-Condición simple o ideal:
…( Esto es una Condición, ……., ……..)
…( Valor1 Operador Valor2, ……., ……..)

…( 1 == 0 , ……., ……..)

Una Condición aquí se utiliza exactamente igual que en la sentencia If-The-Else… excepto por la falta de paréntesis () propios de la condición. Los () que ves son los delimitadores de la sintaxis.
Los Operadores Relacionales disponibles son los mismos que se pueden usar en una Sentencia If-Then-Else Standard y el uso del prefijo ! y el sufijo CS también es valido.

-Condición multiple u compleja:
…( Esto es una Condición Operador Esto es otra Condición, ……., ……..)
…( Valor1 Operador Valor2 Operador Valor3 Operador Valor4, ……., ……..)

…( 1 == 0 || 2 > 3 , ……., ……..)
…( 1 == 0 && 2 > 3 , ……., ……..)

…( 1 == 0 && ( 2 > 3 || 4 < 5 ), ……., ……..)

En este caso también podemos declarar el método con multiples Condiciones determinadas por multiples i diversos Operadores Lógicos al igual que en la sentencia If-The-Else. Los () de las Condiciones aquí tampoco son necesarios… a menos que hubiera multiples Operadores Lógicos entre las multiples Condiciones.
Los Operadores Lógicos disponibles son los mismos que se pueden usar en una Sentencia If-Then-Else Standard.

Ejemplos:

-Método $iif(…) con Condición simple:

  $iif(Nick isOn #Channel, echo -a ***Nick esta en #Channel, echo -a ***Nick no esta en #Channel)
  ;notificamos que Nick esta en el canal #Channel, en el caso de que estuviera, y lo contrario si no estuviera...

La sintaxis anterior demasiado precaria… y aun así estamos ahorrando espacio. Ejecutar esto desde la línea de comando mediante el prefijo “//” no funciona, pero si funciona desde un Script Remoto.
Dado que $iif(…) no es una /Instrucción y en realidad en el entorno de mSL es un Identificador vamos a usarlo de la siguiente forma que seria lo correcto e ideal:

  echo -a ***Nick $iif(Nick isOn #Channel, esta en #Channel, no esta en #Channel)

Ahora vemos lo útil que puede ser y porque podemos ahorrar espacio usando esta versión “Inmediata” de una Sentencia If-Then-Else

-Método $iif(…) con Condición multiple típica:

  echo -a ***Nick $iif(Nick isOn #Channel && Nick isop #Channel, esta en #Channel, no esta en #Channel)
  ;notificamos que Nick esta en el canal #Channel solo si es operador,  si fuera un usuario normal nos
  ;notificaria que no esta en el #Canal...  aunque en realidad podría estar

-Método $iif(…) con Condición multiple y Multiples Operadores Lógicos:

  echo -a ***Nick $iif(Nick isOn #Channel && (Nick isOp  #Channel || Nick isVoice #Channel), esta en #Channel, no esta en  #Channel)
  ;notificamos que Nick esta en el canal #Channel solo  si es operador o si tiene voz, si
  ;fuera un usuario normal nos notificaría que no esta en el #Canal... aunque en realidad podría estar

Notar en este ejemplo la necesidad de paréntesis () propios de al menos una de las condiciones.

Identificadores $V1 y $V2


Los Identificadores $V* nos retornan el valor de los parámetros en una Condición permitiéndonos acceder rápida y prácticamente al valor de dichos parámetros PERO SOLO mientras estemos dentro de las instrucciones ejecutadas. Es decir al igual que las variables este Identificador tiene lo que llamamos Ámbito, Visibilidad o Scope (términos generales de programación), lo cual nos determina su alcance en el Script, y podemos decir que es de carácter Local ya que como dije anteriormente solo se podrá acceder a su valor mientras estemos dentro de las instrucciones ejecutadas. Y se comprende también que al declarar otra Condición en las mismas instrucciones reemplazaría su valor por otro nuevo.
Funciona igualmente tanto en Sentencias If-Then-Else como en el método $IIf(…)

$V1 Primer parametro
$V2 Segundo parametro

Ejemplos:

If ( 1 == 2 ) { … } | Else { … }
$V1 = 1
$v2 = 2

$IIf(A == B, …, …)
$V1 = A
$v2 = B

Cuando tenemos múltiples Condiciones el identificador $V* toma los parámetros de la ultima Condición declarada, véase a continuación…

If ( 1 == 2 ) || ( 2 == 3 ) || ( 3 == 4 ) { … } | Else { … }
$V1 = 3
$v2 = 4

$IIf(A == B || B == C || C == D, …, …)
$V1 = C
$v2 = D

Negando expresiones Booleanas con el prefijo “!”


El prefijo “!” es en realidad un Operador Lógico, no lo dije antes para no confundir, ya que no se utiliza en el mismo lugar que los demás de su tipo sino que se utiliza como prefijo en un Operador Relacional, o como prefijo directamente en una Condición a la cual negaría en caso de que fuera verdadera. Podría implementarse para evitar tener que usar un Else si se sabe que se espera que la condición sea verdadera, o bien para reducir espacio en la declaración de la condición.
En otras palabras el hecho de usar ese prefijo indicaría que se busca que la Condición sea falsa y si no lo usamos es porque estamos buscando que sea verdadera.
En esta sección ya no vamos a hacer referencia a su uso sobre un Operador Relacional porque ya lo vimos anteriormente en la tabla (Ejemplo: !isIn), vamos a ver como se puede utilizar directamente sobre una Condición.
Funciona igualmente tanto en Sentencias If-Then-Else como en el método $IIf(…)

Ejemplos:

   if ( %a == $false ) { ... } | else { ... }  -->    if ( !%a ) { ... } | else { ... }
   if ( %a == $null ) { ... } | else { ... }    -->    if ( !%a ) { ... } | else { ... }

   $iif(%a == $false, ..., ...)                -->    $iif(!%a, ..., ...)
   $iif(%a == $null , ..., ...)                 -->    $iif(!%a, ..., ...)

También podemos entender entonces que una Condición sin el prefijo ! equivale naturalmente a la expresión inversa veridica…

  if ( %a == $true ) { ... } | else { ... }  -->    if ( %a ) { ... } | else { ... }
  if ( %a != $null  ) { ... } | else { ... }    -->    if ( %a ) { ... } | else { ... }

  iif(%a == $true, ..., ...)                  -->    $iif(%a, ..., ...)
  iif(%a != $null, ..., ...)                    -->    $iif(%a, ..., ...)

Depurando


Veamos algunos errores de comprensión y de sintaxis. Y creo que esta de más decir que solo los errores de sintaxis dan error por parte del Engine del mSL, en cambio ante un error de comprensión no tendremos notificación alguna y simplemente nuestro Script no funcionara como quisiéramos dando malos resultados y decepcionándonos:

Error de comprensión usando diversas sentencias
Vamos a aclarar un error que los Scripters mas novatos suelen cometer…
Cuando usamos “else if” estamos verificando solo por esa condición y ninguna mas a su continuación.

Es decir… Considere esto:

  if ( Condición 1 )
  else if ( Condición 2 )
  else if ( Condición 3 )
  else if ( Condición 4 )
  else

Esta Sentencia solo verificara por una Condición hasta llegar a Else…

Que no es lo mismo que… Considerar esto:

  if ( Condición 1 )
  if ( Condición 2 )
  if ( Condición 3 )
  if ( Condición 4 )
  else

Esta Sentencia verificara por todas las Condiciones hasta llegar a Else…
Y obviamente el uso de Else podría no ser necesario.

Interesante es decir que el segundo caso considerado usualmente en tiempo de ejecución demora mas que el primer caso ya que tiene que verificar todas las condiciones antes de llegar a Else o el final.
En el primer caso donde se encuentre una condición que cumpla se ejecuta y sale de la Estructura para continuar con el Script ignorando los otros Else Ifs y el Else si hubiera.

Error de sintaxis al hacer mal o ningún uso de paréntesis ()
Cuando se trata de Condiciones complejas sin importar si estamos utilizando Sentencias If-Then-Else o el Método $IIf(..) debemos de utilizar paréntesis() propios de la Condición. Es la mejor manera de mostrarle exactamente al Engine del mSL lo que queremos que este interprete. De hecho los () no son estrictamente necesarios pero se recomienda a los mas novatos a usarlos por el bien de la legibilidad de su Script.

.Error de sintaxis usando Sub-Operadores
También suele verse la mala utilización de los Sub-Operadores “<=” y “>=” . Véase la siguiente tabla:

Incorrecto Correcto
( V1 =< V2 ) ( V1 <= V2 )
( V1 => V2 ) ( V1 >= V2 )

Sacando Conclusiones


Para el que llego hasta aquí si presto atención debería de haber notado que el método $iif() en su sintaxis típica tiene la desventaja de poder ejecutar solo dos partes (Una verdadera y la otra falsa).
Como si eso fuera poco, solo puede ejecutar UNA INSTRUCCIÓN en cualquiera de esas dos partes.
Y es que en realidad yo utilicé a propósito como sintaxis ideal de la sentencia If-Then-Else una forma extendida… por lo que le deje en evidente ventaja a la Sentencia sobre el Método:
Primero considere:

  if ( Condición ) {
    /*
    [Instrucciones 1]
    -Se ejecutan en caso de que se cumpla la Condición
    -Luego de ejecutarse... el Script continua su curso...
    */
  }
  else {
    */
    [Instrucciones 3]
    -Se ejecutan en caso de que no se cumpla la Condición anterior
    -Luego de ejecutarse... el Script continua su curso...
    */
  }

Aquí ya no estamos tomando la posibilidad de considerar varias Condiciones… como lo ice hoy al al principio de este tutorial… esta es la verdadera Sintaxis típica para una Sentencia If-Then-Else, porque cumple exactamente con lo que la teoría nos explica…

IfSi la condición se cumple…
ThenEjecutar instrucciones
ElseSino ejecutar otras instrucciones

Resumiendo solo hay dos posibilidades… solo ser verifica por una condición… acá no hay Else Ifs… y cuando declaramos Sentencias If-Then-Else tan básicas nisiquiera son necesarias las las llaves { } de ambas partes, a menos que hubiera varias instrucciones para ejecutar.

Ahora considere:

   $iif(Condición, Parte Verdadera, Parte Falsa)

Vemos que es exactamente lo mismo pero en una línea, con la limitación de solo poder ejecutar una instrucción.

Igualmente podemos imitar una sentencia If-Then-Else compleja con el método $iif(…). Voy a utilizar el siguiente ejemplo que fue el caso mas complejo que vimos:

  if ( ( Nick isOn #Channel ) && ( Nick isop #Channel || Nick isVoice #Channel ) ) {
    ;notificamos que Nick esta en el canal #Channel solo si es operador o si tiene voz
    echo -a ***Nick esta en #Channel
  }
  else if ( ( Nick isOn #Channel2 ) && ( Nick isop #Channel2 || Nick isVoice #Channel2 ) ) {
    ;notificamos que Nick esta en el canal #Channel2 solo si es operador o si tiene voz
    echo -a ***Nick esta en #Channel2
  }
  else {
    ;notificamos que Nick no no esta ni en en #Channel ni en #Channel2 porque no tiene privilegios
    ;*...sin embargo puede estar en alguno de esos canales como usuario normal...*
    echo -a ***Nick no esta en #Channel o en #Channel2 !
  }

En este caso tuvimos en cuenta la posibilidad de verificar en #Channel y en #Channel2 para luego en caso de que ninguno cumpla con la condición ejecutar un else… y a primera vista esto no parece posible de realizarse con $iif(…), sin embargo lo que no mencione antes es que los $iif(…) se pueden encestar tanto como sea necesario al igual que las sentencias.

Con el Método $iif(…) quedaría de la siguiente forma:

  echo -a ***Nick $iif(Nick isOn #Channel && (Nick isOp #Channel ||  Nick isVoice #Channel), esta en #Channel, $iif(Nick isOn #Channel2  && (Nick isOp #Channel2 || Nick isVoice #Channel2), esta en  #Channel2, no esta en #Channel o en #Channel2 !))

Por las dudas…


Bueno, si alguien todavía tiene alguna duda (aunque no lo creo), doy por ultimo otros simples ejemplos para poder terminar de comprender el tema:

Con una Sentencia If-Then-Else estándar:

Prueba1 {
  var %a = $?="Un número:"
  var %b = $?="Otro número:"
  if        %a > %b echo -s Resultado: %a es mayor que %b
  else if   %a < %b echo -s Resultado: %a es menor que %b   
  else              echo -s Resultado: %a es igual que %b 
} 

Con una Sentencia If-Then-Else inmediata:

 
Prueba2 {   
  var %a = $?="Un número:"   
  var %b = $?="Otro número:"   
  echo -s Resultado: %a es $iif(%a > %b, mayor, $iif(%a < %b, menor, igual)) que %b
}

Otro Pequeño Ejemplo $iif(…):

  //echo -a $iif($?="Escribe Algo:" == $?="Escribe Algo:", $Verdadero, $Falso)

Aquí una tabla con el resultado de posibles multiples Condiciones con multiples Operadores Lógicos…

  if ($True) && ($True) { ... } | ;Veradero
  ;-
  if ($True) && ($False) { ... } | ;Falso
  ;-
  if ($False) && ($False) { ... }  | ;Falso
  ;-
  if ($True) || ($True) { ... } | ;Verdadero
  ;-
  if ($True) || ($False) { ... } | ;Falso
  ;-
  if ($False) || ($False) { ... } | ;Verdadero
  ;-
  if ($True) || ($False) && ($True) { ... } | ;Verdadero
  ;-
  if ($True) || ($False) && ($False) { ... } | ;Verdadero
  ;-
  if ($False) || ($True) || ($False) { ... } | ;Falso
  ;-
  if ($True) && ($False) && ($False) { ... } | ;Falso

Nota: Algunos ejemplos son meramente explicativos.


, , , , , ,

  1. Deja un comentario

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

A %d blogueros les gusta esto: