Escrito por

InterSystems Corporation
Artículo Pierre-Yves Duquesnoy · feb 9 4m read

Parámetros Variádicos en ObjectScript: La Solución Elegante que No Sabías que Existía

¿Qué son los parámetros variádicos?

ObjectScript permite definir métodos que aceptan un número variable de argumentos usando la sintaxis `args...`. En lugar de fijar cuántos parámetros recibe un método, dejas que el llamante decida cuántos enviar.

Se pueden invocar de dos formas:

1. Con argumentos individuales: `metodo(val1, val2, val3)`

2. Expandiendo un array: `metodo(args...)`

 

 

Crea tus propios métodos variádicos

Puedes definir un método con un parámetro fijo y un número variable de extras:

ClassMethod MiMetodo(fijo As%String, extras...) As%Status
{
    Write"Parámetro fijo: ", fijo, !
    Write"Número de extras: ", $Get(extras, 0), !

    For i = 1:1:$Get(extras, 0) {
        Write"  Extra ", i, ": ", extras(i), !
    }
    Quit$$$OK
}

Y llamarlo de cualquiera de estas dos formas:

// Forma 1: Argumentos individualesDo##class(MiClase).MiMetodo("hola", "valor1", "valor2")

// Forma 2: Expandiendo un arraySet params = 2Set params(1) = "valor1"Set params(2) = "valor2"Do##class(MiClase).MiMetodo("hola", params...)

// Ambas producen la misma salida://   Parámetro fijo: hola//   Número de extras: 2//   Extra 1: valor1//   Extra 2: valor2

 

La convención del array

El array que se pasa con `args...` sigue una convención simple de ObjectScript:

- `args` contiene el número de elementos

- `args(1)`, `args(2)`, etc. contienen los valores

Esto significa que estas dos llamadas son equivalentes:

// Forma 1: Argumentos individualesSet result = statement.%Execute("Juan", 25, "Barcelona")

// Forma 2: Expandiendo un arraySet args = 3Set args(1) = "Juan"Set args(2) = 25Set args(3) = "Barcelona"Set result = statement.%Execute(args...)

 

La segunda forma es la que nos interesa: podemos construir el array dinámicamente y expandirlo en la llamada.

Aplicación práctica: SQL dinámico seguro

Construir consultas SQL dinámicas concatenando strings es tentador... y peligroso:

// ⚠️ NO HAGAS ESTO - Vulnerable a SQL InjectionSet sql = "SELECT * FROM Paciente WHERE Nombre LIKE '%" _ nombre _ "%'"

 

La forma correcta es usar `%SQL.Statement` con parámetros `?`. Pero, ¿qué pasa cuando no sabes cuántos parámetros tendrás hasta el momento de ejecución?

Aquí es donde los variádicos brillan. El método `%Execute()` está definido así:

Method %Execute(%parm...) As%SQL.StatementResult

Acepta parámetros variádicos, así que podemos construir nuestro array dinámicamente y expandirlo:

Implementación completa

ClassMethod BuscarPacientes(filtrosJSON As%DynamicObject) As%SQL.StatementResult
{
    Set sql = "SELECT ID, Nombre, Edad, Ciudad FROM Paciente WHERE 1=1"// Construir condiciones y argumentos dinámicamenteSet args = 0// args será nuestro array variádicoSet iterator = filtrosJSON.%GetIterator()
    While iterator.%GetNext(.key, .value) {
        If key = "nombre" {
            Set sql = sql _ " AND Nombre LIKE ?"Set args($Increment(args)) = "%" _ value _ "%"
        } ElseIf key = "edad" {
            Set sql = sql _ " AND Edad = ?"Set args($Increment(args)) = value
        } ElseIf key = "ciudad" {
            Set sql = sql _ " AND Ciudad = ?"Set args($Increment(args)) = value
        }
    }

    // Preparar el statementSet statement = ##class(%SQL.Statement).%New()
    Set status = statement.%Prepare(sql)
    If$$$ISERR(status) { Quit$$$NULLOREF }

    // ¡La magia! Expandir el array como argumentos variádicosQuit statement.%Execute(args...)
}

 

Ejemplo de uso

// Filtros dinámicos desde un JSONSet filtros = {"nombre": "Juan", "ciudad": "Barcelona"}

Set resultado = ##class(MiPaquete.Utilidades).BuscarPacientes(filtros)

While resultado.%Next() {
    Write resultado.%Get("Nombre"), " - ", resultado.%Get("Ciudad"), !
}

No importa si recibes 1, 5 o 20 filtros: el mismo código los maneja de forma segura.

Conclusión

Los parámetros variádicos con `args...` te permiten:

- Construir arrays de argumentos dinámicamente

- Expandirlos al llamar cualquier método que los soporte

- Evitar SQL injection usando parámetros preparados

- Eliminar cadenas interminables de `If`/`ElseIf`

Referencias

Variable number of method arguments

Passing a variable number of arguments