Parte 3: Funciones Personalizadas¶
Traducción asistida por IA - más información y sugerencias
Al final de esta sección, tendrá funciones personalizadas en su plugin, compiladas e instaladas localmente, ejecutándose en un workflow real.
¿Comenzando desde aquí?
Si se une en esta parte, copie la solución de la Parte 2 para usarla como punto de partida:
1. Ver lo que generó la plantilla¶
Antes de escribir sus propias funciones, observe la función de ejemplo que creó la plantilla para entender el patrón.
Cambie al directorio del plugin:
La plantilla creó un archivo llamado GreetingExtension.groovy donde se definen las funciones del plugin.
Ábralo para ver el punto de partida:
/*
* Copyright 2025, Seqera Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package training.plugin
import groovy.transform.CompileStatic
import nextflow.Session
import nextflow.plugin.extension.Function
import nextflow.plugin.extension.PluginExtensionPoint
/**
* Implementa una función personalizada que puede ser importada por
* scripts de Nextflow.
*/
@CompileStatic
class GreetingExtension extends PluginExtensionPoint { // (1)!
@Override
protected void init(Session session) { // (2)!
}
/**
* Saluda al destinatario indicado.
*
* @param target
*/
@Function // (3)!
void sayHello(String target) {
println "Hello, ${target}!"
}
}
- La clase sobre la que se construye su extensión. Nextflow requiere esto para reconocer sus funciones.
- Se llama cuando el plugin se carga; úselo para la inicialización
- Hace que este método sea invocable desde workflows mediante
include
La plantilla incluye una función de ejemplo sayHello.
La anotación @Function es lo que hace que un método sea invocable desde workflows de Nextflow.
Sin ella, el método existe únicamente dentro del código del plugin.
En Groovy (y Java), los métodos declaran qué tipo retornan y qué tipos tienen sus parámetros.
Por ejemplo, String reverseGreeting(String greeting) declara un método que recibe un parámetro String y retorna un String.
La palabra clave void significa que el método no retorna nada, como ocurre con sayHello arriba.
Esto es diferente de Python o R, donde los tipos no necesitan declararse explícitamente.
2. Reemplazar sayHello con reverseGreeting¶
La función sayHello de la plantilla es un marcador de posición.
Reemplácela con su propia función para ver el ciclo completo de escritura, compilación y uso de una función de plugin.
Edite src/main/groovy/training/plugin/GreetingExtension.groovy para reemplazar el método sayHello:
| GreetingExtension.groovy | |
|---|---|
- Hace que el método sea invocable desde workflows de Nextflow
- Recibe un String, retorna un String
- Método de inversión de cadenas integrado en Groovy
Partes clave de esta función:
@Function: Hace que el método sea invocable desde workflows de NextflowString reverseGreeting(String greeting): Recibe un String, retorna un Stringgreeting.reverse(): Método de inversión de cadenas integrado en Groovy
Métodos públicos y privados
Los métodos sin @Function no se exponen a los workflows de Nextflow.
Puede agregar métodos auxiliares a su clase sin preocuparse de que se filtren al espacio de nombres del workflow.
3. Compilar e instalar su plugin¶
Compile e instale el plugin:
Si la compilación falla
Lea el mensaje de error con atención; generalmente incluye un número de línea y describe el problema. Las causas más comunes son errores de sintaxis (corchete o comilla faltante), nombres de clase mal escritos y tipos incompatibles. Si está atascado, compare su código carácter por carácter con los ejemplos.
4. Usar su función en un workflow¶
El plugin está compilado e instalado.
El siguiente paso es usar reverseGreeting en un workflow para verificar que funciona de extremo a extremo.
Regrese al directorio del pipeline:
Edite greet.nf para importar y usar reverseGreeting:
Ejecute el pipeline:
Output
N E X T F L O W ~ version 25.10.2
Launching `greet.nf` [elated_marconi] DSL2 - revision: cd8d52c97c
Pipeline is starting! 🚀
executor > local (5)
[fe/109754] process > SAY_HELLO (5) [100%] 5 of 5 ✔
Reversed: olleH
Reversed: ruojnoB
Reversed: àloH
Reversed: oaiC
Reversed: ollaH
Output: Hello
Output: Bonjour
Output: Holà
Output: Ciao
Output: Hallo
Pipeline complete! 👋
Su primera función de plugin personalizada está funcionando en un workflow real.
El mismo patrón include { ... } from 'plugin/...' que usó con nf-hello y nf-schema en la Parte 1 funciona con su propio plugin.
5. Agregar decorateGreeting¶
Un plugin puede proveer múltiples funciones. Agregue una segunda que envuelva un saludo con marcadores decorativos; la hará configurable en la Parte 6.
Edite GreetingExtension.groovy para agregar decorateGreeting después de reverseGreeting, antes de la llave de cierre de la clase:
- Interpolación de cadenas en Groovy:
${...}inserta el valor de la variable en la cadena
| GreetingExtension.groovy | |
|---|---|
Esta función usa la interpolación de cadenas de Groovy ("*** ${greeting} ***") para insertar la variable del saludo dentro de una cadena.
Compile, instale y actualice el workflow:
Actualice greet.nf para también importar y usar decorateGreeting:
- Las múltiples funciones del mismo plugin necesitan declaraciones
includeseparadas - Las funciones del plugin también funcionan dentro de bloques
script:de procesos
Output
N E X T F L O W ~ version 25.10.2
Launching `greet.nf` [elated_marconi] DSL2 - revision: cd8d52c97c
Pipeline is starting! 🚀
executor > local (5)
[fe/109754] process > SAY_HELLO (5) [100%] 5 of 5 ✔
Reversed: olleH
Reversed: ruojnoB
Reversed: àloH
Reversed: oaiC
Reversed: ollaH
Decorated: *** Hello ***
Decorated: *** Bonjour ***
Decorated: *** Holà ***
Decorated: *** Ciao ***
Decorated: *** Hallo ***
Pipeline complete! 👋
Las funciones del plugin funcionan tanto en scripts de procesos (como decorateGreeting dentro de SAY_HELLO) como en operaciones de workflow (como reverseGreeting en un map).
Conclusión¶
Aprendió que:
- Las funciones se definen con la anotación
@Functionen subclases dePluginExtensionPoint - Las funciones del plugin importadas con
includefuncionan de manera idéntica ya sea que provengan de su propio plugin o de uno existente - Las funciones del plugin funcionan tanto en scripts de procesos como en operaciones de workflow
¿Qué sigue?¶
Sus funciones funcionan, pero hasta ahora solo lo ha verificado ejecutando el pipeline completo y revisando la salida visualmente. Ese enfoque no escala: a medida que agregue más funciones, necesitará una forma más rápida de verificar que cada una se comporta correctamente, especialmente después de realizar cambios. La siguiente sección presenta las pruebas unitarias, que le permiten verificar funciones individuales automáticamente sin ejecutar un pipeline.