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

标签 asp-classic vbscript import metaprogramming

不久前,我需要一个在 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 缺乏元编程结构,这使得这变得困难。例如,没有与 Ruby 的 method_missing 类似的东西。 ,这将使实现变得微不足道。

我的第一个想法是主要的import使用函数executeGlobal创建一个名为 StringBuilder 的全局函数,不带任何参数,然后加载 StringBuilder.lib,然后使用 executeGlobal使用 StringBuilder 单例来“隐藏”自身(函数)。这样做有两个问题:首先,使用 executeGlobal定义一个函数,然后使用 executeGlobal 覆盖自身总的来说,这似乎是一个相当粗略的想法,其次,事实证明,在 VBScript 中,如果所讨论的函数是内置函数,则只能用变量覆盖函数。哦,好吧。

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

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

最佳答案

Windows 脚本组件在这里会有所帮助吗? http://msdn.microsoft.com/en-us/library/07zhfkh8(VS.85).aspx

它基本上是一种使用 VBScript 或 JScript 编写 COM 组件的方法,您可以使用 CreateObject 对其进行实例化。

关于asp-classic - 在 VBScript 中实现延迟加载模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3497851/

相关文章:

javascript - 无法使用 Webpack、Typescript、自定义模块目录找到模块

php - session 集成,这种方法安全吗?

windows - 将参数从 vbscript 传递到批处理文件

mysql - 从 csv 导入 mysql 时保留特殊字符

vbscript - 如何通过脚本(例如 vbScript)在 Windows 7 中启用 RDP 8.0(从组策略)

vbscript - 读取文本文件并显示在表 vbscript 中

database - 将存储过程从一个数据库复制到另一个

jquery - 多个元素上的一个 jQuery 更改事件

javascript - 如何在asp中使用decodeURIComponent?

asp-classic - ASP 格式化日期