lua-users home
lua-l archive

Re: fallbacks

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> Lua 3.1 doesn't have fallbacks. How do I get fallback like behavior
> out of tags? I want to get tags to apply to *all* tables, not just ones
> I specifically add them too.
All tables have a default tag (you can get its value with "tag{}").
If you set a tag method for this tag, it will aplly
to all "regular" tables (those you did not change the tag).
 For a complete and exact mapping of fallbacks to tag methods, see the
following code. But I don't think you will need all that.
-- Roberto
--------------------------------------------------------------
-- Definition of "setfallback" using tag methods
-- (for compatibility with old code)
--------------------------------------------------------------
-- fallbacks defaults for each event:
local defaults = {
 gettable = function () error('indexed expression not a table') end,
 settable = function () error('indexed expression not a table') end,
 index = function () return nil end,
 getglobal = function () return nil end,
 arith = function () error('number expected in arithmetic operation') end,
 order = function () error('incompatible types in comparison') end,
 concat = function () error('sting expected in concatenation') end,
 gc = function () return nil end,
 ['function'] = function () error('called expression not a function') end,
 error = function (s) write(_STDERR, s, '\n') end,
}
function setfallback (name, func)
 -- set the given function as the tag method for all "standard" tags
 -- (since some combinations may cause errors, use call to avoid messages)
 local fillvalids = function (n, func)
 call(settagmethod, {0, n, func}, 'x', nil)
 call(settagmethod, {tag(0), n, func}, 'x', nil)
 call(settagmethod, {tag(''), n, func}, 'x', nil)
 call(settagmethod, {tag{}, n, func}, 'x', nil)
 call(settagmethod, {tag(function () end), n, func}, 'x', nil)
 call(settagmethod, {tag(settagmethod), n, func}, 'x', nil)
 call(settagmethod, {tag(nil), n, func}, 'x', nil)
 end
 assert(type(func) == 'function')
 local oldfunc
 if name == 'error' then
 oldfunc = seterrormethod(func)
 elseif name == 'getglobal' then
 oldfunc = settagmethod(tag(nil), 'getglobal', func)
 elseif name == 'arith' then
 oldfunc = gettagmethod(tag(0), 'pow')
 foreach({"add", "sub", "mul", "div", "unm", "pow"},
 function(_, n) %fillvalids(n, %func) end)
 elseif name == 'order' then
 oldfunc = gettagmethod(tag(nil), 'lt')
 foreach({"lt", "gt", "le", "ge"},
 function(_, n) %fillvalids(n, %func) end)
 else
 oldfunc = gettagmethod(tag(nil), name)
 fillvalids(name, func)
 end
 return oldfunc or rawgettable(%defaults, name)
end

AltStyle によって変換されたページ (->オリジナル) /