前段时间,我需要一个能够在VBScript中灵活导入库的解决方案。
作为参考,VBScript没有内置导入功能。导入文件的传统方法是使用SSI,它将includee逐字的内容转储到包含器中。由于多种原因,这不是最优的:没有办法避免多次包含,没有办法指定库目录等等。所以我编写了自己的函数。这很简单,使用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单例的“shadow”本身(函数)。这有两个问题:首先,使用executeGlobal
来定义一个函数,然后使用executeGlobal
覆盖它自己似乎是一个相当粗略的想法,其次,事实证明,在VBScript中,你可以如果所讨论的函数是内置函数,则仅覆盖带变量的函数。 Oooookay。
我的下一个想法是做同样的事情,除了使用executeGlobal
替换函数与变量,使用它来替换函数与另一个简单返回单例的函数。这将要求将单例存储在单独的全局变量中。这种方法的缺点(除了策略固有的不合理之外)是访问单例会增加函数调用开销,并且由于解释器解析偏心,单例不能再使用默认属性。
总的来说,这是一个相当棘手的问题,VBScript奇怪的怪癖没有任何帮助。任何想法或建议都会受到欢迎。
答案 0 :(得分:2)
Windows Script Components会在这里提供帮助吗? http://msdn.microsoft.com/en-us/library/07zhfkh8(VS.85).aspx
这基本上是一种使用VBScript或JScript编写COM组件的方法,您可以使用CreateObject
实例化