2

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?

Ltf4an
  • 677
  • 5
  • 16
  • Possible duplicate of [What is the difference between my and our in Perl?](http://stackoverflow.com/questions/845060/what-is-the-difference-between-my-and-our-in-perl) – Steffen Ullrich Nov 19 '16 at 18:37
  • 1
    @SteffenUllrich I don't think so. That's a mechanistic question, *what* do `our` and `my` do? This question is *why* would one use `our`? – Schwern Nov 19 '16 at 18:56

2 Answers2

3

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.

Schwern
  • 127,817
  • 21
  • 150
  • 290
  • 1
    Re "*When you're required to use a global variable.*", i.e. When the variable needs to be accessed by name from another file. Many call file-scoped variables global variables, but they aren't, and `my` is the better choice for them. – ikegami Nov 20 '16 at 01:09
2

It is needed in certain circumstances, such as accessing the class variables from other locations where you don't need/can't use a getter:

package Package;
our $VERSION = '0.01';
1;

Now:

perl -wMstrict -MPackage -E 'say $Package::VERSION'
0.01

If the $VERSION variable was declared with my:

Use of uninitialized value $Package::VERSION in say at -e line 1.

That is, the variable is not visible outside of the package namespace itself, because when using my, it is lexical to the package itself, ie. it's in package scope only.

You must also use our if you are exporting variables:

package Package;
use Exporter;
our @ISA = 'Exporter';
our @EXPORT = qw($x);

our $x = 10;

1;

This will print 10:

perl -wMstrict -MPackage -E 'say $x'

...but with my, you'll get the same warning as above.

stevieb
  • 8,323
  • 3
  • 24
  • 34