|
Sorry to bring this up yet again, but I just realised the
solution offered by LHdeF does not work in the general case. I am trying to write an object oriented library in which you
can have objects for which the following is valid: for v in obj do ... end Using the __call metamethod you can easily get to: for v in obj() do ... end But the redundant parenthesis rankles. LHdeF suggested: setmetatable(obj, {__call = function(x,y,z) return next(x,z)
end}) Which enables: for k, v in obj do ... end Trouble is this only works when the key (k) is exposed in
the generic for. I cannot see any way of making it work for a stateless
iterator. Thus while it works well for table-like objects it is no good for
list-like or set-like objects were the key is irrelevant and should be
hidden. Furthermore, “consuming” the __call metamethod
for this purpose is a “bodge” – it precludes its use for the
intended purpose and it generates odd side-effects if it is accidentally
invoked in other contexts. So we are back were we started (or have I missed something?)
– what is needed is a new metamethod which is invoked when the explist of
a generic for fails to resolve a function in its first slot. The object
designer could put an iterator factory function in this slot which can return any
form of iterator including stateless. I really cannot see why this solution is resisted – it
is fully backward compatible and syntactically uncomplicated. The context of
the explist is easily distinguishable being bracketed by the reserved words ‘in’
and ‘do’. |