https://github.com/Test-More/Test2/issues/9
Issue created to do this the easy/efficient way. On Jan 11, 2016 7:14 PM, "Chad Granum" <exodi...@gmail.com> 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... > 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 >> >> >>