----- Original Message ---- 
From: Randy W. Sims  
 
> > A stream is merely a coderef which returns "chunks" of TAP.  When it 
> > returns undef, the stream is considered finished.  It will be trivial for 
> > me to change this, if needed. 
 
> What is a "chunk"? Is it a "line"? A partial or multiple lines? Can it  
> contain a partial or more than one complete "expression"? 
 
It is a line or multiple lines.  The lexer cannot reliably lex partial lines. 
 
> Still not sure about the coderef. An object could possibly be more  
> flexible, but I can't think of an actual use-case atm, and coderefs are  
> possibly easier on the user. 
 
Already changed to an object in the latest version:  
http://search.cpan.org/dist/TAPx-Parser/ 
 
> > Second, "Bail out!" doesn't stop the parser.  A careful reading of the TAP 
> > docs made it clear that this the the TAP generator's responsibility, not 
> > the parsers.  I can change this behavior, if necessary. 
 
> That sounds right. I'm assuming that a stream is one planned test "file"  
> and no more, so that everything in the stream relates to that one plan. 
 
Right. 
 
> >    while ( my $result = $parser->results ) { 
> >        print $result->as_string; 
> >     }   
 
> The method name results() doesn't convey any meaning, nor does it make  
> it obvious that it is an iterator. I liked next() better. 
 
Hmm, I didn't like the name "results" either.  Yeah, I think next() sounds 
good.  Any vetoes? 
 
> I notice that TAPx::Parser::Grammar contains information about each of  
> the Results types. Could it be moved into the Results types? Maybe let  
> the Results types be sort of like plugins that register a rule. When the  
> rule matches you invoke the constructor for the matching Results class  
> and return it. 
 
I do like this suggestion, but it implies that I need to think about how to 
handle the versioning.  By having TAPx::Parser::Grammar contain this 
information, I could have all of the grammar information encapsulated in one 
place and my intention was to enventually have something like: 
 
   TAPx::Parser::Grammar::V1 
  TAPx::Parser::Grammar::V2 
   TAPx::Parser::Grammar::V2_1 
 
And so on, and then fetch the appropriate grammar using a passed in version 
number.  Still, I wasn't certain how well this would play with how I had the 
result objects set up.  How would I properly version them?  Suggestions 
welcome. 
 
> You would possibly have to include a way of ordering the rules so that  
> rules are checked in the correct order. 
 
Currently in TAP, the order of rule checking is irrelevant as there's no 
ambiguity in how an individual line is parsed.  There *are* efficiency gains to 
be made (check for tests before bailouts, for example), but that's it. 
 
> All the is_${type} methods feel wrong (from a purely abstract  
> design-type perspective), but I guess I don't know enough about how the  
> Parser is going to be used and extended to suggest alternatives. 
 
Agreed.  I'm not too happy with them either, but the source of tprove 
(http://search.cpan.org/src/OVID/TAPx-Parser-0.11/examples/tprove), you can see 
how those come in handy.  The problem is that I really don't like the resulting 
if/elsif chains since those are so prone to bugs.  I've thought about allowing 
callbacks to be set for each type like this: 
 
  my %callbacks = ( 
      test    => \&_test_callback, 
      comment => \&_comment_callback, 
      ... 
  ); 
  my $parser = TAPx::Parser->new({ 
      stream    => $stream, 
      version   => $version, 
      callbacks => \%callbacks 
  }); 
  $parser->run; 
  # or for fine-grained control: 
  while ( my $result = $parser->next ) { 
      $result->do_callback; 
      # extra stuff 
  } 
 
Thoughts?

Cheers, 
Ovid 
 
 
 


Reply via email to