Asp-Classic

在 VBScript 中實現延遲載入模組

  • December 9, 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 缺乏元程式結構,這使得這變得困難。例如,沒有與 Ruby 類似的 Ruby method_missing,這會使實現變得微不足道。

我的第一個想法是使用 mainimport函式executeGlobal創建一個名為 StringBuilder 的全域函式,不帶任何參數,然後載入 StringBuilder.lib,然後使用executeGlobalStringBuilder 單例來“隱藏”自身(函式)。這有兩個問題:首先, usingexecuteGlobal定義一個函式,然後覆蓋自身 usingexecuteGlobal似乎是一個相當粗略的想法,其次,事實證明,在 VBScript 中,如果函式有問題的是內置的。哦,好吧。

我的下一個想法是在做同樣的事情,除了executeGlobal使用它來用另一個簡單地返回單例的函式替換函式,而不是用變數替換函式。這將要求將單例儲存在單獨的全域變數中。這種方法的缺點(除了該策略固有的不合理性之外)是訪問單例會增加函式呼叫成本,並且由於解釋器的解析異常,單例不能再使用預設屬性。

總的來說,這是一個相當棘手的問題,而且 VBScript 的怪癖也無濟於事。歡迎任何想法或建議。

Windows 腳本組件在這裡會有所幫助嗎?http://msdn.microsoft.com/en-us/library/07zhfkh8(VS.85).aspx

它基本上是一種使用 VBScript 或 JScript 編寫 COM 組件的方法,您可以使用它進行實例化CreateObject

引用自:https://stackoverflow.com/questions/3497851