Title

Previous Chapter
Next Chapter

Links
Sections
Chapters
Copyright

Sections

String Functions

Array Functions

Summary

Review Questions

Review Exercises

Chapters

ERRATA

Welcome!

Introduction

Part I: Basic Perl

01-Getting Your Feet Wet

02-Numeric and String Literals

03-Variables

04-Operators

05-Functions

06-Statements

07-Control Statements

08-References

Part II: Intermediate Perl

09-Using Files

10-Regular Expressions

11-Creating Reports

Part III: Advanced Perl

12-Using Special Variables

13-Handling Errors and Signals

14-What Are Objects?

15-Perl Modules

16-Debugging Perl

17-Command line Options

Part IV: Perl and the Internet

18-Using Internet Protocols

ftplib.pl

19-What is CGI?

20-Form Processing

21-Using Perl with Web Servers

22-Internet Resources

Appendixes

A-Review Questions

B-Glossary

C-Function List

D-The Windows Registry

E-What's On the CD?

     

05 - Functions

This chapter takes a look at functions. Functions are blocks of codes that are given names so that you can use them as needed. Functions help you to organize your code into pieces that are easy to understand and work with. They let you build your program step by step, testing the code along the way.

After you get the idea for a program, you need to develop a program outline - either in your head or on paper. Each step in the outline might be one function in your program. This is called modular programming. Modular programming is very good at allowing you to hide the details so that readers of your source code can understand the overall aim of your program.

For instance, if your program has a function that calculates the area of a circle the following line of code might be used to call it:

$areaOfFirstCircle = areaOfCircle($firstRadius);
By looking at the function call, the reader knows what the program is doing. Detailed understanding of the actual function is not needed.

Tip
Well thought out function and variable names help people to understand your program. If the line of code was

$areaFC = areaCirc($fRad);
Its meaning would not be as clear.

Note
Calling a function means that Perl stops executing the current series of program lines. Program flow jumps into the program code inside the function. When the function is finished, Perl jumps back to the point at which the function call was made. Program execution continues from that point onward.

Let's look at the function call a little closer. The first thing on the line is a scalar variable and an assignment operator. You already know this means Perl assigns the value on the right of the assignment operator to $areaOfFirstCircle. But what exactly is on the right?

The first thing you see is the function name: areaOfCircle(). The parentheses directly to the right and no $, @, or % beginning the name indicates that this is a function call. Inside the parentheses is a list of parameters or values that get passed to the function. You can think of a parameter just like a football. When passed, the receiver (for example, the function) has several options: run (modify it in some way), pass (call other routines), fumble (call the error handler).

Note
Perl allows you to use the & character to start function names, and in a few cases it is needed. Those few situations that the & character is needed are beyond the scope of this book.

Listing 5.1 shows a short program that calls and defines the areaOfCircle() function.

Pseudocode

Assign $areaOfFirstCircle the value that is returned by the function areaOfCircle().

Print $areaOfFirstCircle.

Define the areaOfCircle() function.

Get the first parameter from the @_ parameter array.

Calculate the area and return the new value.

Listing 5.1-05LST01.PL - Calculating the Area of a Circle


$areaOfFirstCircle = areaOfCircle(5); print("$areaOfFirstCircle\n"); sub areaOfCircle { $radius = $_[0]; return(3.1415 * ($radius ** 2)); }

This program prints:

78.5375
The fact that something prints tells you that the program flow returned to the print line after calling the areaOfCircle() function.

A function definition is very simple. It consists of:

sub functionName {
}
That's it. Perl function definitions never get any more complex.

The complicated part comes when dealing with parameters. Parameters are values passed to the function (remember the football?). The parameters are specified inside the parentheses that immediately follow the function name. In Listing 5.1, the function call was areaOfCircle(5). There was only one parameter, the number 5. Even though there is only one parameter, Perl creates a parameter array for the function to use.

Inside the areaOfCircle() function, the parameter array is named @_. All parameters specified during the function call are stored in the @_ array so that the function can retrieve them. Our small function did this with the line:

$radius = $_[0];
This line of code assigns the first element of the @_ array to the $radius scalar.

Note
Because parameters are always passed as lists, Perl functions are also referred to as list operators. And if only one parameter is used, they are sometimes referred to as unary operators. However, I'll continue to call them functions and leave the finer points of distinction to others.

The next line of the function:

return(3.1415 * ($radius ** 2));
calculates the circle's area and returns the newly calculated value. In this case, the returning value is assigned to the $areaOfFirstCircle scalar variable.

Note
If you prefer, you don't need to use the return() function to return a value since Perl automatically returns the value of the last expression evaluated. I prefer to use the return() function and be explicit so that there is no mistaking my intention.

You may have used programming languages that distinguish between a function and a subroutine. The difference being that a function returns a value and a subroutine does not. Perl makes no such distinctions. Everything is a function - whether or not it returns a value.

Example: Using the Parameter Array (@_)

All parameters to a function are stored in an array called @_. One side effect of this is that you can find out how many parameters were passed by evaluating @_ in a scalar context.

Pseudocode

Call the firstSub() function with a variety of parameters.

Define the firstSub() function

Assign $numParameters the number of elements in the array @_.

Print out how any parameters were passed.

firstSub(1, 2, 3, 4, 5, 6);
firstSub(1..3);
firstSub("A".."Z");

sub firstSub {
    $numParameters = @_;
    print("The number of parameters is $numParameters\n");
}
This program prints out:
The number of parameters is 6
The number of parameters is 3
The number of parameters is 26
Perl lets you pass any number of parameters to a function. The function decides which parameters to use and in what order. The @_ array is used like any other array.

Let's say that you want to use scalar variables to reference the parameters so that you don't have to use the clumsy and uninformative $_[0] array element notation. By using the assignment operator, we can assign array elements to scalars in one easy step.

Pseudocode

Call the areaOfRectangle() function with varying parameters.

Define the areaOfRectangle() function.

Assign the first two elements of @_ to $height and $width respectively.

Calculate the area.

Print the three variables: $height, $width and $area.

areaOfRectangle(2, 3);
areaOfRectangle(5, 6);

sub areaOfRectangle {
    ($height, $width) = @_;

    $area = $height * $width;

    print("The height is $height. The width is $width.
        The area is $area.\n\n");
}
This program prints out:
The height is 2. The width is 3.
        The area is 6.

The height is 5. The width is 6.
        The area is 30.
The statement ($height, $width) = @_; does the array element to scalar assignment. The first element is assigned to $height and the second element is assigned to $width. After the assignment is made you can use the scalar variables to represent the parameters.

Example: Passing Parameters by Reference

Using scalar variables inside your functions is a good idea for another reason - besides simple readability concerns. When you change the value of the elements of the @_ array, you also change the value of the parameters in the rest of the program. This is because Perl parameters are called by reference. When parameters are called by reference, changing their value in the function also changes their value in the main program. Listing 5.2 shows how this happens.

Pseudocode

Create an array with 6 elements.

Print the elements of the array.

Call the firstSub() function.

Print the elements of the array.

Define the firstSub() function.

Change the values of the first two elements of @_.

Listing 5.2-05LST02.PL - Using the @_ Array to Show Call by Reference


@array = (0..5);
print("Before function call, array = @array\n");
firstSub(@array);
print("After function call, array =  @array\n");

sub firstSub{
    $_[0] = "A";
    $_[1] = "B";
}

This program prints:

Before function call, array =  0 1 2 3 4 5
After function call, array =   A B 2 3 4 5
You can see that the function was able to affect the @array variable in the main program. Generally this is considered bad programming practice because it does not isolate what the function does from the rest of the program. If you change the function so that scalars are used inside the function this problem goes away. Listing 5.3 shows how to redo the program in Listing 5.2 so that scalars are used inside the function.

Pseudocode

Create an array with 6 elements.

Print the elements of the array.

Call the firstSub() function.

Print the elements of the array.

Define the firstSub() function.

Assign the first two elements of @_ to $firstVar and $secondVar.P> Change the values of the scalar variables.

Listing 5.3-05LST03.PL - Using Scalars Instead of the @_ Array inside Functions


@array = (0..5); print("Before function call, array = @array\n"); firstSub(@array); print("After function call, array = @array\n"); sub firstSub{ ($firstVar, $secondVar) = @_; $firstVar = "A"; $secondVar = "B"; }

This program prints:

Before function call, array =  0 1 2 3 4 5
After function call, array =   0 1 2 3 4 5
This example shows that the original @array variable is left untouched. However, another problem has quietly arisen. Let's change the program a little so that the values of $firstVar are printed before and after the function call. Listing 5.4 shows how changing a variable in the function affects the main program.

Pseudocode

Assign a value to $firstVar.

Create an array with 6 elements.

Print the elements of the array.

Call the firstSub() function.

Print the elements of the array.

Define the firstSub() function.

Assign the first two elements of @_ to $firstVar and $secondVar.

Change the values of the scalar variables.

Listing 5.4-05LST04.PL - Using Variables in Functions Can Cause Unexpected Results


$firstVar = 10; @array = (0..5); print("Before function call\n"); print("\tfirstVar = $firstVar\n"); print("\tarray = @array\n"); firstSub(@array); print("After function call\n"); print("\tfirstVar = $firstVar\n"); print("\tarray = @array\n"); sub firstSub{ ($firstVar, $secondVar) = @_; $firstVar = "A"; $secondVar = "B"; }

This program prints:

Before function call
        firstVar = 10
        array    = 0 1 2 3 4 5

After function call
        firstVar = A
        array    = 0 1 2 3 4 5
By using the $firstVar variable in the function you also change its value in the main program. By default, all Perl variables are accessible everywhere inside a program. This ability to globally access variables can be a good thing at times. But it doesn't help when trying to isolate a function from the rest of your program. The next section shows you how to create variables that can only be used inside functions.

Example: Scope of Variables

Scope refers to the visibility of variables. In other words, which parts of your program can see or use it. Normally, every variable has a global scope. Once defined, every part of your program can access a variable.

It is very useful to be able to limit a variable's scope to a single function. In other words, the variable will have a limited scope. This way, changes inside the function can't affect the main program in unexpected ways. Listing 5.5 introduces two of Perl's built-in functions that create variables of limited scope. The my() function creates a variable that only the current function can see. The local() function creates a variable visible inside the current function and inside any functions that are called by the current function. If that sounds confusing, don't worry. It is confusing, but Listing 5.5 should clear things up. In this case, it's a listing that is worth a thousand words, not a picture!

Pseudocode

Call firstSub() with two parameters.

Define the firstSub() function.

Assign the first parameter to local variable $firstVar.

Assign the second parameter to my variable $secondVar.

Print the variables.

Call the second function without any parameters.

Print the variables to see what changed.

Define the secondSub() function.

Print the variables.

Assign new values to the variables.

Print the variables to see that the new values were assigned correctly.

Listing 5.5-05LST05.PL - Using the Local and My Functions to Create Local Variables


firstSub("AAAAA", "BBBBB"); print("done: firstVar = $firstVar\n"); print("done: secondVar = $secondVar\n\n"); sub firstSub{ local ($firstVar) = $_[0]; my($secondVar) = $_[1]; print("firstSub: firstVar = $firstVar\n"); print("firstSub: secondVar = $secondVar\n\n"); secondSub(); print("firstSub: firstVar = $firstVar\n"); print("firstSub: secondVar = $secondVar\n\n"); } sub secondSub{ print("secondSub: firstVar = $firstVar\n"); print("secondSub: secondVar = $secondVar\n\n"); $firstVar = "CCCCC"; $secondVar = "DDDDD"; print("secondSub: firstVar = $firstVar\n"); print("secondSub: secondVar = $secondVar\n\n"); }

This program prints:

firstSub: firstVar = AAAAA
firstSub: secondVar = BBBBB

secondSub: firstVar  = AAAAA
Use of uninitialized value at test.pl line 19.
secondSub: secondVar =

secondSub: firstVar  = CCCCC
secondSub: secondVar = DDDDD

firstSub: firstVar  = CCCCC
firstSub: secondVar = BBBBB

Use of uninitialized value at test.pl line 3.
done: firstVar  =
done: secondVar = DDDDD
The output from this example shows that secondSub() could not access the $secondVar variable which was created with my() inside firstSub(). Perl even prints out an error message that warns about the uninitialized value. The $firstVar variable, however, can be accessed and valued by secondSub().

Tip
It's generally a better idea to use my() instead of local() so that you can tightly control the scope of local variables. Think about this way - It's four in the morning and the project is due. Is that the time to be checking variable scope? No, using my()enforces good programming practices and reduces headaches.

Actually, the my() function is even more complex than I've said. The easy definition is that it creates variables that only the current function can see. The true definition is that it creates variables with lexical scope. That is, variables that are local to the file, block, or eval. This distinction is only important when creating modules or objects so let's ignore the complicated definition for now. You'll hear more about it in Chapter 15, "Perl Modules."

If you remember, I mentioned calling parameters by reference. Passing parameters by reference means that functions can change the variable's value and the main program sees the change. When local() is used in conjunction with assigning the @_ array elements to scalars, then the parameters are essentially being called by value. The function can change the value of the variable, but only the function is affected. The rest of the program sees the old value.

Example: Using a List as a Function Parameter

Now that you understand about the scope of variables, let's take another look at parameters. Since all parameters are passed to a function in one array, what if you need to pass both a scalar and an array to the same function? This next example shows you what happens.

Pseudocode

Call the firstSub() function with two parameters: a list and a scalar.

Define the firstSub() function.

Assign the elements of the @_ array to @array and $firstVar.

Print @array and $firstVar.

firstSub((0..10), "AAAA");

sub firstSub{
    local(@array, $firstVar) = @_;

    print("firstSub: array    = @array\n");
    print("firstSub: firstVar = $firstVar\n");
}

This program prints:

firstSub: array    = 0 1 2 3 4 5 6 7 8 9 10 AAAA
Use of uninitialized value at test.pl line 8.
firstSub: firstVar =
When the local variables are initialized, the @array variables grab all of the elements in the @_ array, leaving none for the scalar variable. This results in the uninitialized value message displayed in the output. You can fix this by merely reversing the order of parameters. If the scalar value comes first, then the function processes the parameters without a problem.

Pseudocode

Call the firstSub() function with two parameters: a scalar and a list.

Define the firstSub() function.

Assign the elements of the @_ array to $firstVar and @array.

Print @array and $firstVar.

firstSub("AAAA", (0..10));

sub firstSub{
    local($firstVar, @array) = @_;

    print("firstSub: array    = @array\n");
    print("firstSub: firstVar = $firstVar\n");
}
This program prints:
firstSub: array    = 0 1 2 3 4 5 6 7 8 9 10
firstSub: firstVar = AAAA
Note
You can pass as many scalar values as you want to a function, but only one array. If you try to pass more than one array, the array elements become joined together and passed as one array to the function. Your function won't be able to tell when one array starts and another ends.

Example: Nesting Function Calls

Function calls can be nested many levels deep. Nested function calls simply means that one function can call another which in turn can call another. Exactly how many levels you can nest depends on which version of Perl you are running and how your machine is configured. Normally, you don't have to worry about it. If you want to see how many levels your system can recurse try the following small program.

Pseudocode

Call the firstSub() function.

Define the firstSub() function.

Print $count

Increment $count by one.

Call the firstSub() function recursively.

firstSub();

sub firstSub{
    print("$count\n");
    $count++;
    firstSub();
}
My system counts up to 127 before displaying the following message:
Error: Runtime exception
While it is important to realize that there is a limit to the number of times your program can nest functions, you should never run into this limitation unless you are working with recursive mathematical functions.

Example: Using a Private Function

Occasionally, you might want to create a private function. A private function is one that is only available inside the scope where it was defined.

Pseudocode

Assign the return value from performCalc() to $temp.

Print $temp.

Define the performCalc() function which accepts two parameters and returns the sum of the parameters squared. An anonymous function is used to perform the square function.

Assign my scalar variables values from the @_ parameter array.

Define the private function referred to by $square.

Return the first element of the @_ parameter array raised to the 2nd power.

Return the value of $firstVar raised to the 2nd power and $secondVar raised to the 2nd power.

$temp = performCalc(10, 10);
print("temp = $temp\n");

sub performCalc {
    my ($firstVar, $secondVar) = @_;

    my $square = sub {
        return($_[0] ** 2);
    };

    return(&$square($firstVar) + &$square($secondVar));
};
This program prints:
temp = 200
This example is rather trivial but it serves to show that in Perl it pays to create little helper routines. A fine line needs to be draw between what should be included as a private function and what shouldn't. I'd draw the line at 5 or 6 lines of code. Anything longer should probably be made into its own function. I'd also say that a private function should only have one purpose for existence. Performing a calculation and then opening a file is too much functionality for a single private function to have.

The rest of the chapter is devoted to showing you some of the built-in function of Perl. These little nuggets of functionality will become part of your arsenal of programming weapons.

String Functions

The first set of functions that we'll look at are those that deal with strings. These functions let you determine a string's length, search for a sub-string, and change the case of the characters in the string, among other things. Table 5.1 shows Perl's string functions.

Table 5.1-String Functions
Function Description
chomp(STRING) OR chomp(ARRAY) Uses the value of the $/ special variable to remove endings from STRING or each element of ARRAY. The line ending is only removed if it matches the current value of $/.
chop(STRING) OR chop(ARRAY) Removes the last character from a string or the last character from every element in an array. The last character chopped is returned.
chr(NUMBER) Returns the character represented by NUMBER in the ASCII table. For instance, chr(65) returns the letter A.
crypt(STRING1, STRING2) Encrypts STRING1. Unfortunately, Perl does not provide a decrypt function. This function is not supported under the Windows operating systems.
index(STRING, SUBSTRING, POSITION) Returns the position of the first occurrence of SUBSTRING in STRING at or after POSITION. If you don't specify POSITION, the search starts at the beginning of STRING.
join(STRING, ARRAY) Returns a string that consists of all of the elements of ARRAY joined together by STRING. For instance, join(">>", ("AA", "BB", "CC")) returns "AA>>BB>>CC".
lc(STRING) Returns a string with every letter of STRING in lowercase. For instance, lc("ABCD") returns "abcd".
lcfirst(STRING) Returns a string with the first letter of STRING in lowercase. For instance, lcfirst("ABCD") returns "aBCD".
length(STRING) Returns the length of STRING.
ord(STRING) Returns the ascii value of the first character of STRING. If STRING is omitted, then $_ is used. For instance, ord("ABC") returns the number 65.
Errata Note
This function has been added to the list after the printed version was completed. Its utility as a string function was initially overlooked. Randal Schwartz was kind enough to mention that it should be added.
rindex(STRING, SUBSTRING, POSITION) Returns the position of the last occurrence of SUBSTRING in STRING at or before POSITION. If you don't specify POSITION, the search starts at the end of STRING.
split(PATTERN, STRING, LIMIT) Breaks up a STRING using PATTERN as the delimiter. The LIMIT parameter indicates how many parts to create from STRING. In an array context, it returns a list of the parts that were found. In a scalar context, the number of parts found.
substr(STRING, OFFSET, LENGTH) Returns a portion of STRING as determined by the OFFSET and LENGTH parameters. If LENGTH is not specified, then everything from OFFSET to the end of STRING is returned. A negative OFFSET can be used to start from the right side of STRING.
uc(STRING) Returns a string with every letter of STRING in uppercase. For instance, uc("abcd") returns "ABCD".
ucfirst(STRING) Returns a string with the first letter of STRING in uppercase. For instance, ucfirst("abcd") returns "Abcd".

Note
As a general rule, if Perl sees a number where it expects a string, the number is quietly converted to a string without your needing to do anything.

Some of these functions use the special variable $_ as the default string to work with. More information about $ can be found in Chapter 9, "Using Files," and Chapter 12, "Using Special Variables."

The next few sections demonstrate some of these functions. After seeing some of them work, you'll be able to use the rest of them.

Example: Changing a String's Value

Frequently, I find that I need to change part of a string's value, usually somewhere in the middle of the string. When this need arises, I turn to the substr() function. Normally, the substr() function returns a sub-string based on three parameters: the string to use, the position to start at, and the length of the string to return.

Pseudocode

Assign $firstVar the return value from substr().

Print $firstVar.

$firstVar = substr("0123BBB789", 4, 3);
print("firstVar  = $firstVar\n");
This program prints:
firstVar = BBB
The substr() function starts at the fifth position and returns the next three characters. The returned string can be used for assignment like the above example, as an array element, for string concatention or any of a hundred other options.

Things become more interesting when you put the substr() function on the left-hand side of the assignment statement. Then, you can actually assign a value to the string that substr() returns.

Pseudocode

Initialize $firstVar with a string literal.

Replace the string returned by the substr() function with "AAA".

Print $firstVar.

$firstVar = "0123BBB789";
substr($firstVar, 4, 3) = "AAA";
print("firstVar  = $firstVar\n");
This program prints:
firstVar = 0123AAA789

Example: Searching a String

Another useful thing you can do with strings is search them to see if they contain a given sub-string. For example if you have a full path name such as "C:\\WINDOWS\\TEMP\\WSREWE.DAT", you might need to extract the file name at the end of the path. You might do this by searching for the last backslash and then using substr() to return the sub-string.

Note
The path name string has double-backslashes to indicate to Perl that we really want a backslash in the string and not some other escape sequence. You can read more about escape sequences in Chapter 2, "Numeric and String Literals."

Pseudocode

Assign a string literal to $pathName.

Find the location of the last backslash by starting at the end of the string and working backward using the rindex() function. When the position of the last backslash is found, add one to it so that $position points at the first character ("W") of the filename.

Use the substr() function to extract the filename and assign it to $fileName.

Print $fileName.

$pathName = "C:\\WINDOWS\\TEMP\\WSREWE.DAT";
$position = rindex($pathName, "\\") + 1;
$fileName = substr($pathName, $position);
print("$fileName\n");
This program prints:
WSREWE.DAT
If the third parameter - the length - is not supplied to substr(), it simply returns the sub-string that starts at the position specified by the second parameter and continues until the end of the string specified by the first parameter.

Array Functions

Arrays are a big part of the Perl language and it has a lot of functions to help you work with them. Some of the actions they perform include deleting elements, checking for the existence of an element, reversing all of the the elements in an array, and sorting the elements. Table 5.2 lists the functions you can use with arrays.

Table 5.2-Array Functions
Function Description
defined(VARIABLE) returns true if VARIABLE has a real value and false if the variable has not yet been assigned a value. This is not limited to arrays, any data type can be checked. Also see the exists function for information about associative array keys.
delete(KEY) Removes the key-value pair from the given associative array. If you delete a value from the %ENV array the environment of the current process is changed, not that of the parent.
each(ASSOC_ARRAY) Returns a two-element list that contains a key and value pair from the given associative array. The function is mainly used so that you can iterate over the associate array elements. A null list is returned when the last element has been read.
exists(KEY) Returns true if the KEY is part of the specified associative array. For instance, exists($array{"Orange"}) returns true if the %array associative array has a key with the value of "Orange."
join(STRING, ARRAY) Returns a string that consists of all of the elements of ARRAY joined together by STRING. For instance, join(">>", ("AA", "BB", "CC")) returns "AA>>BB>>CC".
keys(ASSOC_ARRAY) Returns a list that holds all of the keys in a given associative array. The list is not in any particular order.
map(EXPRESSION, ARRAY) Evaluates EXPRESSION for every element of ARRAY. The special variable $_ is assigned each element of ARRAY immediately before EXPRESSION is evaluated.
pack(STRING, ARRAY) Creates a binary structure, using STRING as a guide, of the elements of ARRAY. You can look in Chapter 8, "References," for more information.
pop(ARRAY) Returns the last value of an array. It also reduces the size of the array by one.
push(ARRAY1, ARRAY2) Appends the contents of ARRAY2 to ARRAY1. This increases the size of ARRAY1 as needed.
reverse(ARRAY) Reverses the elements of a given array when used in an array context. When used in a scalar context, the array is converted to a string, and the string is reversed.
scalar(ARRAY) Evaluates the array in a scalar context and returns the number of elements in the array.
shift(ARRAY) Returns the first value of an array. It also reduces the size of the array by one.
sort(ARRAY) Returns a list containing the elements of ARRAY in sorted order. See Chapter 8, "References," for more information.
splice(ARRAY1, OFFSET, LENGTH, ARRAY2) Replaces elements of ARRAY1 with elements in ARRAY2. It returns a list holding any elements that were removed. Remember that the $[ variable may change the base array subscript when determining the OFFSET value.
split(PATTERN, STRING, LIMIT) Breaks up a string based on some delimiter. In an array context, it returns a list of the things that were found. In a scalar context, it returns the number of things found.
undef(VARIABLE) Slways returns the undefined value. In addition, it undefines VARIABLE which must be a scalar, an entire array or a subroutine name.
unpack(STRING, ARRAY) Does the opposite of pack().
unshift(ARRAY1, ARRAY2) Adds the elements of ARRAY2 to the front of ARRAY1. Note that the added elements retain their original order. The size of the new ARRAY1 is returned.
values(ASSOC_ARRAY) Returns a list that holds all of the values in a given associative array. The list is not in any particular order.

As I did with the string functions, only a few of these functions will be explored. Once you see the examples, you'll be able to handle the rest with no trouble.

Example: Printing an Associative Array

The each() function returns key, value pairs of an associative array one-by-one in a list. This is called iterating over the elements of the array. Iteration is a synonym for looping. So you could also say that the each() function starts at the beginning of an array and loops through each element until the end of the array is reached. This ability lets you work with key, value pairs in a quick easy manner.

The each() function does not loop by itself. It needs a little help from some Perl control statements. For this example, we'll use the while loop to print an associative array. The while (CONDITION) {} control statement continues to execute any program code surrounded by the curly braces until the CONDITION turns false.

Pseudocode

Create an associative with number, color pairs.

Using a while loop, iterate over the array elements.

Print the key, value pair.

%array = ( "100", "Green", "200", "Orange");

while (($key, $value) = each(%array)) {
    print("$key = $value\n");
}
This program prints:
100 = Green
200 = Orange
The each() function returns false when the end of the array is reached. Therefore, you can use it as the basis of the while's condition. When the end of the array is reached, the program continues execution after the closing curly brace. In this example, the program simply ends.

Example: Checking the Existence of an Element

You can use the defined() function to check if an array element exists before you assign a value to it. This ability is very handy if you are reading values from a disk file and don't want to overlay values already in memory. For instance, suppose you have a disk file of customers' addresses and you'd like to know if any of them are duplicates. You check for duplicates by reading the information one address at a time and assigning the address to an associative array using the customer name as the key value. If the customer name already exists as a key value, then that address should be flagged for follow-up.

Since we haven't talked about disk files yet, we'll need to emulate a disk file with an associative array. And instead of using customer's address, we'll use customer number, customer name pairs. First, we see what happens when an associative array is created and two values have the same keys.

Pseudocode

Call the createPair() function three times to create three key, value pairs in the %array associative array.

Loop through %array, printing each key, value pair.

Define the createPair() function.

Create local variables to hold the key, value pair passed as parameters.

Create an array element to hold the key, value pair.

createPair("100",  "Kathy Jones");
createPair("200",  "Grace Kelly");
createPair("100", "George Orwell");

while (($key, $value) = each %array) {
    print("$key, $value\n");
};

sub createPair{
    my($key, $value) = @_;

    $array{$key} = $value;
};
This program prints
100, George Orwell
200, Grace Kelly
This example takes advantages of the global nature of variables. Even though the %array element is set in the createPair() function, the array is still accessible by the main program. Notice that the first key, value pair (100 and Kathy Jones) are overwritten when the third key, value pair is encountered. You can see that it is a good idea to be able to determine when an associative array element is already defined so that duplicate entries can be handled. The next program does this.

Pseudocode

Call the createPair() function three times to create three key, value pairs in the %array associative array.

Loop through %array, printing each key, value pair.

Define the createPair() function.

Create local variables to hold the key, value pair passed as parameters.

If the key, value pair already exists in %array then increment the customer number by one. Check to see if the new key, value pair exists. If so, keep incrementing until a non-existent key, value pair is found.

Create an array element to hold the key, value pair.

createPair("100",  "Kathy Jones");
createPair("200",  "Grace Kelly");
createPair("100", "George Orwell");

while (($key, $value) = each %array) {
    print("$key, $value\n");
};

sub createPair{
    my($key, $value) = @_;

    while (defined($array{$key})) {
        $key++;
    }

    $array{$key} = $value;
};
This program prints:
100, Kathy Jones
101, George Orwell
200, Grace Kelly
You can see the customer number for George Orwell has been changed to 101. If the array had already had an entry for 101, the George Orwell' new customer number would be 102.

Summary

In this chapter you've learned about functions - what they are and how to call them. You saw that you can create your own function or use one of Perl's many built-in functions. Each function can accept any number of parameters which get delivered to the function in the form of the @_ array. This array, like any other array in Perl, can be accessed using the array element to access individual element (For instance, $_[0] accesses the first element in the @_ array.). Because Perl parameters are passed by reference, changing the @_ array changes the values in the main program as well as the function.

You learned about the scope of variables and how all variables are global by default. Then, you saw how to create variable with local scope using local() and my(). My() is the better choice in almost all situations because it enforces local scope and limits side effects from function to inside the functions.

Then you saw that it was possible to nest function calls which means that one function can call another which in turn can call another. You might also call this a chain of function calls. Private functions were introduced next. A private function is one that can only be used inside the function that defines it.

A list of string functions was then presented. These included functions to remove the last character, encrypt a string, find a sub-string, convert array elements into a string, change the case of a string characters, and find the length of a string. Examples were shown about how to change a string's characters and how to search a string.

The section on array functions showed that Perl has a large number of functions that deal specifically with arrays. The list of functions included the ability to delete elements, return key and value pairs from associative arrays, reverse an array's elements, and sort an array. Examples were shown for printing an associative array and checking for the existence of an element.

The next chapter, "Statements," goes into detail about what statements are and how you create them. The information that you learned about variables and functions will come into play. You'll see how to link variables and functions together to form expressions and statements.

Review Questions

  1. What is a parameter?

  2. What two functions are used to create variables with local scope?

  3. What does parameter passing by reference mean?

  4. What is the @_ array used for?

  5. Do Perl variables have global or local scope by default?

  6. Why is it hard to pass two arrays to a function?

  7. What is the difference between variables created with local() and variables created with my()?

  8. What does the map() function do?

Review Exercises

  1. Create a function that prints its own parameter list.

  2. Create a program that uses three functions to demonstrate function call nesting.

  3. Use the chop() function in a program. Print both the returned character and the string that was passed as a parameter.

  4. Run the following program to see how many levels of recursion your system configuration supports.
    firstSub();
    
    sub firstSub{
        print("$count\n");
        $count++;
        firstSub();
    }
  5. Write a function that uses the substr() and uc() functions to change the tenth through twenthieth characters to uppercase.

  6. Write a function that uses the keys() function to print out the values of an associative array.

  7. Create a program that uses a private function to subtract two numbers and multiply the result by four.

  8. Write a program that shows what the shift() and unshift() functions do.

  9. Write a program that shows what the push() and pop() functions do.

Top of Page | Sections | Chapters | Copyright