Lua利用元表实现修饰器

基础概念概述

有时我们要为一些对象增加元数据(文档,变量类型什么的),但有时对象是从别处来的,没法修改内部,所以要用到修饰器。

注:本文的对象指lua中的table,function,userdata等。

什么是修饰器?

修饰器可以理解成数学中的算子,接受一个函数,返回修饰过的一个函数,例如微分算子,可以返回函数的导函数。修饰器与它类似,就是接受一个对象,返回修饰过的对象。

文档字符串(docstring)

用来说明对象的功能,使用方法的一个字符串,随着对象传递,可以使用特定的函数获取该字符串(例如py中的help函数)。

利用元表模拟文档修饰器

利用lua强大的元表功能,可以很方便的实现修饰器,给对象增加docstring。在lua的中,每一个对象可以用作table的key,也就是所谓的弱表(weak table,具体见《lua程序设计第一版》第十七章 weak 表)。所以只要建立一个全局表,,用对应对象做key,来存储每个对象的docstring,就可以了,具体实现:

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

代码来自lua-user wiki

用运算符重载

像下面这个:

random = docstring[[Compute random number.]] .. typecheck(“number”, ‘->’, “number”) .. .random(n) end

重载了.. 运算符,为什么要这样?这样就可以省去一对括号,让人看不出docstring是一个函数= =

可以用下列代码实现:

mt = {__concat = print(“decorator”, table.concat(a, “,”), …)return f(…)end end} return setmetatable({…}, mt) return setmetatable({…}, mt)end

btw,除了..运算符,你也可以重载别的,反正看起来好看就行。

不论你在什么时候结束,重要的是结束之後就不要悔恨

Lua利用元表实现修饰器

相关文章:

你感兴趣的文章:

标签云: