Реализация модулей с отложенной загрузкой в ​​VBScript - PullRequest
9 голосов
/ 17 августа 2010

Некоторое время назад мне нужно было решение для разумного импорта библиотек в VBScript.

VBScript, для справки, не имеет встроенных возможностей импорта.Традиционный метод импорта файлов заключается в использовании SSI, который выгружает содержимое дословного включения во включающее устройство.Это менее чем оптимально по ряду причин: нет способа избежать множественного включения, нет способа указать каталог библиотеки и т. Д. Поэтому я написал свою собственную функцию.Это довольно просто, используя executeGlobal со словарем для отслеживания импортированных модулей и оборачивая все это в объект для инкапсуляции:

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"

В любом случае, это работает довольно хорошо, но это много работыесли я не в конечном итоге использовать библиотеку.Я хотел бы сделать это ленивым, чтобы поиск, загрузка и выполнение файловой системы выполнялись только в том случае, если библиотека фактически используется.Это упрощается тем, что к функциям каждой библиотеки обращаются исключительно через одноэлементный объект в глобальной области действия с тем же именем, что и библиотека.Например:

' 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

Таким образом, очевидно, что для ленивого импортера очевидным подходом является определение StringBuilder как объекта, который при доступе загружает StringBuilder.lib изаменить себя.

К сожалению, VBScripts затрудняет это из-за отсутствия метапрограммирующих конструкций.Например, не существует аналога method_missing Руби, который сделал бы реализацию тривиальной.

Сначала я подумал о том, чтобы основная функция import использовала executeGlobal для создания глобальной функции с именем StringBuilder.не принимая аргументов, которые, в свою очередь, загружали бы StringBuilder.lib, а затем использовали executeGlobal, чтобы "затенить" себя (функцию) с помощью синглтона StringBuilder.С этим есть две проблемы: во-первых, использование executeGlobal для определения функции, которая затем переопределяет себя с использованием executeGlobal, в целом выглядит довольно схематично, а во-вторых, оказывается, что в VBScript вы можете переопределить только функциюс переменной, если рассматриваемая функция является встроенной.Oooookay.

Следующая мысль, которую я имел, делала то же самое, за исключением того, что вместо того, чтобы использовать executeGlobal для замены функции переменной, используйте ее для замены функции другой функцией, которая просто возвращает одиночный код.Это потребует, чтобы синглтон был сохранен в отдельной глобальной переменной.Недостатки этого подхода (помимо присущей ему некошерстности стратегии) ​​заключаются в том, что доступ к синглтону привел бы к дополнительным накладным расходам при вызове функции и что из-за эксцентриситета синтаксического анализа интерпретатора синглтон больше не мог использовать свойства по умолчанию.В целом, это довольно сложная проблема, и странные причуды VBScript не помогают.Любые идеи или предложения приветствуются.

1 Ответ

2 голосов
/ 10 декабря 2010

Помогут ли здесь компоненты Windows Script? http://msdn.microsoft.com/en-us/library/07zhfkh8(VS.85).aspx

Это в основном способ написания компонентов COM с использованием VBScript или JScript, создание которых вы можете создать с помощью CreateObject

...