Saltar al contenido principal
Versión: v20

Operadores

Un operador es un símbolo o un grupo de símbolos que utiliza para verificar, modificar o combinar los valores. Usted ya conoce a la mayoría de los operadores. Por ejemplo, 1 + 2 utiliza el operador de adición (o signo más) para sumar dos números, y el resultado es 3. Los operadores de comparación, como = o >, le permiten comparar dos o más valores.

El lenguaje 4D es compatible con los operadores que ya conoce de otros lenguajes como C o JavaScript. Sin embargo, el operador de asignación es := para evitar que se utilice de forma errónea cuando el operador "igual a" (=) está planeado. Los operadores básicos como los operadores aritméticos (+, -, *, /, %...) y los operadores de comparación (=, >, >=.) puede utilizarse con números, pero también con datos booleanos, textos, fecha, hora, puntero o imagen. Al igual que JavaScript, el lenguaje 4D soporta el concepto de valores truthy y falsy, que se utilizan en los operadores de corto-cicrcuit.

Terminología

El lenguaje 4D soporta los operadores binarios y ternarios:

  • los operadores binarios operan en dos objetivos (como 2 + 3) y aparecen entre sus dos objetivos.
  • los operadores ternarios operan en tres objetivos. Like C, 4D has only one ternary operator, the ternary conditional operator (a ? b : c).

Los valores que los operadores afectan son los operandos. En la expresión 1 + 2, el símbolo + es un operador binario y sus dos operandos son los valores 1 y 2.

Asignación

El operador de asignación (a:=b) inicializa o actualiza el valor de a con el valor de b:

$myNumber:=3 //assigns 3 to MyNumber variable  
$myDate:=!2018/01/21! $myNumber:=3 //assigns 3 to MyNumber variable
$myDate:=!2018/01/21! //assigns a date literal
$myLength:=Length("Acme") //assigns the result of the command (4) to $myLength
$col:=New collection //$col is initialized with an empty collection $myNumber:=3 //assigns 3 to MyNumber variable
$myDate:=!2018/01/21! //assigns a date literal
$myLength:=Length("Acme") //assigns the result of the command (4) to $myLength
$col:=New collection //$col is initialized with an empty collection $myNumber:=3 //assigns 3 to MyNumber variable
$myDate:=!2018/01/21! //assigns a date literal
$myLength:=Length("Acme") //assigns the result of the command (4) to $myLength
$col:=New collection //$col is initialized with an empty collection $myNumber:=3 //assigns 3 to MyNumber variable
$myDate:=!2018/01/21! //assigns a date literal
$myLength:=Length("Acme") //assigns the result of the command (4) to $myLength
$col:=New collection //$col is initialized with an empty collection

NO confunda el operador de asignación := con el operador de comparación de igualdad =. Se ha elegido deliberadamente un operador de asignación diferente (y no =) para evitar los problemas y la confusión que suelen producirse con == o === en otros lenguajes de programación. Estos errores son a menudo difíciles de reconocer por el compilador y conducen a una solución de problemas que requiere mucho tiempo.

Operadores básicos

Los resultados del operador dependen de los tipos de datos a los que se aplican. 4D soporta diferentes operadores en tipos de datos escalares. Se describen con los tipos de datos, en las siguientes secciones:

Operadores de asignación compuestos

Histórico
VersiónModificaciones
v19 R4Añadidos

4D ofrece operadores de asignación compuestos que combinan la asignación con otra operación. Un ejemplo es el operador de asignación adicional (+=):

$a:=1 
$a+=2 // $a=3

Se admiten los siguientes operadores de asignación compuestos:

OperadorSintaxisAsignaEjemplo
AdiciónText += TextText$t+=" World" //$t:=$t+" World"
Number += NumberNumber$n+=5 //$n:=$n+5
Date += NumberFecha$d+=5 //$d:=$d+5
Time += TimeHora$t1+=$t2 //$t1:=$t1+$t2
Time += NumberNumber$t1+=5 //$t1:=$t1+5
Picture += PicturePicture$p1+=$p2 //$p1:=$p1+$p2 (add $p2 to the right of $p1)
Picture += NumberPicture$p1+=5 //$p1:=$p1+5 (move $p1 horizontally 5 pixels to the right)
RestaNumber -= NumberNumber$n-=5 //$n:=$n-5
Date -= NumberFecha$d-=5 //$d:=$d-5
Time -= TimeHora$t1-=$t2 //$t1:=$t1-$t2
Time -= NumberNumber$t1-=5 //$t1:=$t1-5
Picture -= NumberPicture$p1-=5 //$p1:=$p1-5 (mover horizontalemente $p1 de 5 píxeles a la izquierda)
DivisiónNumber /= NumberNumber$n/=5 //$n:=$n/5
Time /= TimeHora$t1/=$t2 //$t1:=$t1/$t2
Time /= NumberNumber$t1/=5 //$t1:=$t1/5
Picture /= PicturePicture$p1/=$p2 //$p1:=$p1/$p2 (añadir $p2 debajo de $p1)
Picture /= NumberPicture$p1/=5 //$p1:=$p1/5 (desplazar verticalmente $p1 de 5 píxeles)
MultiplicaciónText *= NumberText$t*="abc" //$t:=$t*"abc"
Number *= NumberNumber$n*=5 //$n:=$n*5
Time *= TimeHora$t1*=$t2 //$t1:=$t1*$t2
Time *= NumberNumber$t1*=5 //$t1:=$t1*5
Picture *= NumberPicture$p1*=5 //$p1:=$p1*5 (redimensionar $p1 de 5)

Estos operadores se aplican a todas las expresiones asignables (excepto de las imágenes como propiedades de objeto o elementos de colección).

La operación "source operator value" no es estrictamente equivalente a "source := source operator value" porque la expresión que designa la fuente (variable, campo, propiedad del objeto, elemento de colección) sólo se evalúa una vez. Por ejemplo, en una expresión tal como getPointer()->+=1 el método getPointer es llamado sólo una vez.

La indexación de caracteres en el texto y la indexación de bytes en el blob no soporta a estos operadores.

Ejemplos

// Addition
$x:=2
$x+=5 //$x=7

$t:="Hello"
$t+=" World" //$t="Hello World"

$d:=!2000-11-10!
$d+=10 //$d=!2000-11-20!

// Subtraction
$x1:=10
$x1-=5 //$x1=5

$d1:=!2000-11-10!
$d1-=10 // $d1=!2000-10-31!

// Division
$x3:=10
$x3/=2 // $x3=5


// Multiplication
$x2:=10
$x2*=5 // $x2=10

$t2:="Hello"
$t2*=2 // $t2="HelloHello"
$d+=10 //$d=!2000-11-20!

// Resta
$x1:=10
$x1-=5 //$x1=5

$d1:=!2000-11-10!
$d1-=10 // $d1=!2000-10-31!

// División
$x3:=10
$x3/=2 // $x3=5


// Multiplicación
$x2:=10
$x2*=5 // $x2=10

$t2:="Hello"
$t2*=2 // $t2="HelloHello"

Operadores en cortocircuito

Los operadores && y || son los operadores en cortocircuito. Un operador en cortocircuito es aquel que no necesariamente evalúa todos sus operandos.

La diferencia con los operadores booleanos simples & y || es que los operadores en cortocircuito && y || no devuelven un valor booleano. Evalúan las expresiones como truthy o falsy, y luego devuelven una de las expresiones.

Operador en corto-circuito AND (&&)

Histórico
VersiónModificaciones
v19 R4Añadidos

La regla es la siguiente:

Dado Expr1 && Expr2:

El operador en cortocircuito AND evalúa los operandos de izquierda a derecha, devolviendo inmediatamente el valor del primer operando falso que encuentra; si todos los valores son truthy, se devuelve el valor del último operando.

La siguiente tabla resume los diferentes casos para el operador &&:

Expr1Expr2Valor devuelto
truthytruthyExpr2
truthyfalsyExpr2
falsytruthyExpr1
falsyfalsyExpr1

Ejemplo 1

var $v : Variant

$v:= "Hello" && "World" //"World"
$v:=False && 0 // False
$v:=0 && False // False
$v:=5 && !00-00-00! // 00/00/00
$v := 5 && 10 && "hello" //"hello" // 00/00/00
$v := 5 && 10 && "hello" //"hello"

Ejemplo 2

Digamos que tiene una tienda en línea, y algunos productos tienen un tipo de impuesto aplicado, y otros no.

Para calcular el impuesto, se multiplica el precio por el tipo impositivo, que puede no haberse especificado.

Así que puede escribir esto:

var $tax : Variant

$tax:=$item.taxRate && ($item.price*$item.taxRate)

$tax sera NULL si taxRate es NULL (o indefinido), de lo contrario almacenará el resultado del cálculo.

Ejemplo 3

Los operadores de cortocircuito son útiles en pruebas como:

If(($myObject#Null) && ($myObject.value>10))
//code
End if

Si $myObject es Null, el segundo argumento no se ejecuta, por lo que no se lanza ningún error.

Operador en corto-circuito OR (||)

Histórico
VersiónModificaciones
v19 R4Añadidos

El operador || devuelve el valor de uno de los operandos especificados. La expresión se evalúa de izquierda a derecha y se comprueba la posible evaluación en "cortocircuito" utilizando la siguiente regla:

Dado Expr1 || Expr2:

Si Expr1 es truthy, Expr2 no se evalúa y el cálculo devuelve Expr1.

Si Expr1 es falsy, el cálculo devuelve Expr2.

La siguiente tabla resume los diferentes casos y el valor devuelto por el operador ||:

Expr1Expr2Valor devuelto
truthytruthyExpr1
truthyfalsyExpr1
falsytruthyExpr2
falsyfalsyExpr2

Ejemplo 1

Supongamos que tiene una tabla llamada Employee. Algunos empleados han introducido un número de teléfono y otros no. Esto significa que $emp.phone podría ser NULL, y no se puede asignar NULL a una variable texto. Pero puede escribir lo siguiente:

var $phone : Text

$phone:=$emp.phone || "n/a"

En este caso, $phone almacenará un número de teléfono o la cadena "n/a".

Ejemplo 2

Dada una tabla llamada Person con un campo name, así como un campo maiden name para las mujeres casadas.

El siguiente ejemplo comprueba si hay un apellido de soltera y lo almacena en una variable, de lo contrario simplemente almacena el nombre de la persona:

var $name: Text

$name:=$person.maidenName || $person.name

Prioridad

Los operadores && y || tienen la misma prioridad que los operadores lógicos & y |, y se evalúan de izquierda a derecha.

Esto significa que a || b && c se evalúa como (a || b) && c.

Operador ternario

Histórico
VersiónModificaciones
v19 R4Añadidos

El operador condicional ternario permite escribir expresiones condicionales de una línea. Por ejemplo, puede reemplazar una secuencia completa de instrucciones If…Else.

Se necesitan tres operandos en el siguiente orden:

  • una condición seguida de un signo de interrogación (?)
  • una expresión a ejecutar si la condición es truthy, seguida de dos puntos (:)
  • una expresión a ejecutar si la condición es falsy

Sintaxis

La sintaxis es la siguiente:

condition ? condition ? exprIfTruthy : exprIfFalsy condition ? exprIfTruthy : exprIfFalsy condition ? exprIfTruthy : exprIfFalsy

Dado que la sintaxis con tokens utiliza dos puntos, se recomienda insertar un espacio después de los dos puntos : o encerrar los tokens utilizando paréntesis para evitar cualquier conflicto.

Ejemplos

Un ejemplo sencillo

var $age : Integer
var $beverage : Text

$age:=26
$beverage:=($age>=21) ? "Beer" : "Juice"

ALERT($beverage) // "Beer" "Beer" : "Juice"

ALERT($beverage) // "Beer"

Gestión de los datos de una tabla

Este ejemplo almacena el nombre completo de una persona en una variable, y maneja el caso cuando no se ha especificado el nombre o el apellido:

var $fullname : Text

// If one of the names is missing, store the one that exists, otherwise store an empty string
$fullname:=($person.firstname && $person.lastname) ? ($person.firstname+" "+$person.lastname) : ($person.lastname || $person.firstname) || "" ($person.firstname+" "+$person.lastname) : ($person.lastname || $person.firstname) || ""

Truthy y falsy

Histórico
VersiónModificaciones
v19 R4Añadidos

Además de un tipo, cada valor también tiene un valor booleano inherente, conocido generalmente como truthy o falsy<.

Los valores truthy y falsy sólo son evaluados por los operadores en cortocircuito y ternarios.

Los siguientes valores son falsy:

  • false
  • Null
  • indefinido
  • Null object
  • Null collection
  • Null pointer
  • Null picture
  • Null date !00-00-00!
  • "" - Cadenas vacías
  • [] - Colecciones vacías
  • {} - Objetos vacios

Todos los demás valores se consideran truthy, incluyendo:

  • 0 - cero numérico (Entero u otro)

En 4D, la evaluación truthy y falsy refleja la usabilidad de un valor, lo que significa que un valor truthy existe y puede ser procesado por el código sin generar errores o resultados inesperados. La razón de ser de esto es ofrecer una forma conveniente de manejar valores undefined y null en objetos y colecciones, de modo que un número reducido de instrucciones If…Else sean necesarias para evitar errores de ejecución.

Por ejemplo, cuando se utiliza un operador en cortocircuito OR:

$value:=$object.value || $defaultValue

... se obtiene el valor por defecto cada vez que $object no contenga la propieda valor O cuando sea null. Por lo tanto, este operador comprueba la existencia o utilidad del valor en lugar de un valor específico. Obsérvese que como el valor numérico 0 existe y es utilizable, no se le da un tratamiento especial, por lo que es truthy.

En cuanto a los valores que representan las colecciones, los objetos o las cadenas, los valores "vacíos" se consideran como falsy. Es útil cuando se quiere asignar un valor por defecto cuando se encuentra un valor vacío.

$phone:=$emp.phone || "n/a"