Espaces de nom

De Base de connaissances eggdrops & TCL

Si vous avez déjà eu des problèmes avec des variables globales ou des procédures dans votre script interférant avec d'autres scripts, vous avez besoin des namespaces.

Les namespaces représentent ce qui rapproche le plus le Tcl de la programmation orientée objet. Ils permettent au programmeur de placer des variables et des procédures dans un sous-environnement clairement délimité et avec un nom distinct, de façon à ne pas créer de conflits avec quoi que ce soit d'autre dans le namespace global.

Premiers pas

namespace eval MyScript {
  variable response "Hello World!"

  bind pub - "hi" MyScript::respond
  proc respond {nick uhost hand chan text} {
    variable response
    puthelp "PRIVMSG $nick :$response"
    return 1
  }
}

MyScript est le nom du namespace. Ce sera le préfixe utilisé dans le nom des variables et des procédures si elles sont appelées depuis d'autres namespaces (tels quel le namespace global).

Notez que le bind spécifie le nom complet pour la procédure.

Notez également que la variable $response réside à l'intérieur du namespace. Cela signifie qu'il ne s'agit pas d'une variable globale. Donc à l'intérieur de la procédure, elle est déclarée comme variable plutôt que comme global.

Notez que les variables doivent être déclarées sur des lignes séparées si vous en utilisez plusieurs. Elles ne peuvent pas être déclarées en une seule longue ligne comme les globals.

catch MyScript::uninstall
namespace eval MyScript {
  variable response "Hello World!"

  bind pub - "hi" MyScript::respond
  proc respond {nick uhost hand chan text} {
    variable response
    puthelp "PRIVMSG $nick :$response"
    return 1
  }

  bind evnt - prerehash MyScript::uninstall
  proc uninstall {args} {
    unbind pub - "hi" MyScript::respond
    unbind evnt - prerehash MyScript::uninstall
    namespace delete MyScript
  }
}

Plutôt que d'obliger les utilisateurs à effectuer un .restart pour désinstaller les scripts, désinstallons le nôtre lorsqu'un rehash est détecté.

Si l'utilisateur a toujours le script dans le .conf, il sera automatiquement chargé après le rehash. Avant tout, les binds ne sont pas directement associés au namespace donc ils doivent être unbind séparément. Enfin, le namespace lui-même peut être supprimé. N'oubliez pas d'arrêter tous les timers que vous pourriez avoir dans votre script.

De plus, dans le but de désinstaller/réinstaller également pour les utilisateurs qui ont chargé le script au moyen de la commande .tcl source, ajoutez la 1ère ligne (catch blablabla...) pour appeler la procédure de désinstallation. Le catch est là afin que le bot ne plante pas si la procédure de désinstallation n'existe pas encore (premier lancement).

set ns "MyScript"
catch ${ns}::uninstall
namespace eval $ns {
  unset ::ns

  variable response "Hello World!"

  bind pub - "hi" [namespace current]::respond
  proc respond {nick uhost hand chan text} {
    variable response
    puthelp "PRIVMSG $nick :$response"
    return 1
  }

  bind evnt - prerehash [namespace current]::uninstall
  proc uninstall {args} {
    unbind pub - "hi" [namespace current]::respond
    unbind evnt - prerehash [namespace current]::uninstall
    namespace delete [namespace current]
  }
}

Si vous vous inquiétez en ce qui concerne la possibilité que des conflits surviennent entre votre namespace et un autre, faites ceci :

Premièrement, définissez le namespace dans une variable globale. Ceci n'est utilisé que dans les deux premières lignes, donc on peut ensuite unset la variable globale de manière à ne pas encombrer le namespace global. Après cela, [namespace current] doit être utilisé partout où MyScript était utilisé. Cela rend pratiquement impossible l'occurrence d'un conflit entre votre script et un autre.

Crédits