I frequently find myself leaving out 'use warnings' when developing CPAN modules to ensure backward compatibility for Perls prior to 5.6. However, that means that I'm also missing an important safety net that helps save me from myself as I develop.

Here are two ideas I had to work around this -- turning lexical warnings on for Perl 5.6 or better (i.e. where I develop) but not causing problems for older versions of Perl:

Some quick tests seems to indicate that these both work -- at least for my Perl > 5.006.

Does anyone see any potential problems with this approach? If not, I'm probably going to add the latter to my module boilerplate.

-xdg

Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Replies are listed 'Best First'.
Re: Backward compatible lexical warnings
by tilly (Archbishop) on Aug 30, 2006 at 22:16 UTC
    I'd probably code it like this.
    BEGIN { # Keep older versions of Perl from seeing warnings. $INC{"warnings.pm"} = "faked" if $] < 5.006; } ... use warnings;
    That way there is no dependency and nobody will ever have to wonder what the actual scope of your non-standard warnings loading is.
Re: Backward compatible lexical warnings (don't)
by tye (Sage) on Aug 31, 2006 at 06:24 UTC

    My suggestion is that you simply refrain from including use warnings in your module. It is true that I'm not one of the people who justify not caring about backward compatability by disparaging people who don't update Perl for an entire millenium :), but I think you should avoid this more than just because of problems with backward compatability.

    First, it is a good thing® to utilize warnings to help you notice mistakes in your modules. This might lead you to think that you should use warnings in your module. But I accomplish this by using #!/usr/bin/perl -w in my test scripts (and perhaps other scripts that I use when developing the module). It works better because it shows me warnings in the code that is using the module and (most of) the code in other modules that my module uses.

    "But there's no harm in doing use warnings in my module, right?" you ask. Actually, there is harm.

    Before I continue, let me note that I'm only talking about utilizing use warnings to enable the production of warnings by the module's code. There certainly are other reasons to utilize the warnings.pm pragma. And if there are any other beneficial effects of a simple use warnings; in a module, then please let me know.

    I'm a strong believer in enabling warnings during development. But I find that in most production situations, Perl's warnings are better left disabled.

    A warning is only useful if it makes it to a person who can understand it and address the problem that created it. In development, warnings are useful because they are sent directly to the developer. But most production environments don't have a good channel set up for delivering any warnings generated to a developer's attention, much less to the appropriate developer's attention.

    So in most production environments, Perl warnings are mostly useless and can cause problems like confusing your users, obscuring important information in a flood of relative trivia, or even just consuming too many resources.

    So even for non-module code, I use -w during development and drop the -w when deploying to production. But me dropping -w doesn't stop any use warnings-using module from generating warnings.

    So I think a module should only use warnings if its test suite includes cases of passing in undef for every parameter that could reasonably be an empty string or zero (and also does its best to test for other sources of warnings from the module code caused, in part, by what the module user passed in).

    It can often be a reasonable style choice to use undef when any empty string or zero is wanted. So it is a disservice to have a module that generates warnings when such an undef is passed to it (unless -w is in effect).

    - tye        

Re: Backward compatible lexical warnings
by ambrus (Abbot) on Aug 30, 2006 at 20:12 UTC

    The problem with the first approach is that perls older than 5.006002 don't have the if module in core. This doesn't affect the second one of course.

Re: Backward compatible lexical warnings
by Tanktalus (Canon) on Aug 30, 2006 at 20:04 UTC

    To be honest, is there really a need to worry about this? Do you have active users who are not upgrading perl to 5.6 or 5.8, but are upgrading your module?

    You're missing out not just on important safety for yourself as you develop, you're also missing out on some handy syntactical sugar (our, lexical filehandles, POSIX character classes in regexes, better utf8 support, etc.). I would suggest polling your existing community, if any, to see what their perl levels are, and see if there would really be any concern with just moving up to 2001 (perl 5.6.1) or, better, 2003 (perl 5.8.1). You may be giving yourself headaches for no reason.

    Update: Added italics. I'm not proposing that organisations change perls with each minor release. However, perl 5.6 is already antiquated by computing standards. That's about the time that Java 1.3 was out - as far as I'm aware, not only is it not supported anymore, but most people seem to have moved on to Java 1.4 already (which is probably newer than Perl 5.8.0). Why does perl get special treatment here?

      To be honest, is there really a need to worry about this?

      Usually, no. But several of the modules I've written are intended as very low-level building blocks and thus I want them to be backwards compatible as far as possible in case other authors want to or need to write something to run on an ancient version of Perl. (E.g. Class::InsideOut, Test::Number::Delta)

      Generally, I try to avoid using handy syntactical sugar if I don't need to. For example, if my only use of our is to specify the module's $VERSION, then I don't feel that little bit of sugar is really worth breaking my module on older Perls.

      Side note: I found it interesting to run Perl::MinimumVersion on some of my code. There are often very simple and easily avoided things that prevent backward compatibility if that's important.

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      To be honest, is there really a need to worry about this? Do you have active users who are not upgrading perl, but are upgrading your module?

      Upgrading perl to the next stable release means re-testing every single program you have in production, to find out what this release breaks. It's not something an organization does every day.

      Downloading the lastest version of a new module is what people do by default. It is something an organization does every day.

      I think his concerns are valid.

        Upgrading perl to the next stable release...

        There have been ten stable releases of Perl since 5.6.0. I don't believe that anyone who hasn't upgraded to a Perl released this millennium has a serious desire to install the new version of a module.