Perl's not the only TAP source

David E. Wheeler david at kineticode.com
Sat Jun 20 19:55:54 GMT 2009


On Jun 20, 2009, at 6:14 AM, Steve Purkis wrote:

> Nice - that's exactly the kinda thing I had in mind :-).

Me too. I want to show off a released version of TAP::Harness/Parser  
running Perl, pgTAP, and JavaScript tests at OSCON next month.

>> So, where are we at?
>
> Unfortunately I've not had any time to come back to this until now,  
> been bloody busy, as you can probably tell by sporadic replies.  But  
> I have been following the thread...

Yeah, I know how it goes.

> I take the point on not being forced to sub-class to write a plugin,  
> using roles is fine by me so long as we include an instantiation step.

What for? I mean, what's the difference between calling functions in a  
module and passing an object vs. calling methods on objects? Requiring  
instantiation means source authors have to implement three methods.

> That way it gives the best of both worlds - that way the internal  
> classes can all be implemented by sub-classing to share common code,  
> and the external plugins can do whatever they want.

What common code? In the example I provided, the code was pretty  
damned simple. I pretty much removed all of the duplicate code.

> As far as I can tell, there are 2 options:
> * source & formatter plugins only (ie: source API stays the same)
> * generic plugins (API not defined yet)

Agreed. We already have pluggable formatters, no?

> 2. Figure out what to do with TAP::Parser::Iterators.
> I'm still not convinced we need a separate class of iterators for  
> the parser to use.  Source classes could be iterators too, and that  
> would remove the need for the IteratorFactory class, which basically  
> just makes decisions the Sources could make themselves.

Well, if sources aren't classes, then not so much. It's also mixing  
two things into one class/module: source detection and determination  
and iteration. Two completely separate things. It makes much more  
sense to me if the sources simply say whether they can handle a  
particular source and to return an iterator for said source.

> Of course, in your examples you seem happy to delegate the running  
> commands to the iterator classes.  So maybe they should stay after  
> all?  Or maybe we can just get rid of the 'Factory' class, and let  
> the source classes use the iterators directly?  I know I introduced  
> it, and for valid reasons at the time.  I just feel it over- 
> complicates things now.

I don't care if there's a factory, though; it's fine with me for each  
source to just us the appropriate iterator class directly.

> 3. Convert the Source & SourceFactory API to use roles.
> At a glance, I like your suggestions (can_handle / source).

can_handle/stream in my last proposal.

> But I'd need to think more about how the interface and make sure we  
> handle everything (source config, command params, sharing common  
> code, etc), before refactoring.

There isn't a lot of common code; indeed, there's almost no code at  
all. That's the beautiful thing. The config, params, etc., can all be  
passed in via an object. Hell, if there is common code you can have it  
in methods on that object.

> I've had a quick think about the make_with_rawsource /  
> make_with_command idea, and realized that this would be pushing the  
> decision about what type of source you've got into the  
> SourceFactory. My first reaction is: that's asking it to do too  
> much.  The whole point of having source detectors was so that they  
> can make the decision.  Yes, it does do some detective work to  
> assemble meta data, but that was more to avoid code duplication, the  
> detectors can still ignore it if they choose.  My second reaction  
> is: that could simplify the API some, which is good for the plugin  
> writer.

Not following you here. With my latest example, there is just a  
stream() function in the source that knows what kind of iterator to  
return. So the Raw source would return a raw iterator, while the PHP  
source would return an exec iterator.

> My third though is your suggestion on passing objects through might  
> be the way to go.

Yes, exactly.

> 4. Update docs.
> Make sure they're all still relevant.  Not just API docs, sub- 
> classing docs too.  Include examples.

Agreed.

> 5. Deprecated API release.
> Once we all agree on this, we should make a point release to  
> deprecate the API before we do the real release.  As this changes  
> the API quite a bit, is it worth bumping up the minor release number?

I thought that the API was preserved, that this stuff was all in  
addition. No?

> Now the bad news as for when I'll be free...  I've got an exam to  
> prep for in a week and a half, so hopefully after that.

As I said, I'd love to get this done by OSCON so I could show it off  
to all the Perl geeks there and make the Ruby, Python, and PHP geeks  
jealous!

Best,

David



More information about the tapx-dev mailing list