Escrito por

Desenvolvedor at QI Tech
Artigo Heloisa Paiva · Fev. 17 3m read

Parâmetros Variádicos em ObjectScript: A Solução Elegante que Você Não Sabia que Existia

O que são parâmetros variádicos?

O ObjectScript permite definir métodos que aceitam um número variável de argumentos usando a sintaxe `args...`. Em vez de fixar quantos parâmetros um método recebe, você deixa que quem chama decida quantos enviar.

Eles podem ser invocados de duas formas:

1. Com argumentos individuais: `metodo(val1, val2, val3)`

2. Expandindo um array: `metodo(args...)`

 


Crie seus próprios métodos variádicos

Você pode definir um método com um parâmetro fixo e um número variável de extras:

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

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

E chamá-lo de qualquer uma destas duas formas:

// Forma 1: Argumentos individuaisDo##class(MiClase).MiMetodo("olá", "valor1", "valor2")

// Forma 2: Expandindo um arraySet params = 2Set params(1) = "valor1"Set params(2) = "valor2"Do##class(MiClase).MiMetodo("olá", params...)

// Ambas produzem a mesma saída://   Parâmetro fixo: olá//   Número de extras: 2//   Extra 1: valor1//   Extra 2: valor2

A convenção do array

O array que é passado com `args...` segue uma convenção simples do ObjectScript:

- `args` contém o número de elementos

- `args(1)`, `args(2)`, etc. contêm os valores

Isso significa que estas duas chamadas são equivalentes:

// Forma 1: Argumentos individuaisSet result = statement.%Execute("João", 25, "Barcelona")

// Forma 2: Expandindo um arraySet args = 3Set args(1) = "João"Set args(2) = 25Set args(3) = "Barcelona"Set result = statement.%Execute(args...)

A segunda forma é a que nos interessa: podemos construir o array dinamicamente e expandi-lo na chamada.

Aplicação prática: SQL dinâmico seguro

Construir consultas SQL dinâmicas concatenando strings é tentador... e perigoso:

// ⚠️ NÃO FAÇA ISSO - Vulnerável a SQL InjectionSet sql = "SELECT * FROM Paciente WHERE Nome LIKE '%" _ nombre _ "%'"

A forma correta é usar `%SQL.Statement` com parâmetros `?`. Mas o que acontece quando você não sabe quantos parâmetros terá até o momento da execução?

Aqui é onde os variádicos brilham. O método `%Execute()` é definido assim:

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

Ele aceita parâmetros variádicos, portanto podemos construir nosso array dinamicamente e expandi-lo:

Implementação completa

ClassMethod BuscarPacientes(filtrosJSON As%DynamicObject) As%SQL.StatementResult
{
    Set sql = "SELECT ID, Nombre, Edad, Ciudad FROM Paciente WHERE 1=1"// Construir condições e argumentos dinamicamenteSet args = 0// args será nosso 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 o statementSet statement = ##class(%SQL.Statement).%New()
    Set status = statement.%Prepare(sql)
    If$$$ISERR(status) { Quit$$$NULLOREF }

    // A mágica! Expandir o array como argumentos variádicosQuit statement.%Execute(args...)
}

Exemplo de uso

// Filtros dinâmicos a partir de um JSONSet filtros = {"nombre": "João", "ciudad": "Barcelona"}

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

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

Não importa se você recebe 1, 5 ou 20 filtros: o mesmo código os manipula de forma segura.

Conclusão

Os parâmetros variádicos com `args...` permitem que você:

- Construa arrays de argumentos dinamicamente

- Expanda-os ao chamar qualquer método que os suporte

- Evite SQL injection usando parâmetros preparados (prepared statements)

- Elimine cadeias intermináveis de `If`/`ElseIf`

Referências

Variable number of method arguments

Passing a variable number of arguments