2010-08-16 10 views
9

Il y a quelque temps, j'avais besoin d'une solution pour importer correctement les bibliothèques dans VBScript. VBScript, à titre de référence, n'a pas de capacités d'importation intégrées. La méthode traditionnelle d'importation de fichiers consiste à utiliser SSI, qui déverse le contenu de l'include textuellement dans le Includeer. Ceci est moins qu'optimal pour un certain nombre de raisons: il n'y a aucun moyen d'éviter l'inclusion multiple, il n'y a aucun moyen de spécifier un répertoire de bibliothèque, etc. J'ai donc écrit ma propre fonction. Il est assez simple, en utilisant executeGlobal avec un dictionnaire pour garder la trace des modules importés et envelopper le tout dans un objet pour l'encapsulation:Implémentation de modules avec chargement paresseux dans VBScript

class ImportFunction 
    private libraries_ 

    private sub CLASS_INITIALIZE 
     set libraries_ = Server.createObject("Scripting.Dictionary") 
    end sub 

    public default property get exec (name) 
     if not libraries_.exists(name) then 
      ' The following line will find the actual path of the named library ' 
      dim lib_path: set lib_path = Path.resource_path(name & ".lib", "libraries") 

      on error resume next 
      ' Filesystem is a class of mine; its operation should be fairly obvious ' 
      with FileSystem.open(lib_path, "") 
       executeGlobal .readAll 
       if Err.number <> 0 then 
        Response.write "Error importing library " 
        Response.write lib_path & "<br>" 
        Response.write Err.source & ": " & Err.description 
       end if 
      end with 
      on error goto 0 

      libraries_.add name, null 
     end if 
    end property 
end class 
dim import: set import = new ImportFunction 

' Example: 
import "MyLibrary" 

Quoi qu'il en soit, cela fonctionne assez bien, mais il est beaucoup de travail si je n » Je finis par utiliser la bibliothèque. Je voudrais le rendre paresseux, de sorte que la recherche, le chargement et l'exécution du système de fichiers ne soient effectués que si et quand la bibliothèque est réellement utilisée. Ceci est simplifié par le fait que les fonctionnalités de chaque bibliothèque sont accessibles uniquement via un objet singleton dans la portée globale du même nom que la bibliothèque. Par exemple:

' StringBuilder.lib ' 

class StringBuilderClass ... end class 

class StringBuilderModule 
    public function [new] 
     set [new] = new StringBuilderClass 
    end function 

    ... 
end class 
dim StringBuilder: set StringBuilder = new StringBuilderModule 

 

import "StringBuilder" 
dim sb: set sb = StringBuilder.new 

Il semble donc que l'approche évidente est l'importateur paresseux pour définir StringBuilder comme un objet qui, quand on y accède, chargera StringBuilder.lib et se remplacer.

Malheureusement, cela est rendu difficile par VBScripts triste manque de constructions de métaprogrammation. Par exemple, il n'y a pas d'analogue à method_missing de Ruby, ce qui aurait rendu l'implémentation triviale.

Ma première pensée a été pour la fonction principale import à utiliser executeGlobal pour créer une fonction globale appelée StringBuilder sans argument qui en StringBuilder.lib de charge de tour et ensuite utiliser executeGlobal à lui-même « l'ombre » (la fonction) avec le StringBuilder singleton. Il y a deux problèmes avec ceci: premièrement, utiliser executeGlobal pour définir une fonction qui se redéfinit elle-même en utilisant executeGlobal semble être une idée plutôt sommaire en général, et deuxièmement, il s'avère que dans VBScript, vous ne pouvez remplacer une fonction que par une variable si la fonction en question est un builtin. Oooookay. La pensée suivante que j'avais était de faire la même chose, sauf qu'au lieu d'utiliser executeGlobal pour remplacer la fonction par une variable, utilisez-la pour remplacer la fonction par une autre fonction qui renvoyait simplement le singleton. Cela nécessiterait que le singleton soit stocké dans une variable globale distincte. Les désavantages de cette approche (mis à part la inhomogénéité inhérente à la stratégie) sont que l'accès au singleton ajouterait un surcroît d'appel de fonction et que, en raison des excentricités d'analyse de l'interpréteur, le singleton ne pourrait plus utiliser les propriétés par défaut.

Dans l'ensemble, c'est un problème plutôt collant, et les bizarreries bizarres de VBScript ne sont d'aucune aide. Toutes les idées ou suggestions seraient les bienvenues.

+6

Man ... C'est une forte volonté d'utiliser asp classique là! – cregox

+0

Pas mon choix. Croyez-moi, ce n'est pas mon idée d'un code élégant. –

+0

@Thom nous avons toujours le choix, mais je vous souhaite bonne chance.Je ne peux pas (prendre la peine de) arrêter d'apprendre et de réfléchir à ce sujet maintenant. :) – cregox

Répondre