Architecture et Cas d'Usage
Yaegi se distingue comme un interpréteur Go natif, permettant l'évaluation de code source à l'exécution. Il offre une alternative robuste pour le chargement de plugins, l'extension d'applications et le prototypage rapide, le tout sans dépendances externes autres que la bibliothèque standard.
Caractéristiques Techniques
- Conformité stricte avec les spécifications du langage Go.
- Architecture 100% Go, facilitant le cross-compilation et l'intégration.
- Sandboxing natif : isolation des appels système et du paquet
unsafepar défaut. - API d'évaluation minimaliste et performante.
- Compatibilité avec les versions récentes de l'écosystème Go.
Domaines d'Application
- Moteurs de règles métier dynamiques.
- Systèmes de plugins rechargables à chaud.
- Environnements REPL pour le débogage et l'expérimentation algorithmique.
- Automatisation de tâches système via des scripts natifs.
Mise en place de l'environnement
L'acquistiion de l'outil en ligne de commande s'effectue via le gestionnaire de modules Go :
go install github.com/traefik/yaegi/cmd/yaegi@latest
Pour une intégration en tant que bibliothèque au sein de votre propre projet :
import "github.com/traefik/yaegi/interp"
Évaluation de Code et Intégration
Exécution via le REPL
L'interpréteur interactif permet de tester des instructions et d'explorer la bibliothèque standard à la volée :
$ yaegi
> import "math"
> math.Sqrt(144)
12
> import "strings"
> strings.ToUpper("yaegi")
"YAEGI"
Scripts Auto-exécutables
Il est possible de créer des scripts Go directement exécutables depuis le système d'exploitation en utilisant le shebang approprié :
#!/usr/bin/env yaegi
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now().Format("15:04:05")
fmt.Printf("Execution started at %s\n", now)
}
Rendez le fichier exécutable et lancez-le :
chmod +x timer.go
./timer.go
Intégration Programmatique (Embarqué)
L'API d'interprétation permet d'injecter un moteur d'exécution dans une application hôte. Voici une approche modifiée pour illustrer l'évaluation de structures de données et de boucles :
package main
import (
"fmt"
"log"
"github.com/traefik/yaegi/interp"
"github.com/traefik/yaegi/stdlib"
)
func main() {
// Initialisation du contexte d'interprétation
evaluateur := interp.New(interp.Options{})
evaluateur.Use(stdlib.Symbols)
// Importation des dépendances nécessaires
if _, err := evaluateur.Eval(`import "fmt"`); err != nil {
log.Fatalf("Erreur d'import: %v", err)
}
// Exécution d'une logique dynamique
script := `
data := []int{10, 20, 30, 40}
somme := 0
for _, val := range data {
somme += val
}
fmt.Printf("Le total est : %d\n", somme)
`
if _, err := evaluateur.Eval(script); err != nil {
log.Fatalf("Erreur d'exécution: %v", err)
}
}
Fonctionnalités Avancées et Limites
Injection de Logique Dynamique
Yaegi excelle dans l'extraction de symboles Go compilés vers des contextes interprétés. Exemple de manipulation de fonctions mathématiques à la volée :
const codeDynamique = `package calculateur
func AppliquerRemise(prix float64, taux float64) float64 {
return prix * (1 - taux/100)
}`
ctx := interp.New(interp.Options{})
ctx.Eval(codeDynamique)
// Récupération et typage de la fonction
symbole, _ := ctx.Eval("calculateur.AppliquerRemise")
fonctionRemise := symbole.Interface().(func(float64, float64) float64)
prixFinal := fonctionRemise(150.0, 20.0) // Résultat attendu : 120.0
fmt.Printf("Prix après remise : %.2f\n", prixFinal)
Options de la CLI
Pour des besoins spécifiques nécessitant un accès bas niveau, des drapeaux peuvent être activés pour lever les restrictions de sécurité :
# Activation des appels système et du paquet unsafe
yaegi -syscall -unsafe -unrestricted mon_script.go
Contraintes Techniques Actuelles
L'architecture par interprétation AST implique certaines limites inhérentes :
- Incompatibilité avec les fichiers d'assemblage (
.s). - Absence de support pour l'interfaçage direct avec C (cgo).
- Surcoût de performance par rapport au code natif compilé.
- Gestion spécifique des modules Go nécessitant des wrappers explicites pour les bibliothèques tierces non standard.