warnings::DynamicScope - Provides warning categories in dynamic scope.
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.
This module provides warning categories in dynamic scope through the special variable "%^W".
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.
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>
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';
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.
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;
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.
If you don't like Perl's variable abbreviation like $^W, try:
use English qw(WARNING);
None by default.
Documentation about lexical warnings.
You can use warning categories based on lexical scope, by using functions "warnings::enabled", etc.
You can make your warning category with "warnings::register" pragma.
Keitaro Miyazaki, <kmiyazaki@cpan.org<gt>
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.
To install warnings::DynamicScope, copy and paste the appropriate command in to your terminal.
cpanm
cpanm warnings::DynamicScope
CPAN shell
perl -MCPAN -e shell install warnings::DynamicScope
For more information on module installation, please visit the detailed CPAN module installation guide.