Understand “global” variables.

Perl has two sorts of variables: the lexical variables that are limited to a particular scope, and package variables that you define in a namespace. The package variables are sometimes also called global variables because they are visible from anywhere in the program as long as you know their name. As you might suspect, Perl makes it a bit more interesting: there are many sorts of global variables.

For this Item, forget about lexical variables. Focus on how the non-lexical variables work rather than which sort you should normally use. You’re only considering the behavior for these variables:

  • package globals
  • special “true” globals
  • special package globals
  • per-filehandle special variables

Package variables are global, mostly

Perl has packages the compartmentalize your work so you can choose variable names without knowing all of the other names already defined in your program. While in a particular package, you can use just the variable name (e.g. $name, and away from that package, you can use the full package specification (e.g. $Cat::name):

{
package Cat; 
$name = 'Buster';
print "\$name is [$name]. \$Cat::name is [$Cat::name]\n";
}

{
package Dog;
print "\$name is [$name]. \$Cat::name is [$Cat::name]\n";
}

The output shows that while in package Cat, both $name and $Cat::name are the same thing. In Dog, however, $name isn’t the same variable, but you can still see $Cat::name:

$name is [Buster]. $Cat::name is [Buster]
$name is []. $Cat::name is [Buster]

If you know the package and name of the variable, such as $Cat::name, you can access it from anywhere in the program. Since these variables are package variables, you call them package globals.

Most special variables live in main::

Most Perl special variables are always defined in the main:: package no matter where you use them or what the current package is. We’ll call these true globals, for lack of a better term, since you only need to know the name of the variable. You’ve already know about the special variables such as $_ and [email protected], and you can read about the others in perlvar.

In this program, you set $_ in the Not_main package:

{
package Not_main; 
$_ = 'Buster';
print "\$_ is [$_]. \$main::_ is [$main::_]\n";
}

{
package main;
print "\$_ is [$_]. \$main::_ is [$main::_]\n";
}

The output is the same in both packages because $_ doesn’t rely on the current package to look up its value:

$_ is [Buster]. $main::_ is [Buster]
$_ is [Buster]. $main::_ is [Buster]

There’s the small note that Perl 5.10 lets you define a lexical $_ (Item 15: Use $_ for brevity and elegance) and that the $_ in given-when use a lexical $_ (Item 24: Use given-when to make a switch statement), but ignore that for this Item.

Some special variables aren’t in main::

There are at least two exceptions to special variables living in the main:: package. Perl uses the package variables $a and $b in sort; these variables are always in the same package as the sort, in this case, Cats:

package Cats;
my @strings = qw(Mimi Ella Buster Ginger);

{
my @sorted = sort { $a cmp $b } @strings;
print "@sorted\n";
}

{
my @sorted = sort { $main::a cmp $main::b } @strings;
print "@sorted\n";
}

The output shows that the first block sorts the strings just fine, but the second block doesn’t change the order at all. It’s a little more apparent what’s going on when you print the values that you are sorting:

package Cats;
my @strings = qw(Mimi Ella Buster Ginger);

{
my @sorted = sort { 
	print "a: [$a] b: [$b]\n";
	$a cmp $b 
	} @strings;
print "@sorted\n";
}

{
my @sorted = sort { 
	print "a: [$main::a] b: [$main::b]\n";
	$main::a cmp $main::b 
	} @strings;
print "@sorted\n";
}

The output shows that the second sort doesn’t see the elements at all; it’s looking in the wrong package:

a: [Mimi] b: [Ella]
a: [Buster] b: [Ginger]
a: [Ella] b: [Buster]
a: [Ella] b: [Ginger]
a: [Mimi] b: [Ginger]
Buster Ella Ginger Mimi
a: [] b: []
a: [] b: []
a: [] b: []
a: [] b: []
Mimi Ella Buster Ginger

In this case, “special” really means that Perl uses the variables to do its work. There’s no magic with them. Since $a and $b are sort of a hybrid, you call them special package variables.

Filehandles have their own set of special variables

Some of the special variables lead multiple lives because Perl actually tracks their values per-filehandle. The value you get from these variables is that for the current default output filehandle, which you can change with select. You’ll probably only ever use one of these variables since most of them deal with formats:

Variable English perlvar description
$~ $FORMAT_NAME The name of the current report format for the currently selected output channel. Default is the name of the filehandle.
$^ $FORMAT_TOP_NAME The name of the current top-of-page format for the currently selected output channel. Default is the name of the filehandle with _TOP appended.
$| $OUTPUT_AUTOFLUSH If set to nonzero, forces a flush right away and after every write or print on the currently selected output channel.
$% $FORMAT_PAGE_NUMBER The current page number of the currently selected output channel. Used with formats.
$= $FORMAT_LINES_PER_PAGE The current page length (printable lines) of the currently selected output channel. Default is 60. Used with formats.
$- $FORMAT_LINES_LEFT The number of lines left on the page of the currently selected output channel. Used with formats.

These values are always those for the default output filehandle. Each filehandle structure in the internals tracks these values for itself. The default filehandle is an output feature, so it exposes variables that affect output. The tricky thing, however, is that some of the values that a filehandle track are not exposed in Perl special variables through the default filehandle.

Perl also tracks the $. variable per filehandle, but it really the line count for the last input handle that you used. It doesn’t care about the default output filehandle because it’s not an output attribute, as you can see in this program:

use vars qw($fh_1 $fh_a);
sub show_line_count {
	select $main::fh_1;
	print STDOUT "fh_1: \$. is $.\n";

	select $main::fh_a;
	print STDOUT "fh_a: \$. is $.\n";

	select STDIN;
	print STDOUT "STDIN: \$. is $.\n";
	}

my $string_1 = join "\n", map { "line $_" } 1 .. 26;
my $string_a = join "\n", map { "line $_" } 'a' .. 'z';

open $main::fh_1, '<', \$string_1;
open $main::fh_a, '<', \$string_a;

<$fh_1> for 1 ..5;
show_line_count();

<$fh_a>;
show_line_count();

The output shows that $. doesn’t care what the default output filehandle is:

fh_1: $. is 5
fh_a: $. is 5
STDIN: $. is 5
fh_1: $. is 1
fh_a: $. is 1
STDIN: $. is 1

Although Perl exposes some of the filehandle values through special variables, you can also access them directly through IO::Handle without changing the default output filehandle, but we’ll save that for another Item.

Things you can ignore (for now)

If you thought you were done, remember that you are using Perl. Some variables are visible across threads or private to a particular thread.

Things to remember

  • Package variables are visible throughout the entire program.
  • You can access a package variable anywhere in the program if you know its package. These are package globals.
  • Perl’s special variables are defined in main::, no matter what the current package is. These are true globals.
  • The $a and $b variables are special, but they are defined in the current package. These are special package globals.
  • Perl special variables related to output filehandles are tracked per-filehandle and their current values are for the default output filehandle.
Leave a comment

0 Comments.

Leave a Reply


[ Ctrl + Enter ]