lua-users home
lua-l archive

Iteration syntax, one more time (cada loco con su tema)

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


I just posted a little patch and some explanatory material to
<http://lua-users.org/wiki/ExtendingForAndNext>.
Summary: The patch adds a "next" tag method which allows the definition of
iteratable userdata (or tables iteratable in a non-default manner) as well
as the possibility to defined generator functions with a consistent syntax.
An example of the second:
function words(str)
 return
 function(k)
 local _, k, v = strfind(%str, "([%w]+)", (k or 0) + 1)
 return k,v
 end
end
-- Some uses:
function count(gen)
 local c = 0
 for k, v in gen do c = c + 1 end
 return c
end
function dictionary(gen)
 local dict = {}
 for k, v in gen do dict[v] = (dict[v] or 0) + 1 end
 return dict
end
function tovector(gen)
 local vec = {n = 0}
 for k, v in gen do tinsert(vec, v) end
 return vec
end
--- Two tag method examples:
VECTOR_TAG = newtag()
settagmethod(VECTOR_TAG, "next",
 function(v, i)
 i = (i or 0) + 1
 if i <= v.n then
 return i, v[i]
 end
 end)
-- use the tag method:
-- (see above)
wordlist = tovector(words(str))
settag(wordlist, VECTOR_TAG)
for i, v in wordlist do
 -- something; i is the numeric indices and v the successive values
end
-- Here's a possibly more interesting example. A Queue is often
-- useful for holding pending tasks. This implementation provides
-- the standard functions but it also provides an iteration method
-- The iteration method is destructive; when you're handed
-- a queue element, it's already been removed from the queue.
-- You can put new things on the queue during the
-- iteration, and they will eventually be iterated over; the
-- iteration ends when the queue is empty.
-- This is not a particularly efficient implementation; I
-- was trying to keep it simple to be illustrative
QUEUE_TAG = newtag()
function qmake() return settag({low = 1, high = 0}, QUEUE_TAG) end
function qget(q)
 local low, v = q.low, nil
 if low <= q.high then
 v, q.low = q[low], low+1
 return v
 end
end
function qput(q, thing)
 q.high = q.high + 1
 q[q.high] = thing
end
function qisempty(q) return q.low > q.high end
settagmethod(QUEUE_TAG, "next",
 function(self) return not qisempty(self), qget(self) end)
Oxfam works with others to find lasting solutions to poverty and suffering.
Oxfam GB is a member of Oxfam International, a company limited by guarantee and registered in England No. 612172.
Registered office: 274 Banbury Road, Oxford OX2 7DZ.
Registered charity No. 202918.
Visit the web site at http://www.oxfam.org.uk

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