The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

warnings::DynamicScope - Provides warning categories in dynamic scope.

SYNOPSIS

  require warnings::DynamicScope;

  package GrandMother;
  use warnings::register;
  
  sub deliver {
      my $self;
      $^W{GrandMother} && warn "You have warned by grandma.";
      bless \$self;
  }
  
  package Mother;
  use base "GrandMother";
  use warnings::register;
  
  sub deliver {
      $^W{Mother} && warn "You have warned by mom.";
      $_[0]->SUPER::deliver();
  }
  
  package main;
  
  $^W = 1;
  $^W{GrandMother} = 0;
  
  my $me = Mother->deliver(); # => You have warned by mom.
  

DESCRIPTION

This module provides warning categories in dynamic scope through the special variable "%^W".

VARIABLE

This modules brings a new special variable called "%^W". Yes, it is very similar to special variable "$^W" in appearance, but these are different things.

But you can use it like special variable "$^W":

 require warnings::DynamicScope;

 package MyPkg;
 use warnings::register;
 
 sub my_func {
     if ($^W{MyPkg}) {
         print "Don't do it!!\n";
     } else {
         print "That's fine\n";
     }
 }
 
 package main;
 $^W = 1;

 {
     local $^W{MyPkg} = 0;
     MyPkg::my_func();
 }
 MyPkg::my_func();

This code prints:

 That's fine.
 Don't do it!!

That's all.

DEAD BIT

Each warning category has extra property called "Dead Bit".

The Dead Bit will be set if the string "FATAL" is passed to the variable "%^W" as it's value for a key, and then 2 will be returned as the value for a key.

You can use it as blow:

 require warnings::DynamicScope;
 
 package MyPkg;
 use warnings::register;
 use Carp qw(carp croak);
 
 sub func1 {
     if ($^W{MyPkg} == 2) {
        # Dead Bits is on.
         croak("Fatal Error!\n");
 
     } elsif ($^W{MyPkg}) {
         carp("Non Fatal Error!\n");
     }
 }
 
 package main;
 
 $^W{MyPkg} = 'FATAL';    # Set Dead Bit.
 eval { MyPkg::func1() };
 print $@;                # => Fatal Error!
 
 $^W{MyPkg} = 1;          # Set warning bit of category "MyPkg".
 MyPkg::func1();          # => Non Fatal Error!
 
 $^W{MyPkg} = 0;          # Clear all of the bits.
 MyPkg::func1();          # <nothing happens>
BEGIN BLOCK

If the variable "%^W" was used in "BEGIN" block, it behaves as compiler directive.

So, if you write like:

 BEGIN {
   $^W{uninitialized} = 0;
 }

it brings same result of:

 no warnings 'uninitialized';
NOTE

All of categories predefined in Perl does not understand warning bits in dynamic scope, so they won't work unless it was set by warnings pragma.

$^W AND %^W

The values of variables $^W and %^W are linked internally by the keyword 'all':

 $^W = 1;       # is equal to $^W{all} = 1;
 $^W = 0;       # is equal to $^W{all} = 0;
 
 $^W{all} = 1;  # is equal to $^W = 1;
 $^W{all} = 0;  # is equal to $^W = 0;

OBJECTIVE

The reason why I decided to write a new module which provides capability similar to warnings pragma is that I found the limitation of "warnings::enabled" and "warnings::warnif" function.

While I'm writing my module, I noticed that the code like below will not work as I intended:

  use warnings;
  
  package GrandMother;
  use warnings::register;
  
  sub deliver {
      my $self;
      warnings::warnif("GrandMother", "You have warned by grandma.");
      bless \$self;
  }
  
  package Mother;
  use base "GrandMother";
  use warnings::register;
  
  sub deliver {
      warnings::warnif("Mother", "You have warned by mom.");
      $_[0]->SUPER::deliver();
  }
  
  package main;
  no warnings "GrandMother";
  no warnings "Mother";
  
  my $me = Mother->deliver(); # => You have warned by grandma.

In this code, I intended to inhibit warning messages from each class "GrandMother" and "Mother".

But, if I run this code, warning in "GrandMother" class will be emitted. So that means the information by pragma 'no warnings "GrandMother"' would not be passed to "GrandMother" class properly.

I thought this comes from nature of these function that these functions uses warnings information in static scope. (They gets static scope information from stack of caller function.)

So, I started write this module to make warning categories work with dynamic scope.

TIPS

If you don't like Perl's variable abbreviation like $^W, try:

 use English qw(WARNING);

EXPORT

None by default.

SEE ALSO

perllexwarn

Documentation about lexical warnings.

warnings

You can use warning categories based on lexical scope, by using functions "warnings::enabled", etc.

warnings::register

You can make your warning category with "warnings::register" pragma.

AUTHOR

Keitaro Miyazaki, <kmiyazaki@cpan.org<gt>

COPYRIGHT AND LICENSE

Copyright (C) 2005 by Keitaro Miyazaki

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.6 or, at your option, any later version of Perl 5 you may have available.