home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


4.7 Subroutines

Subroutines are declared using one of these forms:

sub 
name
 {
block
}
sub 
name
 (
proto
) {
block
}
Prototypes allow you to put constraints on the arguments you provide to your subroutines.

You can also create anonymous subroutines at run-time, which will be available for use through a reference:

$
subref
 = sub {
block
};

4.7.1 Calling Subroutines

The ampersand ( & ) is the identifier used to call subroutines. Most of the time, however, subroutines can be used in an expression just like built-in functions. To call subroutines directly:


name
(
args
);                  # & is optional with parentheses

name
 
args
;                   # Parens optional if predeclared/imported
&
name;
                       # Passes current @_ to subroutine
To call subroutines indirectly (by name or by reference):
&$subref(
args
);                 # & is not optional on indirect call
&$subref;                       # Passes current @_ to subroutine

4.7.2 Passing Arguments

All arguments to a subroutine are passed as a single, flat list of scalars, and return values are returned the same way. Any arrays or hashes passed in these lists will have their values interpolated into the flattened list.

Any arguments passed to a subroutine come in as the array @_ .

You may use the explicit return statement to return a value and leave the subroutine at any point.

4.7.3 Passing References

If you want to pass more than one array or hash into or out of a function and have them maintain their integrity, then you will want to pass references as arguments. The simplest way to do this is to take your named variables and put a backslash in front of them in the argument list:

@returnlist = ref_conversion(
\@temps1, \@temps2, \@temps3
);
This sends references to the three arrays to the subroutine (and saves you the step of creating your own named references to send to the function). The references to the arrays are passed to the subroutine as the three-member @_ array. The subroutine will have to dereference the arguments so that the data values may be used.

Returning references is a simple matter of returning scalars that are references. This way you can return distinct hashes and arrays.

4.7.4 Private and Local Variables

Any variables you use in the function that aren't declared private are global variables. In subroutines, you'll often want to use variables that won't be used anywhere else in your program, and you don't want them taking up memory when the subroutine is not being executed. You also might not want to alter variables in subroutines that might have the same name as global variables.

The my function declares variables that are lexically scoped within the subroutine. Lexically scoped variables are private variables that only exist within the block or subroutine in which they are declared. Outside of their scope, they are invisible and can't be altered in any way.

To scope multiple variables at once, use a list in parentheses. You can also assign a variable in a my statement:

my @list = (44, 55, 66);
my $cd = "orb";
Dynamic variables are visible to other subroutines called from within their scope. Dynamic variables are defined with local , and they are not private variables, but rather they are global variables with temporary values. When a subroutine is executed, the global value is hidden away, and the local value is used. Once the scope is exited, the original global value is used. Most of the time you will want to use my to localize parameters in a subroutine.

4.7.5 Prototypes

Prototypes allow you to design your subroutines to take arguments with constraints on the number of parameters and types of data. To declare a function with prototypes, use the prototype symbols in the declaration line, like this:

sub addem ($$) {
...
}
In this case, the function expects two scalar arguments. The following table gives the various prototype symbols:

Symbol Meaning
$ Scalar
@ List
% Hash
& Anonymous subroutine
* Typeglob

A backslash placed before one of these symbols forces the argument to be that exact variable type. For instance, a function that requires a hash variable would be declared like this:

sub hashfunc (\%);
Unbackslashed @ or % symbols act exactly alike, and will eat up all remaining arguments, forcing list context. A $ likewise forces scalar context on an argument, so taking an array or hash variable for that parameter would probably yield unwanted results.

A semicolon separates mandatory arguments from optional arguments. For example:

sub newsplit (\@$;$);
requires two arguments: an array variable and a scalar. The third scalar is optional. Placing a semicolon before @ and % is not necessary since lists can be null.

A typeglob prototype symbol ( * ) will always turn its argument into a reference to a symbol table entry. It is most often used for filehandles.