in reply to Re^11: the "our" declaration ?!! (special vars)
in thread the "our" declaration ?!!

If you think it is just a question of what I am "used to", then you need to read more carefully. If you don't understand how "vars" works, then you should correct that, because it is really simple and occasionally useful.

What vars does is declare a certain global in a certain package so that strict will not complain about it. If you have a package that crosses files, the declaration will cover both (assuming it happens in the first one Perl compiles). If you declare a variable then change packages, the declaration stops having an effect. In short, vars actually works like ikegami claimed that our did.

Simple, huh? What is it good for? In the unlikely situation that you want to share a global in 2 very different places, vars is the best way to do it. If in one file you need to declare something in another, vars is the only way to do it. (Luckily exporting a variable with Exporter also declares it, so you very rarely need to do that.) The only real benefit that our has over vars is that you can save one line on certain often-used declarations. (I don't consider obfuscation to be a benefit.) Other than that saving of typing, there is always a better way to do it.

On the missing orthogonality of how you can use local, that is Larry Wall's executive decision. He thought that using local on my variables would be too confusing, and so has deliberately rejected patches that would change that. I definitely don't blame that on our, however it is a difference and I like keeping track of differences.

But I personally don't often want to do local lexical variables. What has proven more useful for me is using local on the keys of a hash instead.

  • Comment on Re^12: the "our" declaration ?!! (special vars)

Replies are listed 'Best First'.
Re^13: the "our" declaration ?!! (special vars)
by LanX (Saint) on Jan 21, 2009 at 20:50 UTC
    > If you think it is just a question of what I am "used to", then you need to read more carefully.

    actually I read it all carefully but it's complicated to interpret a page full of coding *theory* without any code *examples*...and English is actually not my best foreign language ...

    >If you don't understand how "vars" works, then you should correct that, because it is really simple and occasionally useful.

    well the perldoc says

    the "use vars" and "use subs" declarations are not BLOCK-scoped. They are thus effective for the entire file in which they appear.
    but actually - as I only found out by experimenting - it depends on the scope of "package" which confused me!

    to make it clearer some code:

    use strict; $\="\n"; use vars qw($x); $x="main"; { print $x; package one; use vars qw($x); $x="one"; print $x; } print $x; __END__ main one main
    But where's the problem to import variables with our ??? Could you give me please a code example?

    Cheers Rolf

      Indeed. The vars and subs pragmas affect packages, not files. Their effects can even span files, if more than one file use the same package.

      Since imported variables aren't subject to use strict, and imported subs can override core functions, vars and subs simply export new vars and subs (respectively) into the caller's package.

Re^13: the "our" declaration ?!! (special vars)
by Sandy (Curate) on Jan 21, 2009 at 20:56 UTC
    Sorry if I misunderstand what you say
    What vars does is declare a certain global in a certain package so that strict will not complain about it. If you have a package that crosses files, the declaration will cover both (assuming it happens in the first one Perl compiles).
    foo.pl
    #!/usr/bin/perl use strict; use warnings; package Foo; use Bar; our $one; our $two; use vars qw($three $four); $one = 'one'; $two = 'two'; $three = 'three'; $four = 'four'; print "$one $two $three $four\n"; Foo::switch(); print "$one $two $three $four\n";
    Bar.pm
    #!/usr/bin/perl use strict; use warnings; package Foo; our $one; our $two; use vars qw($three $four); sub switch { $one = 1; $two = 2; $three = 3; $four = 4; } 1;
    result
    [sandy][~] perl foo.pl one two three four 1 2 3 4
    I'm not sure I see the difference between our and use vars

    UPDATE

    Thank you ikegami. Now I get it.

      Try commenting out

      use vars qw($three $four);

      in foo.pl. Then try commenting out

      our $one; our $two;

      in foo.pl

        Yeah but this saves just one line in foo.pl, a benefit restricted to cases where I don't wanna use the import() method!

        Sandy thanks for the code-example, makes it much clearer! : )

Re^13: the "our" declaration ?!! (special vars)
by Jenda (Abbot) on Jan 21, 2009 at 23:27 UTC

    The real benefit of "our" is that it's block scoped. It's not "I know about this variable in the current package, let me access it directly wherever I am". It's rather "Excuse me? I'd like to access this 'global' variable over here without having to prepend the package name." Its effects are much more restricted (OK, this depends on the location of the "our" declaration). So you specifically CAN'T declare something in one file and have it affect the code in another, you can't declare somewhere that you intend to use a 'global' variable and silence all fatal errors for such named variables all over the place no matter whether on that other place you are aware of some global.

    Of course if you declare all your globals on top of the file it doesn't matter much whether you use vars ... or our (...). But that's about as clever as declaring all variables with my (...) on top of the file. You can, but you should not.

    I would rather our in this block and our in that block and stay "safe" elsewhere.

      When I our in this block and our in that block, nothing prevents me from accidentally using slightly different variable names in the two blocks. This is a common error for me, particularly when the blocks are far apart, and I really want strict to catch it.

      Therefore if I want to access a global in 2 places, I really, really want to declare that global in one place. While the ability to declare it in multiple tight scopes sounds neat, it is bad software design to do things that way.

        As Jenda pointed out you can still declare once with our() on top of the file, which has the same effect as "use vars"...

        Sorry, I still don't understand what you can do with "vars" which is not possible with our()¹. Could you please post a short code example to make it clearer?

        UPDATES:
        (¹) Or an explicit import() method.