home *** CD-ROM | disk | FTP | other *** search
- =head1 NAME
-
- perllexwarn - Perl Lexical Warnings
-
- =head1 DESCRIPTION
-
- The C<use warnings> pragma is a replacement for both the command line
- flag B<-w> and the equivalent Perl variable, C<$^W>.
-
- The pragma works just like the existing "strict" pragma.
- This means that the scope of the warning pragma is limited to the
- enclosing block. It also means that the pragma setting will not
- leak across files (via C<use>, C<require> or C<do>). This allows
- authors to independently define the degree of warning checks that will
- be applied to their module.
-
- By default, optional warnings are disabled, so any legacy code that
- doesn't attempt to control the warnings will work unchanged.
-
- All warnings are enabled in a block by either of these:
-
- use warnings ;
- use warnings 'all' ;
-
- Similarly all warnings are disabled in a block by either of these:
-
- no warnings ;
- no warnings 'all' ;
-
- For example, consider the code below:
-
- use warnings ;
- my @a ;
- {
- no warnings ;
- my $b = @a[0] ;
- }
- my $c = @a[0];
-
- The code in the enclosing block has warnings enabled, but the inner
- block has them disabled. In this case that means the assignment to the
- scalar C<$c> will trip the C<"Scalar value @a[0] better written as $a[0]">
- warning, but the assignment to the scalar C<$b> will not.
-
- =head2 Default Warnings and Optional Warnings
-
- Before the introduction of lexical warnings, Perl had two classes of
- warnings: mandatory and optional.
-
- As its name suggests, if your code tripped a mandatory warning, you
- would get a warning whether you wanted it or not.
- For example, the code below would always produce an C<"isn't numeric">
- warning about the "2:".
-
- my $a = "2:" + 3;
-
- With the introduction of lexical warnings, mandatory warnings now become
- I<default> warnings. The difference is that although the previously
- mandatory warnings are still enabled by default, they can then be
- subsequently enabled or disabled with the lexical warning pragma. For
- example, in the code below, an C<"isn't numeric"> warning will only
- be reported for the C<$a> variable.
-
- my $a = "2:" + 3;
- no warnings ;
- my $b = "2:" + 3;
-
- Note that neither the B<-w> flag or the C<$^W> can be used to
- disable/enable default warnings. They are still mandatory in this case.
-
- =head2 What's wrong with B<-w> and C<$^W>
-
- Although very useful, the big problem with using B<-w> on the command
- line to enable warnings is that it is all or nothing. Take the typical
- scenario when you are writing a Perl program. Parts of the code you
- will write yourself, but it's very likely that you will make use of
- pre-written Perl modules. If you use the B<-w> flag in this case, you
- end up enabling warnings in pieces of code that you haven't written.
-
- Similarly, using C<$^W> to either disable or enable blocks of code is
- fundamentally flawed. For a start, say you want to disable warnings in
- a block of code. You might expect this to be enough to do the trick:
-
- {
- local ($^W) = 0 ;
- my $a =+ 2 ;
- my $b ; chop $b ;
- }
-
- When this code is run with the B<-w> flag, a warning will be produced
- for the C<$a> line -- C<"Reversed += operator">.
-
- The problem is that Perl has both compile-time and run-time warnings. To
- disable compile-time warnings you need to rewrite the code like this:
-
- {
- BEGIN { $^W = 0 }
- my $a =+ 2 ;
- my $b ; chop $b ;
- }
-
- The other big problem with C<$^W> is the way you can inadvertently
- change the warning setting in unexpected places in your code. For example,
- when the code below is run (without the B<-w> flag), the second call
- to C<doit> will trip a C<"Use of uninitialized value"> warning, whereas
- the first will not.
-
- sub doit
- {
- my $b ; chop $b ;
- }
-
- doit() ;
-
- {
- local ($^W) = 1 ;
- doit()
- }
-
- This is a side-effect of C<$^W> being dynamically scoped.
-
- Lexical warnings get around these limitations by allowing finer control
- over where warnings can or can't be tripped.
-
- =head2 Controlling Warnings from the Command Line
-
- There are three Command Line flags that can be used to control when
- warnings are (or aren't) produced:
-
- =over 5
-
- =item B<-w>
-
- This is the existing flag. If the lexical warnings pragma is B<not>
- used in any of you code, or any of the modules that you use, this flag
- will enable warnings everywhere. See L<Backward Compatibility> for
- details of how this flag interacts with lexical warnings.
-
- =item B<-W>
-
- If the B<-W> flag is used on the command line, it will enable all warnings
- throughout the program regardless of whether warnings were disabled
- locally using C<no warnings> or C<$^W =0>. This includes all files that get
- included via C<use>, C<require> or C<do>.
- Think of it as the Perl equivalent of the "lint" command.
-
- =item B<-X>
-
- Does the exact opposite to the B<-W> flag, i.e. it disables all warnings.
-
- =back
-
- =head2 Backward Compatibility
-
- If you are used with working with a version of Perl prior to the
- introduction of lexically scoped warnings, or have code that uses both
- lexical warnings and C<$^W>, this section will describe how they interact.
-
- How Lexical Warnings interact with B<-w>/C<$^W>:
-
- =over 5
-
- =item 1.
-
- If none of the three command line flags (B<-w>, B<-W> or B<-X>) that
- control warnings is used and neither C<$^W> or the C<warnings> pragma
- are used, then default warnings will be enabled and optional warnings
- disabled.
- This means that legacy code that doesn't attempt to control the warnings
- will work unchanged.
-
- =item 2.
-
- The B<-w> flag just sets the global C<$^W> variable as in 5.005 -- this
- means that any legacy code that currently relies on manipulating C<$^W>
- to control warning behavior will still work as is.
-
- =item 3.
-
- Apart from now being a boolean, the C<$^W> variable operates in exactly
- the same horrible uncontrolled global way, except that it cannot
- disable/enable default warnings.
-
- =item 4.
-
- If a piece of code is under the control of the C<warnings> pragma,
- both the C<$^W> variable and the B<-w> flag will be ignored for the
- scope of the lexical warning.
-
- =item 5.
-
- The only way to override a lexical warnings setting is with the B<-W>
- or B<-X> command line flags.
-
- =back
-
- The combined effect of 3 & 4 is that it will allow code which uses
- the C<warnings> pragma to control the warning behavior of $^W-type
- code (using a C<local $^W=0>) if it really wants to, but not vice-versa.
-
- =head2 Category Hierarchy
-
- A hierarchy of "categories" have been defined to allow groups of warnings
- to be enabled/disabled in isolation.
-
- The current hierarchy is:
-
- all -+
- |
- +- closure
- |
- +- deprecated
- |
- +- exiting
- |
- +- glob
- |
- +- io -----------+
- | |
- | +- closed
- | |
- | +- exec
- | |
- | +- layer
- | |
- | +- newline
- | |
- | +- pipe
- | |
- | +- unopened
- |
- +- misc
- |
- +- numeric
- |
- +- once
- |
- +- overflow
- |
- +- pack
- |
- +- portable
- |
- +- recursion
- |
- +- redefine
- |
- +- regexp
- |
- +- severe -------+
- | |
- | +- debugging
- | |
- | +- inplace
- | |
- | +- internal
- | |
- | +- malloc
- |
- +- signal
- |
- +- substr
- |
- +- syntax -------+
- | |
- | +- ambiguous
- | |
- | +- bareword
- | |
- | +- digit
- | |
- | +- parenthesis
- | |
- | +- precedence
- | |
- | +- printf
- | |
- | +- prototype
- | |
- | +- qw
- | |
- | +- reserved
- | |
- | +- semicolon
- |
- +- taint
- |
- +- threads
- |
- +- uninitialized
- |
- +- unpack
- |
- +- untie
- |
- +- utf8
- |
- +- void
- |
- +- y2k
-
- Just like the "strict" pragma any of these categories can be combined
-
- use warnings qw(void redefine) ;
- no warnings qw(io syntax untie) ;
-
- Also like the "strict" pragma, if there is more than one instance of the
- C<warnings> pragma in a given scope the cumulative effect is additive.
-
- use warnings qw(void) ; # only "void" warnings enabled
- ...
- use warnings qw(io) ; # only "void" & "io" warnings enabled
- ...
- no warnings qw(void) ; # only "io" warnings enabled
-
- To determine which category a specific warning has been assigned to see
- L<perldiag>.
-
- Note: In Perl 5.6.1, the lexical warnings category "deprecated" was a
- sub-category of the "syntax" category. It is now a top-level category
- in its own right.
-
-
- =head2 Fatal Warnings
-
- The presence of the word "FATAL" in the category list will escalate any
- warnings detected from the categories specified in the lexical scope
- into fatal errors. In the code below, the use of C<time>, C<length>
- and C<join> can all produce a C<"Useless use of xxx in void context">
- warning.
-
- use warnings ;
-
- time ;
-
- {
- use warnings FATAL => qw(void) ;
- length "abc" ;
- }
-
- join "", 1,2,3 ;
-
- print "done\n" ;
-
- When run it produces this output
-
- Useless use of time in void context at fatal line 3.
- Useless use of length in void context at fatal line 7.
-
- The scope where C<length> is used has escalated the C<void> warnings
- category into a fatal error, so the program terminates immediately it
- encounters the warning.
-
- To explicitly turn off a "FATAL" warning you just disable the warning
- it is associated with. So, for example, to disable the "void" warning
- in the example above, either of these will do the trick:
-
- no warnings qw(void);
- no warnings FATAL => qw(void);
-
- If you want to downgrade a warning that has been escalated into a fatal
- error back to a normal warning, you can use the "NONFATAL" keyword. For
- example, the code below will promote all warnings into fatal errors,
- except for those in the "syntax" category.
-
- use warnings FATAL => 'all', NONFATAL => 'syntax';
-
- =head2 Reporting Warnings from a Module
-
- The C<warnings> pragma provides a number of functions that are useful for
- module authors. These are used when you want to report a module-specific
- warning to a calling module has enabled warnings via the C<warnings>
- pragma.
-
- Consider the module C<MyMod::Abc> below.
-
- package MyMod::Abc;
-
- use warnings::register;
-
- sub open {
- my $path = shift ;
- if ($path !~ m#^/#) {
- warnings::warn("changing relative path to /tmp/")
- if warnings::enabled();
- $path = "/tmp/$path" ;
- }
- }
-
- 1 ;
-
- The call to C<warnings::register> will create a new warnings category
- called "MyMod::abc", i.e. the new category name matches the current
- package name. The C<open> function in the module will display a warning
- message if it gets given a relative path as a parameter. This warnings
- will only be displayed if the code that uses C<MyMod::Abc> has actually
- enabled them with the C<warnings> pragma like below.
-
- use MyMod::Abc;
- use warnings 'MyMod::Abc';
- ...
- abc::open("../fred.txt");
-
- It is also possible to test whether the pre-defined warnings categories are
- set in the calling module with the C<warnings::enabled> function. Consider
- this snippet of code:
-
- package MyMod::Abc;
-
- sub open {
- warnings::warnif("deprecated",
- "open is deprecated, use new instead") ;
- new(@_) ;
- }
-
- sub new
- ...
- 1 ;
-
- The function C<open> has been deprecated, so code has been included to
- display a warning message whenever the calling module has (at least) the
- "deprecated" warnings category enabled. Something like this, say.
-
- use warnings 'deprecated';
- use MyMod::Abc;
- ...
- MyMod::Abc::open($filename) ;
-
- Either the C<warnings::warn> or C<warnings::warnif> function should be
- used to actually display the warnings message. This is because they can
- make use of the feature that allows warnings to be escalated into fatal
- errors. So in this case
-
- use MyMod::Abc;
- use warnings FATAL => 'MyMod::Abc';
- ...
- MyMod::Abc::open('../fred.txt');
-
- the C<warnings::warnif> function will detect this and die after
- displaying the warning message.
-
- The three warnings functions, C<warnings::warn>, C<warnings::warnif>
- and C<warnings::enabled> can optionally take an object reference in place
- of a category name. In this case the functions will use the class name
- of the object as the warnings category.
-
- Consider this example:
-
- package Original ;
-
- no warnings ;
- use warnings::register ;
-
- sub new
- {
- my $class = shift ;
- bless [], $class ;
- }
-
- sub check
- {
- my $self = shift ;
- my $value = shift ;
-
- if ($value % 2 && warnings::enabled($self))
- { warnings::warn($self, "Odd numbers are unsafe") }
- }
-
- sub doit
- {
- my $self = shift ;
- my $value = shift ;
- $self->check($value) ;
- # ...
- }
-
- 1 ;
-
- package Derived ;
-
- use warnings::register ;
- use Original ;
- our @ISA = qw( Original ) ;
- sub new
- {
- my $class = shift ;
- bless [], $class ;
- }
-
-
- 1 ;
-
- The code below makes use of both modules, but it only enables warnings from
- C<Derived>.
-
- use Original ;
- use Derived ;
- use warnings 'Derived';
- my $a = new Original ;
- $a->doit(1) ;
- my $b = new Derived ;
- $a->doit(1) ;
-
- When this code is run only the C<Derived> object, C<$b>, will generate
- a warning.
-
- Odd numbers are unsafe at main.pl line 7
-
- Notice also that the warning is reported at the line where the object is first
- used.
-
- =head1 TODO
-
- perl5db.pl
- The debugger saves and restores C<$^W> at runtime. I haven't checked
- whether the debugger will still work with the lexical warnings
- patch applied.
-
- diagnostics.pm
- I *think* I've got diagnostics to work with the lexical warnings
- patch, but there were design decisions made in diagnostics to work
- around the limitations of C<$^W>. Now that those limitations are gone,
- the module should be revisited.
-
- document calling the warnings::* functions from XS
-
- =head1 SEE ALSO
-
- L<warnings>, L<perldiag>.
-
- =head1 AUTHOR
-
- Paul Marquess
-