in reply to Our Across Multiple Files?

It's important to understand exactly what our does, then you'll see that you can use it across multiple files.

our, like my, is a lexically-scoped declaration. That means it holds sway over a particular region of the source code -- from the declaration down to the end of the block that the declaration is in.

The effect of an our declaration is a bit subtle. It allows you to use a global variable (i.e. a package variable) without having to qualify it with the name of the package. So far so good, but the complication arises when you change the current package within the scope of the our declaration.

use strict; package foo; our $x; # Declare $x as an abbreviation for $foo::x $x = 23; package bar; print $x; # Still refers to $foo::x even # though we're now in package 'bar'

When you understand that, you'll see how to use our across multiple files. The important thing is to make sure that the declaration is in the same package each time. For example:

# This is test.pl use strict; our $foo = "Hello!\n"; use Bar; Bar->test();

# This is Bar.pm use strict; our $foo; package Bar; sub test { print $foo; } 1;

A more difficult question is why you'd want to do this. Using a global variable from within a package violates encapsulation. If you find yourself needing to do it, that's probably a sign that your code needs to be redesigned.

Replies are listed 'Best First'.
Re: Re: Our Across Multiple Files?
by Anonymous Monk on Dec 17, 2001 at 22:46 UTC
    I have a single DBH connection object, a single instance object, and others for a one-time project I'm working on myself. I know its not exaclty great technique, but because I'm the only one that will ever see it, I don't think it will hurt in the long run.

      You could just put it in package main, as in $main::db = new DB();, although it's one of those design choices that can get very deeply sedimented in a large project, and hard to change later.

      If you're feeling amibitious, why not try a singleton class, with a class method that returns the data you need?

      package GlobalVarsSingleton; my $instance; # a 'private' ctor sub _new { # init stuff } sub Instance { my ($class, %args) = @_; unless (defined $instance) { $instance = $class->_new(%args); return $instance; } else { return $instance; } }

      The singleton ensures that you'll only have one instance of the data per interpreter, and the calling code doesn't have to care where that data lives.

      The only remaining caveat is that code not meant to stick around sometimes does. I have code written as throw-away from year ago slightly tweaked and running in production on servers today. Oh, and that Unix thing so many people (including myself) love? The original was meant to be an in-house project...