private int foo() { return 1; }Por el contrario, en GeneXus los parámetros de un objeto pueden ser de entrada, salida o entrada/salida, en cualquier cantidad y orden. (*)
Por ejemplo, podría tener una función que dado un producto me devuelve el saldo en cantidad y en importe, de dicho producto en el depósito. (**)
La regla parm sería por ejemplo:
parm(in:ProductoId, out:&SaldoCantidad, out:&SaldoImporte);Pero entonces, ¿cómo invoco ese programa?. Hay varias opciones, puede ser con call, o incluso con udp...
call(PGetSaldoProducto, ProductoId, &SaldoCantidad, &SaldoImporte)En una nota hace un tiempo, hablando sobre la legibilidad del código, comentaba sobre la ventaja de usar udp en vez de call... Pero en este caso las dos opciones son malas.
o
&SaldoImporte = udp(PGetSaldoProducto, ProductoId, &SaldoCantidad)
Creo que sería bueno tener una sintaxis como tiene por ejemplo Python para asignar listas de valores... En Python una lista separada por comas es una tupla, que se puede devolver en una función o asignar. Por ejemplo:
# defino la funcionEn GeneXus, si tuvieramos la posibilidad de usar esta notación, podríamos escribir:
def foo():
a = 1
b = 2
c = 3
return a,b,c
# la invoco
d, e, f = foo() # resultado: d=1, e=2, f=3
&SaldoImporte, &SaldoCantidad = udp(PGetSaldoProducto, ProductoId)lo que deja bien claro que la intención de la invocación es cargar el valor de las dos variables de la izquierda...
---------------------------------------
(*) Si bien los parámetros pueden tener cualquier orden, creo que es altamente recomendable dejar los parámetros de salida al final.
(**) Los motivos para tener una función que devuelve más de un valor pueden ser muchos y muy variados. En este caso también se podrían hacer dos funciones, con lógica muy parecida, pero que devolviera una la cantidad y otra el importe. La ventaja de tenerlo así es que se optimiza la performance, porque hay que hacer la recorrida en la base de datos una sola vez.
5 comentarios: