Mailing List Archive

warnings due to module loading order
Hi all,

In larger code bases, we keep getting hit with behavior like this:

$ perl -E 'use Moose; use experimental "signatures"; sub foo($bar)
{$bar + 41}; say foo(1)'
42
$ perl -E 'use experimental "signatures"; use Moose; sub foo($bar)
{$bar + 41}; say foo(1)'
The signatures feature is experimental at -e line 1.
42

In the second example, we get the warning because Moose reloads warnings.
For modules which explicitly disable warnings, it's because we *want *to
explicitly disable those warnings (experimental.pm explicitly unimports
related warnings).

For larger code bases, merely sorting a list of modules you've imported
could cause strange warnings to appear. It can make it very hard to manage,
and in one code base yesterday, we found that strict was somehow being
disabled as a side-effect of similar behavior. This is largely because
those modules are messing with pragmata, changing Perl's compile or run
time behavior, and sometimes those step on each other.

I can think of different ways of dealing with this, but they all seem bad.
My first thought was something like this:

use feature 'signatures';
never warnings 'experimental::signatures'; # lexically scoped, of course
use Moose;
sub foo($bar) { ... }

The above would not generate a warning even though Moose reloads them.
However, you'd still want a way to override never in the current scope. It
would imply a corresponding always keyword: always strict;.

I don't know if this is possible, if it could be generalized, or even if
it's a good idea (I suspect it's not).

Other approaches for dealing with this problem are welcome.

Best,
Ovid
Re: warnings due to module loading order [ In reply to ]
On Thu, 19 Oct 2023 09:14:12 +0200, Ovid <curtis.poe@gmail.com> wrote:

> use feature 'signatures';
> never warnings 'experimental::signatures'; # lexically scoped, of course
> use Moose;
> sub foo($bar) { ... }
>
> The above would not generate a warning even though Moose reloads them. However, you'd still want a way to >override never in the current scope. It would imply a corresponding always keyword: always strict;.
>
> I don't know if this is possible, if it could be generalized, or even if it's a good idea (I suspect it's not).
>
> Other approaches for dealing with this problem are welcome.

I've run into the same issue before and had to do a fix commit for our codebase that touched hundreds of files because moose was overwriting our pragma settings.

In general i'm totally on board with something like this. I wouldn't know how to implement this however, and only have one thought beyond the agreement:

Possibly it could be a simple option to warnings.pm itself, in a form familiar from CSS:

no warnings qw' experimental::signatures !important ';

--
With regards,
Christian Walde
Re: warnings due to module loading order [ In reply to ]
I see overlap with previous "scream when Module is not directly loaded by
current context"

Implementation wise, that sounds to me like tri-state value - accept what
Moose provides only if setting (positive or negative) is not available yet.

... and now idea how to treat warnings as "independent symbols" came and
doesn't want go away

Brano
Re: warnings due to module loading order [ In reply to ]
On 19 Oct 2023, at 08:14, Ovid <curtis.poe@gmail.com> wrote:
[…]
> For larger code bases, merely sorting a list of modules you've imported could cause strange warnings to appear. It can make it very hard to manage, and in one code base yesterday, we found that strict was somehow being disabled as a side-effect of similar behavior. This is largely because those modules are messing with pragmata, changing Perl's compile or run time behavior, and sometimes those step on each other.

This annoyed me a while ago and I wrote warnings::everywhere so I could say e.g.

no warnings::anywhere ‘experimental::signatures'
use Moose;

but I think in practice we decided in our codebase that we should just accept that things like Dancer and Moose just were pragma-like imports, and our code should say

use Moose;
use Dancer;
no warnings ‘experimental::signatures’;
# import other pragmata here

and then proceed to other imports.

From a language perspective I’d be interested in e.g. (bad name alert)

use strict;
use warnings;
use experimental "signatures";
freeze_warnings();
use Moose;
unfreeze_warnings();

which would stop Moose (or whatever else was imported while freeze_warnings was in place) from messing with my warnings.

Sam
--
Website: http://www.illuminated.co.uk/
Re: warnings due to module loading order [ In reply to ]
A lot of this sounds like a conflation of two things:

* `use experimental` really does `no warnings` which turns off things

* `use Moose` is rude and fiddles with ambient pragmata

Not much that perl core can do about this latter point, except to
really encourage module authors in general to please not do that.

However, the first point can likely be improved upon.

In any of my personal modules that produce experimental-like warnings,
I have a positive-sense lexical hint that quiets them. Perhaps we could
do similar in perl core, where now

use experimental ...

in fact sets one of those "this experiment has been opted into" bits,
thus quieting the warning in a way that isn't stomped on by
`use warnings`.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: warnings due to module loading order [ In reply to ]
On Thu, 19 Oct 2023 13:04:43 +0200, Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> wrote:

> * `use Moose` is rude and fiddles with ambient pragmata
>
> Not much that perl core can do about this latter point, except to
> really encourage module authors in general to please not do that.

A further issue is that it's not just Moose.pm

Almost every module in the moose ecosystem does this, and a bunch of others as well.

--
With regards,
Christian Walde
Re: warnings due to module loading order [ In reply to ]
On 19.10.23 09:14, Ovid wrote:
>
> I can think of different ways of dealing with this, but they all seem
> bad. My first thought was something like this:
>
>     use feature 'signatures';
>     never warnings 'experimental::signatures'; # lexically scoped, of
> course
>     use Moose;
>     sub foo($bar) { ... }
>
> The above would not generate a warning even though Moose reloads them.
> However, you'd still want a way to override never in the current scope.
> It would imply a corresponding always keyword: always strict;.
>

I found myself thinking:

use experimental 'signatures';
use Moose qw(:no-pragma);

which then turned into:

use Moose::NoPragma;

which then turned into:

{ use Moose; }

The problem with this approach, of course, is that you still need to
special-case Moose (and enable strict/warnings manually if you don't
have a sufficiently high 'use VERSION' declaration.)
Re: warnings due to module loading order [ In reply to ]
On 2023-10-19 09:14, Ovid wrote:
> Hi all,
>
> In larger code bases, we keep getting hit with behavior like this:
>
>     $ perl -E 'use Moose; use experimental "signatures"; sub foo($bar)
> {$bar + 41}; say foo(1)'
>     42
>     $ perl -E 'use experimental "signatures"; use Moose; sub foo($bar)
> {$bar + 41}; say foo(1)'
>     The signatures feature is experimental at -e line 1.
>     42
>
> In the second example, we get the warning because Moose reloads
> warnings. For modules which explicitly disable warnings, it's
> because we /want /to explicitly disable those warnings
> (experimental.pm <http://experimental.pm> explicitly unimports related
> warnings).
>
> For larger code bases, merely sorting a list of modules you've
> imported could cause strange warnings to appear. It can make it very
> hard to manage, and in one code base yesterday, we found that strict
> was somehow being disabled as a side-effect of similar behavior. This
> is largely because those modules are messing with pragmata,
> changing Perl's compile or run time behavior, and sometimes those step
> on each other.
>
> I can think of different ways of dealing with this, but they all seem
> bad. My first thought was something like this:
>
>     use feature 'signatures';
>     never warnings 'experimental::signatures'; # lexically scoped, of
> course
>     use Moose;
>     sub foo($bar) { ... }
>
> The above would not generate a warning even though Moose reloads them.
> However, you'd still want a way to override never in the current
> scope. It would imply a corresponding always keyword: always strict;.
>
> I don't know if this is possible, if it could be generalized, or even
> if it's a good idea (I suspect it's not).
>
> Other approaches for dealing with this problem are welcome.
>

I'm mainly brainstorming, didn't think it through much yet:

As part of the solution it might be needed to make warnings call some
FIXUP sub, if it exists, at some point(s).
Feels dirty, but there are multiple scenarios to counter.

Then als give warnings an API for such, so modules can evolve to do
things cleanly.

-- Ruud
Re: warnings due to module loading order [ In reply to ]
On Thu, 19 Oct 2023 14:19:44 +0200
Lukas Mai <lukasmai.403+p5p@gmail.com> wrote:

> which then turned into:
>
> { use Moose; }

Yeah that's quite reasonable.

> The problem with this approach, of course, is that you still need to
> special-case Moose (and enable strict/warnings manually if you don't
> have a sufficiently high 'use VERSION' declaration.)

Mhmm. Well that's why everyone should be doing `use v5.36`. ;)

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: warnings due to module loading order [ In reply to ]
Has anybody ever thought of reaching out to the Moose people to change it's
behavior to stop doing that by default? I could see a world where use
Moose; Issues a warning that moose pragmas are deprecated and will
eventually be removed, and starts to no longer set pragma explicitly if a
sufficiently recent feature bundle is detected.

Moose has always prioritized correctness over everything else, and this is
a case where it's (no longer) behaving correctly.

-Chris

On Thu, Oct 19, 2023 at 11:53?AM Paul "LeoNerd" Evans <
leonerd@leonerd.org.uk> wrote:

> On Thu, 19 Oct 2023 14:19:44 +0200
> Lukas Mai <lukasmai.403+p5p@gmail.com> wrote:
>
> > which then turned into:
> >
> > { use Moose; }
>
> Yeah that's quite reasonable.
>
> > The problem with this approach, of course, is that you still need to
> > special-case Moose (and enable strict/warnings manually if you don't
> > have a sufficiently high 'use VERSION' declaration.)
>
> Mhmm. Well that's why everyone should be doing `use v5.36`. ;)
>
> --
> Paul "LeoNerd" Evans
>
> leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
> http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
>
Re: warnings due to module loading order [ In reply to ]
On Thu, Oct 19, 2023 at 9:15?AM Ovid <curtis.poe@gmail.com> wrote:

> Hi all,
>
> In larger code bases, we keep getting hit with behavior like this:
>
> $ perl -E 'use Moose; use experimental "signatures"; sub foo($bar)
> {$bar + 41}; say foo(1)'
> 42
> $ perl -E 'use experimental "signatures"; use Moose; sub foo($bar)
> {$bar + 41}; say foo(1)'
> The signatures feature is experimental at -e line 1.
> 42
>
> In the second example, we get the warning because Moose reloads warnings.
> For modules which explicitly disable warnings, it's because we *want *to
> explicitly disable those warnings (experimental.pm explicitly unimports
> related warnings).
>

There really ought to be a «use warnings ':all_but_defaults' that doesn't
touch experimental and deprecation warnings in either direction for modules
such as Moose.


> For larger code bases, merely sorting a list of modules you've imported
> could cause strange warnings to appear. It can make it very hard to manage,
> and in one code base yesterday, we found that strict was somehow being
> disabled as a side-effect of similar behavior.
>

That sounds like that pragma is just plain broken

Leon
Re: warnings due to module loading order [ In reply to ]
On Thu, Oct 19, 2023 at 6:40?PM Chris Prather <chris@prather.org> wrote:

> Has anybody ever thought of reaching out to the Moose people to change
> it's behavior to stop doing that by default? I could see a world where use
> Moose; Issues a warning that moose pragmas are deprecated and will
> eventually be removed, and starts to no longer set pragma explicitly if a
> sufficiently recent feature bundle is detected.
>
> Moose has always prioritized correctness over everything else, and this is
> a case where it's (no longer) behaving correctly.
>
>> <https://www.tindie.com/stores/leonerd/>
>
>
Moose is extremely concerned with backwards-compatibility and discourages
new features. Their contribution page (
https://metacpan.org/dist/Moose/contribute) says any new feature should
start as a MooseX module. If that's not possible, then you can reach out to
them to discuss it. I also have code out there which does the same thing
and I am not sure if it was wrong, but we effectively have things which
should have been the default long ago (strict and warnings) which aren't,
so we're in an odd place right now.

Best,
Ovid
Re: warnings due to module loading order [ In reply to ]
I think a sensible approach is to only enable strict and warnings if the
bits haven't been fiddled with from their default state.

This would not be backward-compatible for Moose in lots of edge cases,
but would preserve the advertised pragma behavior in most ordinary cases.

-Mike

On 10/19/23 12:40, Chris Prather wrote:
> Has anybody ever thought of reaching out to the Moose people to change
> it's behavior to stop doing that by default? I could see a world where
> use Moose; Issues a warning that moose pragmas are deprecated and will
> eventually be removed, and starts to no longer set pragma explicitly
> if a sufficiently recent feature bundle is detected.
>
> Moose has always prioritized correctness over everything else, and
> this is a case where it's (no longer) behaving correctly.
>
> -Chris
>
> On Thu, Oct 19, 2023 at 11:53?AM Paul "LeoNerd" Evans
> <leonerd@leonerd.org.uk> wrote:
>
> On Thu, 19 Oct 2023 14:19:44 +0200
> Lukas Mai <lukasmai.403+p5p@gmail.com
> <mailto:lukasmai.403%2Bp5p@gmail.com>> wrote:
>
> > which then turned into:
> >
> >      { use Moose; }
>
> Yeah that's quite reasonable.
>
> > The problem with this approach, of course, is that you still
> need to
> > special-case Moose (and enable strict/warnings manually if you
> don't
> > have a sufficiently high 'use VERSION' declaration.)
>
> Mhmm. Well that's why everyone should be doing `use v5.36`. ;)
>
> --
> Paul "LeoNerd" Evans
>
> leonerd@leonerd.org.uk     | https://metacpan.org/author/PEVANS
> http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
>
Re: warnings due to module loading order [ In reply to ]
On Sun, Oct 22, 2023 at 12:56?PM Michael Conrad <mike@nrdvana.net> wrote:
>
> I think a sensible approach is to only enable strict and warnings if the bits haven't been fiddled with from their default state.
>
> This would not be backward-compatible for Moose in lots of edge cases, but would preserve the advertised pragma behavior in most ordinary cases.

This adds the same type of order dependent confusion, just in the
other direction. It would mean that doing:

use experimental qw(signatures);
use Moose;

would not enable any warnings aside from those enabled by default. I
don't think that is a viable solution.

I wouldn't mind if Moose and Moo v3 did not enable strict and warnings
if they were used with a version >= 3 specified.

Another possible option would be for Moose and Moo (or similar
modules) to only try to enable the warnings that are not enabled by
default. This would normally result in all warnings being enabled, but
if any default warnings (like experimental warnings) had been
disabled, they wouldn't be re-enabled. This does still add some
strange behavior, where some warnings touched before using Moose would
have an impact and others would not. But it is at least more
predictable and would work for the most common case being discussed,
of disabling an experimental warning.