# from Ovid # on Thursday 22 January 2009 15:01: >For example, with your code (as I understand it): > > test { > my $manager = Feed::Manager->new($some_uri); > foreach my $resource ($manager->resources) { > ok my $result = $manager->get($resource), "$resource should > work"; } > } > >Imagine that the Feed::Manager connects to an outside resource I don't > have control over and one day they add a new resource. I now have a > new test and need to know that something has changed.
What is it that you need to know in this case? That resources() is returning a new value? If $manager->get($resource) worked, do you need to know that there are more? If so, you're using the plan as something like a stand-in for the assertion: my @resources = $manager->resources; is(scalar(@resources), 12, "have 12 resources"); And actually, you probably want to assert something like: my @resources = $manager->resources; is_deeply([sort(@resources)], \...@expect_resources); Which fails more descriptively than a plan failure. But all this test() function does -- accounting for perl 5 limitations -- is to run a block of who-cares-how-many assertions and guarantee that the block returns. It only emulates is_deeply() in that regard (and without messing with tap it would simply emit a single ok.) A function which takes a list would be a different thing. test_list(\...@resources, sub { my $resource = shift; ok my $result = $manager->get($resource), "$resource should work"; } }); And this, too, could be fully planned before running by ending with now_run_them() sort of a thing. Or, again with the details: perhaps a pre-pass would cripple the test() and test_list() &c functions to merely *count* their number (and number of arguments). One could then hard-code an assertion into the top of the file. As for skipping and todoing -- the block control is now owned by the function rather than the interpreter root. One could even have a set of test {} calls within a block where the skip setting merely instructs the test calls to not execute their blocks. In which case you wouldn't have to count the number of tests being skipped. (But you would have to ensure that your code-to-skip gets inside the blocks -- because everything has trade-offs.) This does reverse the ownership of control flow. So, I guess I'm basically saying that you simply need to code your tests in a purely functional way to avoid the halting problem. A quick review of S04 doesn't seem to say that we're getting much to do with introspecting blocks, but I'm pretty sure Perl 6 will allow us to declare subroutines which take blocks and lists (or iterators) with less hassle than Perl 5 And yes, iterators reintroduce the halting problem because everything has trade-offs. Nonetheless, you can still magically deduce that we're done_testing() because if any test{} didn't return we hit exit() or whatever in the middle. You can also potentially produce some semblance of a progress report. I don't know if this all means that you need nested tap, or even Perl 6. I do hope it points to what might be possible and even maybe relatively easy. Certainly, I find that the numeric plan is clunky and no_plan is too unguarded. The done() is a step. The numeric plan is not strictly necessary and I think any assertion it performs can be achieved (with better diagnostics) by actually asserting that what you intend to do is done as intended. Maybe that logical transformation from one number to @things and @stuff is not for everyone or is considered overly prescriptive, but there's more than one way to do it and perhaps even three. --Eric -- "It is a mistake to allow any mechanical object to realize that you are in a hurry." --Ralph's Observation --------------------------------------------------- http://scratchcomputing.com ---------------------------------------------------