On Monday 05 October 2009 16:07:50 Nathan Davis wrote:
> 1. You really should use a consistent naming convention -- either call the
> decorators blockingProducer and transformGenComponent or BlockingProducer
> and TransformGenComponent.
This is currently a sketch - basically a proof of concept, written when I had
time.
In this case concept comes first, followed by an implementation. Point is
taken though :-) Suggestions for better names welcome. (As noted before)
This is after all also the point of /Sketches - it's not intended to
be "perfect" or great - just a place to play with ideas until they become
clear whether they're useful or not. It's a place for putting ideas into, in
concrete form for discussion. It's far easier to point at code after all :)
As you'd expect several things have been renamed on their way out from
Sketches, along with implementation.
> 2. What are these decorators supposed to do, exactly? When would I use
> one over the other?
blockingProducer wraps a generator that contains calls to blocking operations,
and generates data, and transforms it into a component that sends the yielded
values out the default outbox "outbox".
Literally, it results in producer component which uses blocking operations.
Likewise "TransformGenComponent" wraps a generator that performs some
transformation, and returns a component that has that logic. This is actually
the more awkward case - because it requires the generator be push and pull.
For example, currently I essentially do this:
argv = self.argv
if argv[0] == None:
argv = (self.Inbox,) + argv[1:]
Which gets passed to this:
@TransformerGenComponent
def grep(lines, pattern):
regex = re.compile(pattern)
while 1:
for l in lines():
if regex.search(l):
yield l
Resulting in lines() meaning self.Inbox() is called. This means this:
for l in lines():
Iterates over messages waiting in the component's inbox "inbox". (The yielded
values get sent out the outbox "outbox").
If instead of this, we created the generator self.Inbox() outside the
generator like this:
argv = self.argv
if argv[0] == None:
argv = (self.Inbox(),) + argv[1:]
@TransformerGenComponent
def grep(lines, pattern):
regex = re.compile(pattern)
while 1:
for l in lines: # Change
if regex.search(l):
yield l
Then the problem here is that as soon as the inbox was empty, self.Inbox() -
ie "lines" would raise StopIteration, and not be reusable.
Fundamentally, both wrappers are suggested to be used like this:
@wrapper
def someFunction(arg1, otherargs):
do something, possible iterating over arg1, yielding values
The upshot of this being that this transforms the generator function, so that
rather than returning a generator, it returns a component, which can then be
used like any other component.
http://yeoldeclue.com/cgi-bin/blog/blog.cgi?rm=viewpost&nodeid=1254693316
may make this more obvious.
> Adding some descriptive docstrings would go a long way.
It's a proof of concept - there's no way it'd get in the core without doc
strings :-)
> 3. Why did you choose to return a factory function for a single class for
> blockingProducer, but return a dynamically generated class for
> TransformGenComponent?
Again, same reason. 4 months ago I couldn't see how to do this sensibly in
either case. Yesterday it became clear to me that it could be done sensibly,
and so wrote each version in the most directly obvious way to me at the time.
Obviously there's a schism form an implementation perspective, but from a
concept perspective, they're equivalent:
* You decorate a generator function containing your logic
* The resulting function when called returns a component.
* The "input generator" callback gets values from the
component's primary inbox.
* The values yielded are sent out the component's primary outbox.
Does that help?
Incidentally, I generally have the viewpoint of "get it working; get it
working properly/nicely/correctly; make it faster". The stage this code is at
is "get it working".
Michael.
--
http://yeoldeclue.com/blog
http://twitter.com/kamaelian
http://www.kamaelia.org/Home
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"kamaelia" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/kamaelia?hl=en
-~----------~----~----~----~------~----~------~--~---