[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Question on get/setmetatable()
- From: Sean Conner <sean@...>
- Date: Sat, 16 May 2020 01:13:19 -0400
It was thus said that the Great Andrea once stated:
> Why get/setmetatable() are necessary?
>
> One could simply set a special key such as __metatable by writing something
> like
>
> mt = {}
> t = {}
> t.__metatable = mt
>
> Instead of writing
>
> setmetatable(t,mt)
>
> And similarly for getmetatable()
>
> So what is the reason to keep these functions?
It's mostly exposing the functionality from the C API to Lua. In C,
lua_setmetatable() and lua_getmetatable() are required for supporting
userdata, which are not Lua tables. A good example of this is LPEG [1],
used to parse text by defining composable units of code. For a small
example:
lpeg = require "lpeg"
number = lpeg.R"09"^1 / tonumber
list = lpeg.Ct((number * lpeg.P","^-1)^1)
nums = list:match "1,20,300,4000"
print(nums[1],nums[2],nums[3],nums[4])
'list' is a userdata, which Lua knows nothing about, other than what it can
do via the metatable.
Another reason is that by just assigning the metatable to a field
__metatable required extra work by the Lua VM to check the key on each
assignment for the "special" field __metatable. This also makes it hard to
pretect the __metatable from being manipulated.
The metatable can be protected by setting, strangely enough, the __metatable
field to a value.
t = setmetatable({},{ __metatable = {} })
setmetatable(t,mt)
x = getmetatable(t)
for n,v in pairs(x) do print(n,v) end
setmetatable(t,mt)
With the __metatable field set to a table (and it can be any value other
than nil), getmetatable() will return *that* value rather than the actual
metatable, and trying to reassign a metatable will result in an error.
-spc
[1] http://www.inf.puc-rio.br/~roberto/lpeg/
_______________________________________________
lua-l mailing list -- lua-l@lists.lua.org
To unsubscribe send an email to lua-l-leave@lists.lua.org