[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Accumulator
> takes a couple of classes from LWP (Perl's libwww) and the required
> control structures to spider and perform link checking, and implements
> something *more* functional and extensible in roughly half the code.
This reminds me of some Python code that I've written. The function named
`spider()' takes two arguments: an object in memory and a function. It
traverses all the transitively reachable objects in the Python runtime and
invokes the function once on each. Here's the code (also visible at [1]).
def spider(startnode, func, maxdepth=None):
"""
visits each node once
@param func a func which takes two arguments: the current object, the
previous object which refers to the current object; If the func
returns `-1', then spider() will *not* recurse on that object. If the
func returns `-2', then spider() will exit.
"""
# traverse (depth-first) all memory starting with `startlist' and for each object o, invoke `func(o, p)'
a = {}
return _rec_spider(startnode, a, func, maxdepth=maxdepth)
def _rec_spider(o, a, func, d=0, maxdepth=None):
if o is a or o is locals():
return # skip things that we know may contain it or that we've already visited
for nt in get_references(o):
if not a.has_key(id(nt)):
ret = func(nt, o)
a[id(nt)] = None
if ret == -2:
return -2
elif ret == -1:
continue
elif ((maxdepth is None) or (d < maxdepth)):
if _rec_spider(nt, a, func, d=d+1, maxdepth=maxdepth) == -2:
return -2
This is 17 lines of code (excluding comments and doc strings), and the
interface is flexible enough to do what I want. Even if the Lisp version
turns out to be so blindingly elegant and flexible that it is implemented in
1 line of code and washes my dishes, I doubt that I'll care. The code above
is good enough for me, and I spend my day writing more complicated things
(in Python), not rewriting this function to be ever more "elegant".
Regards,
Zooko
-------
Secure Distributed Systems Consulting -- http://zooko.com/
-------
[1] http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/pyutil/pyutil/memutil.py?rev=HEAD&content-type=text/vnd.viewcvs-markup