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.