Test2, the dist, is just internals. It provides no tools. It does not
have ok(), is(), etc.Um, so... what *is* Test2 then? (And the second question would be: and what
does it have to do with Test::More?) Without context, your first question
is equivalent to "should Foo::Bar maintain $! and $@?".
On Mon, Jan 11, 2016 at 7:14 PM, Chad Granum wrote:
Some things I forgot to mention:
Test2, the dist, is just internals. It provides no tools. It does not have
ok(), is(), etc. What I am talking about is not thr simple task of putting
local $! In some exports. This is localizing $! Around any call to use,
require, open, close, etc. Anything that can alter a handle, write a file,
etc.
The reason for these extreme measures is because that is what
Test::Builder does. Test::More does not localize $! In ok() and is(), it
instead has protections scattered about its internals.
So my proposal is not to write tools that modify $!, it is to spare the
internals from all these hurdles and let the tools do the $! Protection if
they need it.
Now, lots of things depend on Test::Builder jumping through these hoops,
so I will ensure Test::Builder still protects $!.
The question is, do I accomplish this by wrapping everything that
canchange $! In all the Test2 internals, or do I do it by having
Test::Builder protect them when it calls out to Test2? The latter option
would reduce the complexity of Test2, but not break things.
As for tools, yes, preserving $! Is a valuable behavior, but I think it
belongs at the tool level, not the internals.
That said, it just occured to me that this can possibly be accomplished by
having a context store $! And $@ when it is obtained, then restore them
when it is released, which would avoid needing to use local everywhere, and
still preserve them for all tools automatically...
Some things I forgot to mention:
Test2, the dist, is just internals. It provides no tools. It does not have
ok(), is(), etc. What I am talking about is not thr simple task of putting
local $! In some exports. This is localizing $! Around any call to use,
require, open, close, etc. Anything that can alter a handle, write a file,
etc.
The reason for these extreme measures is because that is what
Test::Builder does. Test::More does not localize $! In ok() and is(), it
instead has protections scattered about its internals.
So my proposal is not to write tools that modify $!, it is to spare the
internals from all these hurdles and let the tools do the $! Protection if
they need it.
Now, lots of things depend on Test::Builder jumping through these hoops,
so I will ensure Test::Builder still protects $!.
The question is, do I accomplish this by wrapping everything that
canchange $! In all the Test2 internals, or do I do it by having
Test::Builder protect them when it calls out to Test2? The latter option
would reduce the complexity of Test2, but not break things.
As for tools, yes, preserving $! Is a valuable behavior, but I think it
belongs at the tool level, not the internals.
That said, it just occured to me that this can possibly be accomplished by
having a context store $! And $@ when it is obtained, then restore them
when it is released, which would avoid needing to use local everywhere, and
still preserve them for all tools automatically...
On Jan 11, 2016 4:53 PM, "Chad Granum" wrote:
Test::More/Test::Builder work VERY hard to ensure nothing inside them
alters $! or $@. This is for thing like this:
ok(do_something_scary());
Without Test::More/Builder being careful to support this, the second 2
assertions could fail because something inside ok() modifies $! or $@.
*I cannot change Test::Builder/More* they must continue to protect $!
and $@, otherwise things break (I have a few downstream samples to show
that it does).
However. It is easy enough to have Test::Builder/More protect $! and $@
without requiring Test2 to do so.
Since Test2 is new, and nothing depends on any of its behaviors yet, I am
considering having Test2 not care about modifying $! and $@. So far I have
been taking care to preserve $! and $@, but it does add significant
complexity (and minor, but noticeable slowdown) to Test2.
*Reasons for dropping this promise from Test2:*
- Simplifies code
- $! and $@ are altered by many many things, adding { local ... }
around all of them is a pain
- Sometimes internals you don't expect to set $! will
- Perl itself documents that you cannot depend on $! and $@ being
unchanged past the immediate line after you set it.
- Test::Builder will continue to protect $! and $@, so nothing will
break
- Test2 is new, nothing depends on it preserving these
*Reasons not to drop it:*
- It is helpful to people who might not realize $! and $@ are often
altered unexpectedly.
I am asking for input in case I missed any reasons/arguments for either
side. In either case backwards compatibility will be preserved.
-Chad
Test::More/Test::Builder work VERY hard to ensure nothing inside them
alters $! or $@. This is for thing like this:
ok(do_something_scary());
is($!, 0, "expected $! val");
is($@, undef, '$@ not changed');
is($@, undef, '$@ not changed');
Without Test::More/Builder being careful to support this, the second 2
assertions could fail because something inside ok() modifies $! or $@.
*I cannot change Test::Builder/More* they must continue to protect $!
and $@, otherwise things break (I have a few downstream samples to show
that it does).
However. It is easy enough to have Test::Builder/More protect $! and $@
without requiring Test2 to do so.
Since Test2 is new, and nothing depends on any of its behaviors yet, I am
considering having Test2 not care about modifying $! and $@. So far I have
been taking care to preserve $! and $@, but it does add significant
complexity (and minor, but noticeable slowdown) to Test2.
*Reasons for dropping this promise from Test2:*
- Simplifies code
- $! and $@ are altered by many many things, adding { local ... }
around all of them is a pain
- Sometimes internals you don't expect to set $! will
- Perl itself documents that you cannot depend on $! and $@ being
unchanged past the immediate line after you set it.
- Test::Builder will continue to protect $! and $@, so nothing will
break
- Test2 is new, nothing depends on it preserving these
*Reasons not to drop it:*
- It is helpful to people who might not realize $! and $@ are often
altered unexpectedly.
I am asking for input in case I missed any reasons/arguments for either
side. In either case backwards compatibility will be preserved.
-Chad