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" <exodi...@gmail.com> 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()); >> is($!, 0, "expected $! val"); >> 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 > > >