Asp classic 在VBScript中实现延迟加载模块

Asp classic 在VBScript中实现延迟加载模块,asp-classic,vbscript,import,metaprogramming,Asp Classic,Vbscript,Import,Metaprogramming,不久前,我需要一个解决方案来在VBScript中正常导入库 仅供参考,VBScript没有内置导入功能。导入文件的传统方法是使用SSI,它会将includee的内容逐字转储到includer中。这并不是最优的,原因有很多:无法避免多次包含,无法指定库目录,等等。所以我编写了自己的函数。使用executeGlobal和一个字典来跟踪导入的模块,并将整个模块封装到一个对象中,这相当简单: class ImportFunction private libraries_ private

不久前,我需要一个解决方案来在VBScript中正常导入库

仅供参考,VBScript没有内置导入功能。导入文件的传统方法是使用SSI,它会将includee的内容逐字转储到includer中。这并不是最优的,原因有很多:无法避免多次包含,无法指定库目录,等等。所以我编写了自己的函数。使用
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定义为一个对象,当访问该对象时,它将加载StringBuilder.lib并替换自身

不幸的是,由于缺乏元编程结构,这就变得很困难。例如,没有类似Ruby的
方法_missing
,这会使实现变得微不足道

我的第一个想法是,main
import
函数使用
executeGlobal
来创建一个名为StringBuilder的全局函数,该函数不带任何参数,而这些参数将依次加载StringBuilder.lib,然后使用
executeGlobal
来对StringBuilder单例“隐藏”自身(函数)。这有两个问题:首先,使用
executeGlobal
定义一个函数,然后使用
executeGlobal
重写它自己,这在总体上看起来是一个相当粗略的想法;其次,在VBScript中,如果所讨论的函数是内置函数,则只能使用变量重写函数。好的

我的下一个想法是做同样的事情,除了不使用
executeGlobal
用变量替换函数,而是用另一个只返回单例的函数替换函数。这需要将单例存储在单独的全局变量中。这种方法的缺点(除了策略固有的不确定性)是访问单例会增加函数调用开销,并且由于解释器的解析异常,单例不能再使用默认属性


总的来说,这是一个相当棘手的问题,而VBScript的古怪怪癖也无济于事。欢迎提出任何想法或建议。

Windows脚本组件在这里有帮助吗


基本上,这是一种使用VBScript或JScript编写COM组件的方法,您可以使用
CreateObject

手动对其进行实例化。。。这是一个强烈的意愿,使用经典的asp的权利!不是我的选择。相信我,这不是我对优雅代码的看法。@Thom我们总是有选择的,但我祝你好运。我现在不能(费心)停下来学习和思考这个问题那么你有没有改进或解决过这个问题?我想说的是:让系统来处理加载不需要的东西的额外开销,然后定义它们,或者实现一个“try-catch”式的延迟加载。。。这是我唯一看到的两个。只是好奇你是否找到了前进的道路,或者你是否想继续追求它。我也很好奇,为什么您需要继续支持VBScript,而没有进一步的进展。我认为最后一个选项是最好的:importingfoo定义了一个函数Foo,该函数将模块导入变量Foo_u并返回它。开销不是很多,但是缺少默认属性很烦人,因为我一直将它们用作构造函数。(VBScript不允许在实构造函数中使用参数。)
' 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