第一版是針對 Lua 5.0 編寫的。儘管在很大程度上仍然適用於後續版本,但仍有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買這本書,您同時也協助 支援 Lua 專案


15.2 – 私密性

有時候,套件會匯出所有名稱;也就是說,套件的任何用戶端都可以使用這些名稱。不過,通常在套件中使用私有名稱會比較實用,也就是只有套件本身可以使用這些名稱。在 Lua 中,定義這些私有名稱為區域變數是種方便的方法。例如,讓我們在範例中新增一個私有函式,用來檢查值是否為有效的複數。我們的範例現在如下所示

    local P = {}
    complex = P
    
    local function checkComplex (c)
      if not ((type(c) == "table") and
         tonumber(c.r) and tonumber(c.i)) then
        error("bad complex number", 3)
      end
    end
    
    function P.add (c1, c2)
      checkComplex(c1);
      checkComplex(c2);
      return P.new(c1.r + c2.r, c1.i + c2.i)
    end
    
      ...
    
    return P

這種方法的優缺點是什麼?套件中的所有名稱都存在於個別的命名空間中。套件中的每個實體都清楚標示為公開或私有。此外,我們有真正的私密性:私有實體在套件外無法存取。這種方法的缺點是,在存取同一個套件中的其他公開實體時,它的冗長性,因為每個存取仍然需要前置詞 P。更大的問題是,每當我們將函式的狀態從私有變更為公開(或從公開變更為私有)時,我們都必須變更呼叫。

有一個有趣的解決方案可以同時解決這兩個問題。我們可以在套件中宣告所有函式為區域函式,然後再將它們放入要匯出的最終表格中。依照這種方法,我們的 complex 套件會如下所示

    local function checkComplex (c)
      if not ((type(c) == "table")
         and tonumber(c.r) and tonumber(c.i)) then
        error("bad complex number", 3)
      end
    end
    
    local function new (r, i) return {r=r, i=i} end
    
    local function add (c1, c2)
      checkComplex(c1);
      checkComplex(c2);
      return new(c1.r + c2.r, c1.i + c2.i)
    end
    
      ...
    
    complex = {
      new = new,
      add = add,
      sub = sub,
      mul = mul,
      div = div,
    }

現在我們不需要為任何呼叫加上前置詞,因此呼叫匯出的函式和私有函式是相同的。套件的最後有一個簡單的清單,明確定義要匯出的名稱。大多數人覺得在套件的開頭放置這個清單比較自然,但我們無法將清單放在最上面,因為我們必須先定義區域函式。