On Sat, Mar 17, 2001 at 05:20:23PM +0000, Piers Cawley wrote:
> Michael G Schwern <[EMAIL PROTECTED]> writes:
>
> > Ok, that's great. But then Piers Cawley cried out "HALTING PROBLEM!"
> > from the front row (and get your feet off the stage).
>
> My heckles have always been of the highest quality.
>
> > > From: Piers Cawley <[EMAIL PROTECTED]>
> > > Subject: Re: [FWP] Stumper
> > > To: Michael G Schwern <[EMAIL PROTECTED]>
> > > Cc: [EMAIL PROTECTED]
> > >
> > >
> > > Isn't this a halting problem issue?
> > >
> > > foo { bar() if bar() && bar() };
> > >
> > > How many times does bar get run?
> >
> > To which my reply is basically, "Oh crap."
>
> Ah well, better to find the problem early.
I've been mostly following all this without having had the time to
follow it in detail, and I keep thinking about the parenthetical comment
Joshua Pritikin put in Test.pm, viz "(Your test code should be simpler
than the code it is testing, yes?)".
OK, so this isn't the user's test code, but it seems to me that getting
anywhere near the halting problem means that we've taken a wrong turn
somewhere. Some of the other suggestions on FWP (admittedly provided
without full knowledge of the use to which they might be put) included
use of the B modules and temporary redefinition of ok(). These also
strike me as being a little to complicated for test code.
I have gone back and read the discussion so far. Is "better late than
never" still true? Feel free to withhold judgement ....
If we're allowed to mess with the interface, my counter proposal would
be to simplify it rather than complicate or extend it. Here are some
thoughts:
Planning.
I understand the motivation behind the ideas discussed here, but I don't
see any problem with the current method whereby the number of tests
needs to be declared at the start of the run. OK, so we all run the
script, see how many tests there were and then fill in the number. This
still strikes me as safer than not having the number there. I could
fairly easily be persuaded that having the number specified at the end
is probably OK, but I wouldn't want to recommend it as general practice.
ok()
May I propose the following interface?
ok($scalar, $test_name, $reason);
I suspect that the semantics are fairly obvious. If $scalar is true the
test passes, otherwise it fails. $test_name needs no explanation, and
it need not be present. $reason is ignored if present. It is only
there to match todo() and skip(). Details below.
My motivation for this simple interface is that I see little benefit to
me as a module author in being able to write
ok($x, 17);
rather than
ok($x == 17);
If anything, the latter is more explicit. Think of it as removing all
special cases :-)
ok($x =~ /qaz/);
seems preferable to
ok($x, qr/qaz/);
At a stroke, all the problems associated with eq/ne/lt/... and similar
groups have been solved.
I don't even see the need for passing a subroutine reference to be run.
Why not run it yourself, and pass the result?
todo()
Changing the todo() interface has merit I think, but I would suggest
that changing a test from todo() to ok() should simply be a matter of
changing the name of the function. In other words, I would like todo()
and ok() to be identical, except for the expectation of success or
failure. For todo(), $reason is, of course, the reason the test should
fail.
skip()
Using the same interface as ok() and todo(), skip() skips the test for
$reason. If $reason changes (eg Windows supports file locking) the test
can just change to ok(). If it changes from skip() to todo(), $reason
may need to be changed, but if it wasn't it would probably still be
somewhat appropriate.
I see the motivation for having a parameter to distinguish between
skipping and running the test, but how often does this happen in
practice? I wouldn't be opposed to a function which called either ok()
or skip() based on a parameter if people feel strongly about it.
Prototypes.
I would suggest not prototyping the functions. This will make writing a
wrapper function easier if that is needed.
ONFAIL.
I don't think anyone has mentioned this yet. I've never seen it used,
but I wouldn't want to just chuck it out. It must have scratched some
itch.
That's it. Basically, KISS. We really don't want bugs in the test
code. I'm willing to be told that I've oversimplified, but I'd like to
see real code that has to jump through hoops to cope with this
interface.
I was about to write a detailed critique of Michael Schwern's original
proposal, but most of the comments would now be redundant, based on what
I have written above. I'll still do so, if necessary, but I think I'll
wait to see if anyone has any comments about my ideas.
--
Paul Johnson - [EMAIL PROTECTED]
http://www.pjcj.net