Well, I ran into a snag. I tried doing this: { my($Skipped, $Skip_Reason); sub test_these (&;$) { my($code, $how_many) = @_; goto $code; # skip() will jump to here to bail out of the $code. CONSIDERED_HARMFUL: if( $Skipped ) { $how_many ||= 1; _skipped($Skip_Reason) for 1..$how_many; } # Reset our state. $Skipped = $Todo = 0; $Skip_Reason = $Todo_Reason = undef; } sub skip { $Skipped = 1; $Skip_Reason = shift; # Yes, an actual goto LABEL! This is what lets skip() abort the # test_these block. goto CONSIDERED_HARMFUL; } sub todo { $Todo = 1; $Todo_Reason = shift; } } Problem is, the goto() inside skip() won't jump to the label inside test_these(). The trouble is the goto $code, used to preserve the caller's context (I want the test_these() block to act as much like a normal block as possibe). goto LABEL looks up the callstack for the label, but the C<goto $code> hijacks the callstack, so it never sees test_these() as part of it and thus can't see CONSIDERED_HARMFUL. Two ways around this: 1) Don't worry about preserving caller() information in the test_these() block. This bothers me. Ideally, a test function should interfere as little as possible with the code. 2) Try a real block. I can make this work easily for skips: SKIP: { skip($why, $how_many) if $condition; ok( $some_test ); ok( $some_other_test ); } using a little known hack that you can use C<last> from outside (lexically outside) a block. sub skip { my($why, $how_many) = @_; $how_many ||= 1; _ok_skipped($why) for 1..$how_many; no warnings; last SKIP; } that takes care of skip. What about todo? TODO: { todo($why); ok( $some_test ); ok( $some_other_test ); } and write todo() the same way as before. ok() would note that the $Todo flag was set and act accordingly. Problem is, I need to unset that $Todo flag at the end of the block. Can't think of a way to do that. -- Michael G. Schwern <[EMAIL PROTECTED]> http://www.pobox.com/~schwern/ Perl6 Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One A tickle of paste Teases down my sweaty thigh Oh, plug it again! -- ignatz