Ltf4an Ltf4an - 16 days ago 5
Perl Question

When is our needed in a Perl program?

It seems that our is only needed for exposing a (global) variable in a package. In other contexts, its use only helps readability but is not required.

And if the above observation is right, then by following the practice of encapsulation, it's not even needed in a package, because my would be used, and getter and setter would be provided.

Assuming my application can completely be implemented using OOD, and that within a package, data is strictly passed around using args to subroutines, would I then completely obviate the need for our?

Answer

Use our when...

  1. You're required to use a global variable.
  2. You want to use local (which you probably shouldn't).

In general you're correct, anything you might do as a global variable could be done with a class method accessor gaining all the advantages of encapsulation.

For example...

package Foo;
use strict;
use warnings;

our $Thing = 42;

compared to...

package Foo;
use strict;
use warnings;

sub thing { 42 }

What happens if $Foo::Thing is no longer a simple constant? What if it's something that turns out to be expensive to calculate and rarely used? By encapsulating with Foo->thing you can do the calculation only when needed.

It also allows subclasses to override class information.

package Bar;
our @ISA = qw(Foo);

sub thing { 23 }

And that brings us to when to use our: when you have to. There's a lot of Perl features and libraries that read global variables either by convention or implementation. The most common examples are @ISA for subclassing, $VERSION, and the salad of Exporter variables like @EXPORT.

There are better ways to do this, and many modules like Exporter have replacements, but many of these conventions were laid down when Perl 5 wasn't comfortable with OO.


There is one final use of our and that's to take advantage of local. It can be used to pass extra data around without changing the function signatures. The original value is automatically restored when the function exits.

our $foo;

sub something {
    ...do something involving $foo and set $stuff...

    local $foo = $stuff;
    something();
}

Yes, this is a poor example.

The circumstances where this is useful and advisable are, again, indicative of bad design. Usually it's used to pass extra data between functions without changing their signature, often as part of recursion. File::Find is littered with this technique. Run perldoc -m File::Find and poke around.

Comments