註解與文件字串

lua-users home
wiki

模式:註解、標註和文件字串

有時我們會想將一些元資料與物件關聯起來,例如物件的文件或類型資訊。我們可以將這些資料儲存在物件中的欄位內,藉此修改物件的實作,但這有可能會導致一些問題,特別是在這個物件屬於別人的時候(資訊隱藏)。實際上,如果是函式或唯讀表格,我們可能無法修改物件。

一種解決方法基本上是建立一個將物件(作為鍵)對映到它們的標註(作為值)的全球表格。根據定義,物件擁有獨特的識別碼,因此可以在表格中作為唯一的鍵。以這種方式,物件本體並不會被修改。由於全球表格包含物件的參考,此舉會對垃圾收集造成些許干擾,但我們可以使用 Lua 中的「弱表格」來達成此目的(請參閱《Lua 程式設計》一書中的 LuaBooks)。

以下是將文件字串 [1] 套用到 Lua 物件的方法。

local docstrings = setmetatable({}, {__mode = "kv"})
 
function document(str)
  return function(obj) docstrings[obj] = str; return obj end
end
 
function help(obj)
  print(docstrings[obj])
end
 
document[[Print the documentation for a given object]](help)
document[[Add a string as documentation for an object]](document)
 
f = document[[Print a hello message]](
  function()
    print("hello")
  end
)
f()
help(f)

請注意:如果標註是指回標註物件的物件,垃圾收集可能會失敗(請參閱 GarbageCollectingWeakTables)。

Perl 中的「反向物件」使用了有點類似的模式。

可以在其他情況套用此模式,例如在不對物件進行任何變更的情況下將元資料套用到物件。這些情況包括在 Python 中使用的函式註解 [2] [3]

以下替換語法可以用來套用函式註解到函式,會比較好

random =
  docstring[[Compute random number.]] ..
  typecheck("number", '->', "number") ..
  function(n)
    return math.random(n)
  end

函式註解可以基本上以這種方式實作

mt = {__concat =
  function(a,f)
    return function(...)
      print("decorator", table.concat(a, ","), ...)
      return f(...)
    end
  end
}

function typecheck(...)
  return setmetatable({...}, mt)
end

function docstring(...)
  return setmetatable({...}, mt)
end

在這裡,在函式註解和函式之間使用運算子(..)可以避免函式周圍出現括號,並讓註解鏈串在一起更好看。我們要這個運算子具有右結合性,因此這個運算子唯一可選擇的選項為 ..^

另請參閱 LuaTypeChecking,了解用於表達函式參數和回傳類型的註解具體用法。

--DavidManura,2007-02


RecentChanges · 喜好設定
編輯 · 歷史記錄
上次編輯於 2009 年 5 月 2 日,早上 2:26,格林威治標準時間 (相異之處)