Tobiwan has asked for the wisdom of the Perl Monks concerning the following question:

Hi there, I've tried to get the information if my package used the warnings and strict pragma. The $^W and $^H variables are to magical, so they contain nothing. The ${^WARNING_BITS} even contain nothing. How can I get this information?
package Test; use warnings; use strict; sub bintodec { unpack("N", pack("B32", substr("0" x 32 . shift, -32))); } print "\nW: " . bintodec($^W); print "\nW_BITS: " . bintodec(${^WARNING_BITS}); print "\nH: " . bintodec(${^H});
If you remove the "use warnings" or "use strict" there is no change in output. Even if you say "no strict" or "no warnings".

Replies are listed 'Best First'.
Re: Find out, if "use warnings(all)" and "use strict(all)" are used
by shmem (Chancellor) on Apr 23, 2007 at 12:33 UTC
    for (qw(strict warnings)) { print "using $_\n" if $INC{"$_.pm"}; }

    That should do.

    To check if a specific warning is enabled, use warnings::enabled(category). See warnings. Consult perllexwarn for the available categories.

    The variable $^H is, according to perlvar, strictly for internal use. I guess it is write-only.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Find out, if "use warnings(all)" and "use strict(all)" are used
by rhesa (Vicar) on Apr 23, 2007 at 13:23 UTC
    Because use strict; and no strict 'refs'; are compile-time directives, you can't easily check for them during run-time. One way to find out if a certain scope has strict bits set, is to save $^H to a variable in a BEGIN block:
    #!/usr/bin/perl STRICT: { use strict; my $strict; BEGIN { $strict = $^H } strict_bits($strict); } NO_STRICT: { no strict; my $strict; BEGIN { $strict = $^H } strict_bits($strict); } sub strict_bits { my $h = shift; # from strict.pm my %bitmask = ( refs => 0x00000002, subs => 0x00000200, vars => 0x00000400 ); printf "\$^H = $h = %b\n", $h; print "strict '$_' is ", (($h & $bitmask{$_}) ? 'on' : 'off' ), "\n" for sort keys %bitmask; } __END__ $^H = 1794 = 11100000010 strict 'refs' is on strict 'subs' is on strict 'vars' is on $^H = 256 = 100000000 strict 'refs' is off strict 'subs' is off strict 'vars' is off
    The same idea works for warnings and ${^WARN_BITS}.

    My naive understanding is that $^H is attached to a scope (like the "STRICT" block above) during compile-time, in order to make the strict settings work. Apparently you can't access that setting directly during run-time.

    Someone with greater B::Deparse-fu will no doubt be able to explain this in more depth.

Re: Find out, if "use warnings(all)" and "use strict(all)" are used
by cdarke (Prior) on Apr 23, 2007 at 12:43 UTC
    If you are using warnings and strict as in your script you can check %INC (perlvar) for those modules, for example:
    if (exists($INC{'strict.pm'})) { print "strict\n" } if (exists($INC{'warnings.pm'})) { print "warnings\n" }
    Warnings can also be switched on with the -w command line option, and this is what $^W is used for. In this case just test for truth. So for warnings you may need:
    if (exists($INC{'warnings.pm'}) || $^W) {print "Warnings\n"};
Re: Find out, if "use warnings(all)" and "use strict(all)" are used
by Krambambuli (Curate) on Apr 23, 2007 at 14:39 UTC
    It's important I believe to cut a very clear line between what happens at compile time and what happens at runtime. Once those very distinctive steps are put apart and understood, it might be that your question changes.

    Playing a bit with BEGIN{} might help in getting things apart;
    use strict; my $all; use warnings 'all'; BEGIN { $all = unpack( 'b*', ${^WARNING_BITS} ); } print "ALL : $all\n"; my $none; no warnings 'all'; BEGIN { $none = unpack( 'b*', ${^WARNING_BITS} ); } print "NONE: $none\n"; my $void; use warnings 'void'; BEGIN { $void = unpack( 'b*', ${^WARNING_BITS} ); } print "VOID: $void\n";
    This will display at runtime the values in use at compile time _at that specific point in the program_.

    Note that to unpack ${^WARNING_BITS} - a 96 bits value - your bintodec sub won't work.

    You might be interested in having a look on the warnings.pm source code - it's not really scary and definitely worth a look - and maybe check the 'Pragmatic modules' in perlmodlib.

    Hope that helps.
      Thanks, that was a good hint. I tried to read the warning and strict bits from other packages, so I've to find a way to do it without explicit BEGIN blocks. The following thing works, but why ?!?
      package Aa; use warnings; #no warnings 'void'; use strict; #no strict 'refs'; package Bb; #>> when you uncomment this, it wont work!! #use strict; #use warnings; #<< my $strict = eval('package Aa;my $h;BEGIN { $h = ${^H} };return $h;'); printf "use strict " . ($strict == 1794 ? 'yes' : 'no') . "\n"; my $warn = eval('package Aa;my $w;BEGIN { $w = ${^WARNING_BITS} };retu +rn $w;'); printf "use warnings " . (unpack('b*', warnings::bits('all')) == unpac +k('b*', $warn) ? 'yes' : 'no') . "\n";
      This prints:
      use strict = yes
      use warnings = yes
      
      till you use all-warnings ans all-stricts. Conclusion: it works fine and do what I want.

      And by the way: in last few weeks I've see a lot of little perl wonders like this. I think, there must be a perl-good. Now I'm a believer :D