2 votes

Surcharge d'une commande Tcl standard

Petite question relative à la portée de la procédure

proc lappend {args} {
   set a $args
   lappend a testing ;# want to call the inbuilt tcl lappend command
   puts "$a"
}

set list {new to tcl}
lappend $list

13voto

Donal Fellows Points 56559

Si vous ne faites que ça, ça ne marchera pas. Il remplacera le standard lappend et vous obtiendrez une récursion infinie (enfin, vous aurez une vérification de la profondeur de la pile). Il y a plusieurs façons de contourner ce problème.

Placer votre code dans un espace de nom

Si votre code se trouve dans un espace de nom, il résoudra l'option lappend dans cet espace de nom en premier lieu et n'utiliser l'espace de nom global que si la recherche locale échoue. Vous pouvez utiliser cette méthode comme suit :

namespace eval myNS {
    proc lappend {args} {
        set a $args
        ::lappend a testing ;# Force the use of the global lappend command
        puts "$a"
    }

    set list {new to tcl}
    lappend $list
}

Il y a des variations possibles sur ce point, namespace eval myNS {source example.tcl} (avec votre code étant presque verbatim dans ce fichier source) est l'une des plus intéressantes, car elle permet au code d'être pratiquement indépendant de l'espace de noms.

Renommer le global lappend commande

Vous pouvez également déplacer la commande standard de la manière suivante :

rename lappend lappend_original
proc lappend {args} {
   set a $args
   lappend_original a testing
   puts "$a"
}

set list {new to tcl}
lappend $list

Cette technique fonctionne très bien, tant que vous n'avez pas trop de code qui se bat pour savoir qui a la commande originale. Elle a été utilisée par de nombreux scripts Tcl au fil des ans.

Real solution du problème : traçage de l'exécution

Bien sûr, le lappend n'est pas une commande que vous souhaitez vraiment remplacer car elle est fortement utilisée dans une grande partie du code de la bibliothèque Tcl. Pour le problème de la détermination de l'endroit où un morceau de code appelle réellement lappend et les arguments qui sont passés, il est de loin préférable d'utiliser une méthode d'évaluation de la qualité de l'eau. trace d'exécution . (Le lien qui figure ici renvoie à la documentation de Tcl 8.6, mais cette API est en place depuis Tcl 8.4, vous devriez donc l'avoir à disposition).

proc runningLappend {cmdAndArgs operation} {
    puts [lrange $cmdAndArgs 1 end]
}
trace add execution lappend enter runningLappend

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X