[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Iteration syntax, one more time (cada loco con su tema)
- From: RLake@...
- Date: Tue, 11 Sep 2001 18:48:38 -0500
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