> 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 <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
>>
>>
>>

Reply via email to