2010-08-16 68 views
9

後來,我需要一個解決方案來在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奇怪的怪癖並沒有幫助。任何想法或建議都會受到歡迎。

+6

人......這就是使用傳統的ASP右邊有一個堅強的意志COM組件的方式! – cregox 2010-08-16 22:24:08

+0

不是我的選擇。相信我,這不是我的優雅代碼的想法。 – 2010-08-17 04:15:28

+0

@我們總是有選擇,但我祝你好運。我不能(懶得)停下來學習,現在就思考這個問題。 :) – cregox 2010-08-17 17:28:53

回答