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.