[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: This works... but is it guaranteed to?
- From: Enrico Colombini <erix@...>
- Date: Mon, 3 Oct 2022 18:25:55 +0200
Hi, I've not used Lua for some time (due to bad health, workload and
other problems).
tl:dr
-----
if I call f.abc() where .abc does not exist,
create an f.abc subtable in the __index metamethod
and assign a __call metamethod to f.abc,
is the f.abc() call guaranteed to work?
In detail (see attached code)
-----------------------------
In restructuring an ancient program of mine, I'd like:
f.abc(...)
where 'abc' does not exist,
to have the effect of calling:
g("abc", ...)
I did my homework and found a solution (see attached simplified code).
Basically, I create the f.abc subtable in the __index metamethod for f
(nothing strange here) then, while still in the __index metamethod, I
attach to the newly created f.abc a metatable with a __call metamethod.
Note that all this happens in the middle of a pending call of a
non-existing f.abc() 'function', which is akin to changing the engine of
a running car.
It seems to work fine (I tried it in Lua 5.4.0) confirming my impression
that Lua very often effortlessly does 'the right thing', but I'm not
entirely sure it is 'legal'.
So I have two questions:
1) Can I rely on it even in the future, on other platforms, etc.?
2) Is there a simpler way?
--
Enrico
--this is the function that should be called
function g(k, ...)
--[function body here]
print(k, ...)
end
-- pseudo-function table
f = {}
setmetatable(f, {
--f.k is called, but it does not exist
__index = function(t, k)
--create k subtable
t.k = {}
--make it callable
setmetatable(t.k, {
__call = function(f, ...)
g(k, ...)
end}
)
--the pending f.k() __call fires
return t.k
end, --(__index of f)
}
)
--test:
f.abc("Lua", "is very well designed")
---> abc Lua is very well designed