Parte 3: Funzioni Personalizzate¶
Traduzione assistita da IA - scopri di più e suggerisci miglioramenti
Alla fine di questa sezione, avrete funzioni personalizzate nel vostro plugin, compilate e installate localmente, in esecuzione in un flusso di lavoro reale.
Iniziate da qui?
Se vi unite a partire da questa parte, copiate la soluzione dalla Parte 2 da usare come punto di partenza:
1. Vedere cosa ha generato il template¶
Prima di scrivere le vostre funzioni, osservate la funzione di esempio che il template ha creato per capire il pattern.
Spostatevi nella directory del plugin:
Il template ha creato un file chiamato GreetingExtension.groovy dove vengono definite le funzioni del plugin.
Apritelo per vedere il punto di partenza:
/*
* 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 funzione personalizzata che può essere importata da
* script Nextflow.
*/
@CompileStatic
class GreetingExtension extends PluginExtensionPoint { // (1)!
@Override
protected void init(Session session) { // (2)!
}
/**
* Saluta il destinatario specificato.
*
* @param target
*/
@Function // (3)!
void sayHello(String target) {
println "Hello, ${target}!"
}
}
- La classe su cui si basa la vostra estensione. Nextflow richiede questa classe per riconoscere le vostre funzioni.
- Chiamata quando il plugin viene caricato; da usare per l'inizializzazione
- Rende questo metodo richiamabile dai flussi di lavoro tramite
include
Il template include una funzione sayHello di esempio.
L'annotazione @Function è ciò che rende un metodo richiamabile dai flussi di lavoro Nextflow.
Senza di essa, il metodo esiste solo all'interno del codice del plugin.
In Groovy (e Java), i metodi dichiarano il tipo che restituiscono e i tipi dei loro parametri.
Ad esempio, String reverseGreeting(String greeting) dichiara un metodo che accetta un parametro String e restituisce una String.
La parola chiave void significa che il metodo non restituisce nulla, come nel caso di sayHello sopra.
Questo è diverso da Python o R, dove i tipi non devono essere dichiarati esplicitamente.
2. Sostituire sayHello con reverseGreeting¶
La funzione sayHello del template è un segnaposto.
Sostituitela con la vostra funzione per vedere il ciclo completo di scrittura, compilazione e utilizzo di una funzione del plugin.
Modificate src/main/groovy/training/plugin/GreetingExtension.groovy per sostituire il metodo sayHello:
| GreetingExtension.groovy | |
|---|---|
- Rende il metodo richiamabile dai flussi di lavoro Nextflow
- Accetta una String, restituisce una String
- Il metodo di inversione delle stringhe integrato in Groovy
Elementi chiave di questa funzione:
@Function: Rende il metodo richiamabile dai flussi di lavoro NextflowString reverseGreeting(String greeting): Accetta una String, restituisce una Stringgreeting.reverse(): Il metodo di inversione delle stringhe integrato in Groovy
Metodi pubblici e privati
I metodi senza @Function non sono esposti ai flussi di lavoro Nextflow.
Potete aggiungere metodi di supporto alla vostra classe senza preoccuparvi che vengano esposti nel namespace del flusso di lavoro.
3. Compilare e installare il plugin¶
Compilate e installate il plugin:
Se la compilazione fallisce
Leggete attentamente il messaggio di errore; di solito include un numero di riga e descrive il problema. Le cause più comuni sono errori di sintassi (parentesi o virgolette mancanti), nomi di classe scritti in modo errato e mancata corrispondenza dei tipi. Se siete bloccati, confrontate il vostro codice carattere per carattere con gli esempi.
4. Usare la funzione in un flusso di lavoro¶
Il plugin è compilato e installato.
Il passo successivo è usare reverseGreeting in un flusso di lavoro per verificare che funzioni dall'inizio alla fine.
Tornate alla directory della pipeline:
Modificate greet.nf per importare e usare reverseGreeting:
Eseguite la 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! 👋
La vostra prima funzione personalizzata del plugin funziona in un flusso di lavoro reale.
Lo stesso pattern include { ... } from 'plugin/...' che avete usato con nf-hello e nf-schema nella Parte 1 funziona anche con il vostro plugin.
5. Aggiungere decorateGreeting¶
Un plugin può fornire più funzioni. Aggiungete una seconda funzione che racchiude un saluto con marcatori decorativi; la renderete configurabile nella Parte 6.
Modificate GreetingExtension.groovy per aggiungere decorateGreeting dopo reverseGreeting, prima della parentesi graffa di chiusura della classe:
- Interpolazione di stringhe in Groovy:
${...}inserisce il valore della variabile nella stringa
| GreetingExtension.groovy | |
|---|---|
Questa funzione usa l'interpolazione di stringhe di Groovy ("*** ${greeting} ***") per incorporare la variabile del saluto all'interno di una stringa.
Compilate, installate e aggiornate il flusso di lavoro:
Aggiornate greet.nf per importare e usare anche decorateGreeting:
- Più funzioni dallo stesso plugin richiedono istruzioni
includeseparate - Le funzioni del plugin funzionano anche all'interno dei blocchi
script:dei processi
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! 👋
Le funzioni del plugin funzionano sia negli script dei processi (come decorateGreeting all'interno di SAY_HELLO) che nelle operazioni del flusso di lavoro (come reverseGreeting in un map).
Takeaway¶
Avete imparato che:
- Le funzioni sono definite con l'annotazione
@Functionnelle sottoclassi diPluginExtensionPoint - Le funzioni del plugin importate con
includefunzionano in modo identico sia che provengano dal vostro plugin che da uno esistente - Le funzioni del plugin funzionano sia negli script dei processi che nelle operazioni del flusso di lavoro
Cosa c'è dopo?¶
Le vostre funzioni funzionano, ma finora le avete verificate solo eseguendo l'intera pipeline e controllando l'output a occhio. Questo approccio non è scalabile: man mano che aggiungete più funzioni, avete bisogno di un modo più rapido per verificare che ciascuna si comporti correttamente, specialmente dopo aver apportato modifiche. La sezione successiva introduce i test unitari, che vi permettono di verificare le singole funzioni automaticamente senza eseguire una pipeline.