http://www.perlmonks.org?node_id=48350


in reply to "use vars" will remain (Re: Win32 EXPORT_OK problems)
in thread Win32 EXPORT_OK problems

What is wrong with:
package Our; require strict; # Must be sure it has been loaded sub import { if ($] < 5.006) { my $pkg = caller(); *{"$pkg\::our"} = \*our; @_ = qw(strict vars); goto &strict::unimport; } } sub our { } 1; __END__ =head1 NAME Our - pragma to gracefully degrade 'our' on older Perl's. =head1 SYNOPSIS use strict; use Our; # Must appear after strict our($foo); =head1 DESCRIPTION On older versions of Perl this undoes strict vars, and imports an our function. This allows modules to be developed on newer Perl's using 'our' yet still run on older installations. =head1 BUGS This provides backwards but not forwards compatibility. Caveat developer.
Try the following sample script:
use strict; use Our; our ($foo); $foo = "hello\n"; print $foo;
OK, so you have to put the Our after the strict. And to get the benefit from strict you need to be doing your development on a recent version of Perl. But this lets you get all of the development benefits of our while still retaining backwards compatibility.

Replies are listed 'Best First'.
Oops
by tilly (Archbishop) on Dec 27, 2000 at 03:20 UTC
    There is a neat "feature" I was missing. The following code does something interesting:
    use strict; package Foo; our $foo = "Hello world\n"; package Foo::Bar; print $foo; package Foo::Baz; print $foo;
    While the small module I supplied solves the main backwards compatibility issue, there is no way to tie out older Perl's to such (ab)use.
(tye)Re: "use vars" will remain (Re: Win32 EXPORT_OK problems)
by tye (Sage) on Dec 27, 2000 at 01:39 UTC

    I would still recommend use vars over this.

    First, I don't like the idea of a module that rather sneakilly sometimes turns off use strict "vars". If your development moves to a pre-5.6 version of Perl, you could easily not notice that your innocuous use Our has now disabled your use strict.pm until you waste a couple of days chasing the kind of bug that use strict.pm makes obvious (the reason you are supposed to use strict.pm).

    I certainly don't consider this risk worth the very minor speed improvement which is the only advantage to our over use vars.

    Also, if you are supporting pre-5.6 versions of Perl, you will be testing with pre-5.6 which may require some development in pre-5.6 versions which you shouldn't be doing without use strict.pm.

    So my problems with this approach are quite small but I consider them huge compared to the tiny, tiny "problem" that they solve -- being able to use our instead of use vars. If you are firmly into 5.6-and-later Perl and choose to use our, then these provide a nice way to be pollite to people who aren't.

    I will continue to do use vars until Perl supports non-blocked compile-time code (or another soltution) for being able to conditionally use our (or until pre-5.6 Perl becomes old enough that I never run into it anymore).

            - tye (but my friends call me "Tye")
      You are wrong that a speed improvement is the only reason to use our over use vars. (In fact I am not absolutely positive that it is always a win.)

      The difference with our is that the declaration is lexical, not global. So using our in 3 functions becomes an alternative to a global that is globally accessible, or a private block with a lexical variable.

      Personally I don't consider the win over use vars to be compelling. In fact if you are going to be sharing a variable in several places, I don't like having to synchronize the declarations. Hence for most purposes I actively prefer use vars.

      However that is an opinion decidedly at odds with many other people. Hence the above may prove useful if (unlike me) you are in a predominantly 5.6 environment and like our.

      Actually, I think our has one other advantage over use vars, aside from the very minor speed improvement. With our, as with my, declaration and initialization can be done in one step:
      my $num = 7; our $str = 'Hello';
      whereas with use vars, declaration and initialization must always be separate steps:
      use vars qw/ $str /; $str = 'Hello';

        declaration and initialization can be done in one step

        Ah, yes, but should they? Even I were to use our, I'd still be writing code like:

        our $var; BEGIN { $var= "Hello"; }
        to avoid the race condition between the compile-time declaration of the variable and the (possibly very delayed or non-existant) run-time initialization of the variable. This is only rarely a problem, but it still happens often enough that this habit has saved me enough time that I continue it.

                - tye (but my friends call me "Tye")