2010-08-16 21 views
9

Hace un tiempo, necesitaba una solución para importar sanamente bibliotecas en VBScript.Implementación de módulos con carga diferida en VBScript

VBScript, como referencia, no tiene capacidades de importación integradas. El método tradicional de importación de archivos es usar SSI, que vierte el contenido del includee literal en el includer. Esto es menos que óptimo por varias razones: no hay forma de evitar la inclusión múltiple, no hay forma de especificar un directorio de biblioteca, etc. Así que escribí mi propia función. Es bastante simple, utilizando executeGlobal con un diccionario para realizar un seguimiento de los módulos importados y envolviendo todo el asunto en un objeto para la encapsulación:

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" 

De todos modos, esto funciona bastante bien, pero es mucho trabajo si yo no' t termina usando la biblioteca. Me gustaría hacerlo perezoso, de modo que la búsqueda, carga y ejecución del sistema de archivos solo se realicen siempre y cuando la biblioteca se use realmente. Esto se simplifica por el hecho de que se accede a las características de cada biblioteca únicamente a través de un objeto singleton en el ámbito global del mismo nombre que la biblioteca. Por ejemplo:

' 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 

por lo que parece que el enfoque es obvia para el importador perezoso para definir StringBuilder como un objeto que, cuando se accede, se cargará StringBuilder.lib y reemplazarse a sí misma.

Lamentablemente, esto se complica debido a la triste carencia de VBScripts de construcciones de metaprogramación. Por ejemplo, no existe un análogo al Ruby's method_missing, lo que habría hecho la implementación trivial.

Mi primer pensamiento fue para la función principal import utilizar executeGlobal para crear una función global llamada StringBuilder sin argumentos que, a su vez, StringBuilder.lib carga y luego utilizar executeGlobal a "sombra" en sí (la función) con el StringBuilder semifallo. Hay dos problemas con esto: primero, usar executeGlobal para definir una función que luego se sobrescribe utilizando executeGlobal parece ser una idea bastante superficial en general, y segundo, resulta que en VBScript, solo puede sobrescribir una función con una variable si la función en cuestión es un builtin. Oooookay.

La siguiente idea que tuve fue hacer lo mismo, excepto que en lugar de usar executeGlobal para reemplazar la función con una variable, úsela para reemplazar la función con otra función que simplemente devolvió el singleton. Esto requeriría que el singleton se almacenara en una variable global separada. Las desventajas de este enfoque (aparte de la incoherencia inherente de la estrategia) son que el acceso al singleton agregaría una sobrecarga de llamada de función y que, debido a las excentricidades de análisis del intérprete, el singleton ya no podría usar las propiedades predeterminadas.

En general, es un problema bastante pegajoso, y las peculiaridades de VBScript no son de ayuda. Cualquier idea o sugerencia sería bienvenida.

+6

hombre ... Eso es una fuerte voluntad de utilizar ASP clásico ahí! – cregox

+0

No es mi elección. Créanme, esta no es mi idea de código elegante. –

+0

@Thom siempre tenemos otra opción, pero te deseo buena suerte.No puedo (me molesto) detenerme para aprender y pensar sobre esto ahora mismo. :) – cregox

Respuesta

Cuestiones relacionadas