後來,我需要一個解決方案來在VBScript中正確導入庫。在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的本身(功能)全局函數單身。這有兩個問題:首先,使用executeGlobal
來定義一個函數,然後使用executeGlobal
覆蓋自己似乎是一個相當粗略的想法,第二,事實證明,在VBScript中,只能用一個變量覆蓋函數if有問題的功能是內建的。 Oooookay。
接下來我想到的是做同樣的事情,除了用executeGlobal
來替換函數與變量,用它來代替函數與另一個簡單地返回單身的函數。這將要求單例存儲在一個單獨的全局變量中。這種方法的缺點(除了策略固有的不確定性之外)是訪問單例會增加函數調用開銷,並且由於解釋器的解析偏心,單例不再使用默認屬性。總的來說,這是一個相當棘手的問題,VBScript奇怪的怪癖並沒有幫助。任何想法或建議都會受到歡迎。
人......這就是使用傳統的ASP右邊有一個堅強的意志COM組件的方式! – cregox 2010-08-16 22:24:08
不是我的選擇。相信我,這不是我的優雅代碼的想法。 – 2010-08-17 04:15:28
@我們總是有選擇,但我祝你好運。我不能(懶得)停下來學習,現在就思考這個問題。 :) – cregox 2010-08-17 17:28:53