Date: 29th July 1998 This patch adds lexical warnings to Perl. It should apply over 5.005_50 NOTE: This is a prototype. Do not assume that lexical warnings will necessarily be anything like this implementation. Changes ======= Date: 8th April 1998 * patch now applies cleanly over 5.004_64 * added the -X switch (the inverse "lint" command) Date: 26th Feb 1997 * By popular demand, the warnings bitmask can now be of arbitrary length. The code uses an SV* to store the bitmask. * Rationalised the warning categories a bit. This area still needs a lot of work. * Added -W switch (the "lint" command). * Added an experimental feature to allow warnings to be excalated to fatal errors. The "use warning" pragma ======================== The "use warning" pragma is intended to replace both the use of the command line flag "-w" and its equivalent variable $^W with a pragma that works like the existing "strict" pragma. This means that the scope of the pragma is limited to the enclosing block. It also means that that a pragma setting will not leak across files (via use/require/do). This will allow authors to define the degree of warning checks that will be applied to their module. By default warnings are disabled. All warnings are enabled in a block by either of these: use warning ; use warning 'all' ; Similarly all warnings are disabled in a block by either of these: no warning ; no warning 'all' ; A hierarchy of "categories" have been defined to allow groups of warnings to be enabled/disabled in isolation. The current hierarchy is: all - +--- unsafe -------+--- taint | | | +--- substr | | | +--- signal | | | +--- closure | | | +--- untie | +--- io ---------+--- pipe | | | +--- unopened | | | +--- closed | | | +--- newline | | | +--- exec | +--- syntax ----+--- ambiguous | | | +--- semicolon | | | +--- precedence | | | +--- reserved | | | +--- octal | | | +--- parenthesis | | | +--- deprecated | |--- uninitialized | +--- void | +--- recursion | +--- redefine | +--- numeric | +--- once | +--- misc This hierarchy is very tentative. Feedback is needed. Just like the "strict" pragma any of these categories can be combined use warning qw(void redefine) ; no warning qw(io syntax untie) ; The "lint" flag, -W =================== If the -W flag is used on the command line, it will enable all warnings throughout the program regardless of whether warnings were disabled locally using "no warning" or $^W =0. This includes any file that gets included during compilation via use/require. The inverse "lint" flag, -X =========================== Does exactly the same as the -W flag, except it disables all warnings. Backward Compatability ====================== How Lexical Warnings interact with -w/$^W 1. The -w flag just sets the global $^W variable as in 5.004 This means that any legacy code that currently relies on manipulating $^W to control warning behaviour will still work. 2. Apart from now being a boolean, the $^W variable operates in exactly the same horrible uncontrolled global way as in 5.004, except... 3. If a piece of code is under the control of a lexical warning pragma, the $^W variable will be ignored. The combined effect of 2 & 3 is that it will will allow new code which will use the lexical warning pragma to control old $^W-type code (using a local $^W=0) if it really wants to, but not vice-versa. 4. The only way to override a lexical warnings setting is with the new -W or -X command line flags. Fatal Warnings ============== This feature is very experimental. The presence of the word "FATAL" in the category list will escalate any warnings from the category specified that are detected in the lexical scope into fatal errors. In the code below, there are 3 places where a deprecated warning will be detected, the middle one will produce a fatal error. use warning ; $a = 1 if $a EQ $b ; { use warning qw(FATAL deprecated) ; $a = 1 if $a EQ $b ; } $a = 1 if $a EQ $b ; TODO ==== test harness for -X (assuming it is a permanent fixture). win32, os2 & vms all have warnings. These need to be included. Unresolved Issues ================= The pragma name? A few possibilities: warning warnings warn Hierarchy of Warnings The current patch has a fairly arbitrary hierarchy. Ideas for a useful hierarchy would be most welcome. A command line option to turn off all warnings? -X or -q, perhaps. Current mandatory warnings. May be useful to bring them under the control of this pragma. Severity Do we want/need a severity classification? pedantic high/strict/precise medium/default low/common Versions This is a thorhy issue. Say someone writes a script using Perl 5.004 and places this at the top: use warning ; Time passes and 5.005 comes out. It has added a few extra warnings. The script prints warning messages. A possibility is to allow the warnings that are checked to be limited to those available in a given version of Perl. A possible syntax could be: use warning 5.004 ; or use warning 5.004 qw(void uninitialized) ; Do we really need this amount of control? Documentation There isn't any yet. perl5db.pl The debugger saves and restores $^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 lexiacal warnings patch, but there were design decisions made in diagnostics to work around the limitations of $^W. Now that those limitations are gone, the module should be revisited.