• Home   /  
  • Archive by category "1"

Perl Variable Declaration And Assignment

03 - Variables

In the last chapter, you learned about literals - values that don't change while your program runs because you represent them in your source code exactly as they should be used. Most of the time, however, you will need to change the values that your program uses. To do this, you need to set aside pieces of computer memory to hold the changeable values. And you need to keep track of where all these little areas of memory are so that you can refer to them while your program runs.

Perl, like all other computer languages, uses variables to keep track of the usage of computer memory. Every time you need to store a new piece of information, you assign it to a variable.

You've already seen how Perl uses numbers, strings, and arrays. Now, you'll see how to use variables to hold this information. Perl has three types of variables:

Variable Type Description
Scalars Holds one number or string value at a time. Scalar variable names always begin with a $.
Arrays Holds a list of values. The values can be numbers, strings, or even another array. Array variable names always begin with a @.
Associative Arrays Uses any value as an index into an array. Associative array variable names always begin with a %.

The different beginning characters help you understand how a variable is used when you look at someone else's Perl code. If you see a variable called @Value, you automatically know that it is an array variable.

They also provide a different namespace for each variable type. Namespaces separate one set of names from another. Thus, Perl can keep track of scalar variables in one table of names (or namespace) and array variables in another. This lets you use $name, @name, and %name to refer to different values.

I recommend against using identical variable names for different data types unless you have a very good reason to do so. And if you do need to use the same name, try using the plural of it for the array variable. For example, use $name for the scalar variable name and @names for the array variable name. This might avoid some confusion about what your code does in the future.
Variable names in Perl are case-sensitive. This means that $varname, $VarName, $varName, and $VARNAME all refer to different variables.

Each variable type will be discussed in its own section. You'll see how to name variables, set their values, and some of the uses to which they can be put.

Scalar Variables

Scalar variables are used to track single pieces of information. You'd use them to hold the title of a book, or the number of rooms in a house. You can use just about any name imaginable for a scalar variable as long as it begins with a $.
If you have programmed in Visual Basic, you need to be especially careful when naming variables. Just remember that all scalars begin with a $, not just strings, and that the $ starts the name; it doesn't end it.

Let's jump right in a look at some variable names.

$numberOfRooms $bookTitle $0

It is generally a good idea to stay away from short variable names. Longer variable names are more descriptive and aid in understanding programs.

Let me say a quick word about variable names. I always start my variable names with a lower case letter and then make the first letter of each "word" in the name upper case. Some programmers like to separate each word with an underscore. For example, $numberOfRooms would look like $number_of_rooms. Choose a method that you feel comfortable with and then stick with it. Being consistent will make your program more understandable.

Most programmers try to use descriptive names for their variables. There is no practical limit to the length of a Perl variable name, but I like to keep them under 15 characters. Anything longer than that means that it will take a while to type them and increases the chances of spelling errors.

Example: Assigning Values to Scalar Variables

Now that you know what scalar variable names look like, we'll look at how you can assign a value to them. Assigning values to a variable is done with the equals (=) sign.

$numberOfRooms = 23; $bookTitle = "Perl by Example";Notice that you are assigning literal values to the variables. After assigning the values you can then change them.

Changing Values in Scalar Variables

The next example will make a variable assignment and then change that variable's value using a second assignment. The second assignment will increment the value by five.

$numberOfRooms = 23; $numberOfRooms = $numberOfRooms + 5;

In Perl, you never have to declare, define, or allocate simple data types (for example: scalars, arrays, or associative arrays). When you use the variable for the first time, Perl either assigns it a zero if you need a number, or an empty list if you need an array. Using a variable name is equivalent to defining it.
Letting Perl automatically initialize variables is fine for small programs. However, if you write professional programs that need to be maintained, you'll want to explicitly declare variables using the my() function. Explicitly declaring functions will reduce errors and improve the internal documentation of your programs. The my() function is discussed in Chapter 5, "Functions."

Array Variables

You had a short introduction to arrays last chapter when you printed out entire arrays (with no spaces, remember?) using Perl's print statement. Now, you'll learn about arrays in more detail. Array variable names always begin with a @ character.
I remember that the @ sign starts array variables because "at" and "array" start with the same letter. Simple...but it works for me.

The rules for naming array variables are the same as those for scalar variables. There are no rules. Well, none that you need to worry about. In fact, let's skip looking at variable names and get right to assigning arrays to variables, instead.

Example: Assigning Values to Array Variables

You use the equals (=) sign to assign values to array variables just like scalar values.

We'll use one of the examples from Chapter 2, "Numeric and String Literals" - reworked a little - here so that you'll already be familiar with part of the example.

The printing of the newline character is separated from the printing of the array for a reason. It has to do with how Perl interprets variables in different contexts. If you tried to use print @numberArray . "\n"; Perl thinks that you want to use @numberArray in a scalar context and won't print the elements of the array. It will print the number of elements instead. See the section called "Example: Determine the Number of Elements in an Array" later in this chapter.

@emptyArray = (); @numberArray = (12, 014, 0x0c, 34.34, 23.3E-3); @stringArray = ("This", "is", 'an', "array", 'of', "strings"); @mixedArray = ("This", 30, "is", 'a', "mixed array", 'of', 0x08, "items"); print "Here is an empty array:" . @emptyArray . "<-- Nothing there!\n"; print @numberArray; print "\n"; print @stringArray; print "\n"; print @mixedArray; print "\n";

This program will display

Here is an empty array:0<-- Nothing there! 12121234.340.0233 Thisisanarrayofstrings This30isamixed arrayof8items

In this example, we assign literal values to array variables and then display them using the print command. This is very similar to what we did in Chapter 1, "Getting Your Feet Wet," except that we are temporarily storing the array values into variables before printing them.

Suppose that you want to create one array from two smaller ones. You can do this by using the sub-arrays inside the assignment statement.

@smallArrayOne = (5..10); @smallArrayTwo = (1..5); @largeArray = (@smallArrayOne, @smallArrayTwo); print @largeArray;When run, this program prints the array (5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5). Notice that the 5 is duplicated in the new array and that the elements are still in the same order as the sub-arrays. When you concatenate arrays in this manner, Perl does not sort them or modify their contents in any way.

Example: Using Array Elements

Individual elements of an array are accessed by prefixing the array name with a $ and using an index that indicates to Perl which element you want to use.

Listing 3.2 creates an array of five elements and then prints each individual element.


@array = (1..5); print @array; print "\n"; print $array[0]; print "\n"; print $array[1]; print "\n"; print $array[2]; print "\n"; print $array[3]; print "\n"; print $array[4]; print "\n";

Listing 3.2 will print the following:

12345 1 2 3 4 5Perl array indexes start at 0 - well, they actually start at $[ - but for the moment zero is good enough. Almost every Perl program uses zero as the base array subscript.

The special variable, $[, is used to hold the base array subscript; usually it is zero. However, it can be changed to any integer you want. Even negative ones. Using a negative base array subscript will probably make your programs hard to understand and I recommend against it. Other special variables are mentioned in Chapter 11, "Using Special Variables."

You can replace the numeric literal indexes in the above example with scalar variables. You can say:

$index = 2; @array = (1..5); print $array[$index]; print "\n";which would print 3.

Example: Using Negative Subscripts

Perl is definitely a language that will surprise you at times. In other languages, subscripts must be positive integers. However, Perl lets you use negative subscripts to access array elements in reverse order.
Using a negative subscript may come in handy if you need a fast way to get the value of the last element in an array.

The program in Listing 3.3 assigns a five element array to @array. Then, it uses print statement and negative subscripts to print each array element in reverse order.


@array = (1..5); print @array; print "\n"; print $array[-1]; print "\n"; print $array[-2]; print "\n"; print $array[-3]; print "\n"; print $array[-4]; print "\n"; print $array[-5]; print "\n";

Listing 3.3 will print the following:

12345 5 4 3 2 1

Example: Determining the Number of Elements in an Array

If you need to determine the number of elements that an array contains you can assign the array to a scalar variable.

In fact, any time that an array is used when a scalar is needed, the value used will be the number of array elements.

@array = (1..5); $numberOfElements = @array; $doubleTheSize = 2 * @array; print "The number of array elements is: " . $numberOfElements . "\n"; print "Double the number of array elements is: " . $doubleTheSize . "\n";When this program runs, it will assign a value of 5 to $numberOfElements and 10 to $doubleTheSize.

Perl has the powerful ability to return the number of array elements when the array variable is used in a scalar context. However, this ability can be confusing while looking at someone else's program if you don't remember that there is a difference between scalar contexts and array contexts.

Example: How to Grab a Slice (or Part) of An Array

At times you will need to use some elements of an array and not others. You might want to assign array elements to scalars or to another array. Using only part of an array is done with an array slice. An array slice uses an @ character and the square brackets ([]) to create a sub-array consisting of selected individual elements. For example,
Create a four element array and assign it to @array.
Use an array slice to assign the first and third elements to $first and $third.
Use an array slice to assign the second half of the array to @half.
Print @array, $first, $third and @half to verify their values.
Tranpose the first and last elements in @array.
Print @array to verify that the elements have been switched.

@array = ("One", "Two", "Three", "Four"); ($first, $third) = @array[0, 2]; @half = @array[2, 3]; print("\@array=@array\n"); print("\$first=$first \$third=$third\n"); print("\@half=@half\n"); @array[0, 3] = @array[3, 0]; print("\@array=@array\n");This program will display

@array=One Two Three Four $first=One $third=Three @half=Three Four @array=Four Two Three OneThe array elements are displayed separated by spaces because the array variable was enclosed in double quotes. The section, Example: Variable Interpolation discusses this issue in more detail. You won't really understand the power of array slices until you learn about functions in Chapter 5. At that point, you'll see that functions (sub programs that you invoke using a function name) can return a value. And that the return value might be an array. When calling a function that returns the time and date in an array, a slice can be used to "grab" just those elements that you are interested in. For example, just the year or just the hour.

Associative Array Variables

Now it's time to look at associative arrays. These are definitely the most complicated of the three data types. And yet, they are just another type of array. You've already seen that array elements can be accessed with both positive and negative integer indexes. Well, with associative arrays you can use any scalar data type as an index. Associative array names start with the % character.

You will see associative arrays called hashes at times. The term "Hash" refers to how associative array elements are stored in memory. "Hash" is also much shorter than "associative array" and therefore much easier to type and talk about.

Example: Assigning Values to Associative Array Variables

Before we discuss associative arrays further, let's see how to assign values to them. When defining a whole array, you can use the same representation that was used for arrays - just remember that you need two items for every element in the associative array. You can also assign values to individual elements of an associative array by using curly braces ({}) around the index key.

%associativeArray = ("Jack A.", "Dec 2", "Joe B.", "June 2", "Jane C.", "Feb 13"); $associativeArray{"Jennifer S."} = "Mar 20"; print "Joe's birthday is: " . $associativeArray{"Joe B."} . "\n"; print "Jennifer's birthday is: " . $associativeArray{"Jennifer S."} . "\n";This program will print the following:

Joe's birthday is: June 2 Jennifer's birthday is: Mar 20Perl will extend the associative array as needed when you assign values to keys. An internal table is used to keep track of which keys are defined. If you try to access an undefined key, Perl will return a null or blank string.

You can do a lot with associative arrays, but first you need more background in operators, functions, and statements. We'll handle these topics in future chapters. In the next section, we look at string literals and how they interact with variables.

Double Quoted Strings Revisited

Perl strings have some additional functionality that was not mentioned in Chapter 1, "Getting Your Feet Wet," because you needed to know a little about variables beforehand. Now that you are familiar with how Perl handles basic variables, let's look a little deeper at double quoted strings.

Example: Variable Interpolation

Interpolation is a big word for a simple concept - replacement of a variable name with its value.You already know that variable names are a "stand-in" for a value. If $var is equal to 10, the $var + 20 is really 10 + 20. In Perl, this concept is also used inside strings. You can combine variables and strings in a very natural way using Perl. Simply place the variable directly inside a double quoted string, and its value will be automatically be interpolated as needed.
Until this time, each time you printed an array all of the elements were mashed together (concatenated). Having the array element printed without delimiting spaces made determining the individual items very difficult. If, when printing, you enclose the array in quotes Perl will automatically separate the array elements with a space.

@array = (1..5); print "@array\n";This program will print:

1 2 3 4 5Perl runs into a problem when you want to use a variable and then append some letters to the end. Let's illustrate this with scalar variables.

$word = "large"; print "He was a $wordr fellow.";This program will print:

He was a fellow.In this example, Perl looks for the variable $wordr - obviously not what I intended to do. I meant for the string "He was a larger fellow" to print. This problem can be corrected by doing the following:

$word = "large"; print "He was a " . $word . "r fellow.";Because the variable is separate, Perl sees the correct variable name. Then the string concatenation operator joins the three strings together. This method of programming makes it very easy to see where the variable is.

Remember when I said that Perl enables you to do something in many different ways? You could also do the following:

print "He was a ${word}r fellow.";The curly braces around the variable name tell Perl where the name starts and ends.

If you're ever on IRC and see longhair_ or Kirby Hughes (khughes@netcom.com) tell him I said "thanks." He remembered that curly braces can be used in this manner.

Example: Using the $" Special Variable

Perl has a number of special variables. These variables each have a predefined meaning. Chapter 11, "Using Special Variables," introduces you to quite a few Perl special variables. However, since we were just looking at strings and array we should also spend a moment and talk about the $" special variable.

At times, you may need to print array elements separated by commas or another character. The $" variable controls which separator Perl uses when printing your array. The variable is normally set equal to the space character. However, you may set it to any characters you'd like.

$" = ","; @array = (1..5); print "@array\n";This program will print:

1,2,3,4,5Of course, since $" is a scalar variable you could also assign a longer string to it. For instance, you could use $" = ", " to add both a comma and a space between the array elements.

Summary

This chapter introduced you to the concept of variables - places in computer memory that are used to hold values as your program runs. They are called variables because you can assign different values to them as needed.

You read about three types of variables: Scalars, arrays, and associative arrays. Each variable type has its own unique character that is used to begin a variable names. Scalars use a $. Arrays use an @. And associative arrays use a %.

When I first started to learn Perl, I found it difficult to remember which character begins which variable type. Then, I saw this chart on the Internet and things became clearer:

$ = "the" (singular)

@ = "those" (plural)

% = "relationship"

Each variable type must start with a different character that uses a separate namespace. This means that $varName and @varName are different variables. Remember too that variable names in Perl are case-sensitive.

A lot of this chapter looked at assigning values to variables using the equal (=) sign. We also reviewed how to use positive and negative subscripts (such as $array[1]) to access array elements. Associative array elements are accessed a little differently, curly braces are used instead of square brackets (for example, $associativeArray{"Jack B."}).

And finally, we took another look at double quoted strings to see how variable interpolation works. You saw that Perl automatically replaces variables inside double quoted strings. When arrays are printed inside strings their elements are separated by the value of $" - which is usually a space.

Review Questions

  1. What are the three basic data types that Perl uses?
  2. How can you determine the number of elements in an array?
  3. What is a namespace?
  4. What is the special variable $[ used for?
  5. What is the special variable $" used for?
  6. What is the value of a variable when it is first used?
  7. What is an associative array?
  8. How can you access associative array elements?

Review Exercises

  1. Create a array called @months. It should have 12 elements in it with the names of the month represented as strings.
  2. Create a string that interpolates that value of the variable $numberOfBooks.
  3. Using the range operator (..) create an array with the following elements: 1, 5, 6, 7, 10, 11, 12.
  4. Using the array created in the last exercise, create a print command to display the last element.
  5. Create an associative array that holds a list of five music artists and a rating for them. Use "good," "bad," and "indifferent" as the ratings.
  6. Using the array created in the last exercise, create a print command to display the last element.

Top of Page | Sections | Chapters | Copyright

The trouble

Let's see first an example why is this important.

$l1 = 42; $ll++; print "$l1\n";

We assign 42 to a variable. Later we increment it by one, and then print it. Surprisingly the variable still contains 42.

The author might even know that he has to declare the variables using my so maybe the code looks like this:

my $l1 = 42; $ll++; print "$l1\n";

but the result is the same.

Now imagine that it is not in a 3 lines long example, but in a 1000 lines long script that you can find in many established places. You'd have a very hard time noticing that the auto-increment used the letter l twice, while the first and third rows had a variable with a letter and a number 1.

use strict

If we add a use strict requirement at the beginning of the file,

use strict; my $l1 = 42; $ll++; print "$l1\n";

we will get the following compile-time error message when we try to run the script:

Global symbol "$ll" requires explicit package name at ... line 6.

Seeing that error message isn't that clear either, at least not for the beginners, we'll see later where does it come from. In the meantime, if you are interested, you can read more about the error global symbol requires explicit package name.

In practical terms it means that you have not declared your variable $ll. Of course running to your editor and declaring my $ll won't do any good. You'll have to understand that this is actually a typo and the real variable name is $l1.

We might be still frustrated by the original developer who used a variable name that's hard to differentiate from a letter, but at least we don't spend hours banging our head against the wall.

The exceptions

As in any living languages (such as English and French) there are exceptions from the rules. In Perl too.

The variables $a and $b are special variables used in the sort function of Perl and, for historical reasons, are exempt from the requirement to declare them. I am not saying having such exceptions is a good thing, but it probably cannot be changed without breaking all the code written in the past 20+ years. So I'd strongly recommend never using $a and $b in any code except in connection to sort.

Not even in examples!

You can declare variables using our, use vars, and since 5.10 using state as well. They have different meaning though.

You can also access variables with their fully qualified name ($Person::name in the next example):

use 5.010; use strict; state $x = 42; say $x; our $y = 37; say $y; use vars qw($z); $z = 100; say $z; $Person::name = 'Foo'; say $Person::name;

And the output is

42 37 100 Foo

No warning, no error.

We used the explicit package name in the last example. That's, by-the-way where the error message (global symbol requires explicit package name) came from, but in the real world you rarely need that form. You are way better off always declaring your variables using my, and not using this "fully qualified" form of the variable.

The danger of the explicit package name

As use strict does not apply to the package variables, you can easily make a typo as I actually did when I wrote the first version of the example:

use 5.010; use strict; $Person::name = 'Foo'; say $Perlson::name;

and it printed nothing. No error. No warning. Nothing.

In general relying on fully qualified names can be dangerous. Of course they can be useful in some places, but we'll talk about that another time.

use warnings

Anyway, this brings me to the importance of the use warnings pragmata. If we used that too,

use 5.010; use strict; use warnings; $Person::name = 'Foo'; say $Perlson::name;

we would get the following run-time warnings:

Name "Person::name" used only once: possible typo at ... line 6. Name "Perlson::name" used only once: possible typo at ... line 7. Use of uninitialized value $Perlson::name in say at ... line 7.

Might not be the best solution, but at least we get some indication that something went wrong.

Even that warning can disappear if I am extremely bad at typing.

use 5.010; use strict; use warnings; $Perlson::name = 'Moo'; $Person::name = 'Foo'; $Person::name = 'Bar'; say $Perlson::name;

Here I made the exact same typo twice (maybe a copy paste?) and the result is

Moo

No error. No warning. Still incorrect behavior.

Always use strict

My conclusion is to always use strict by default.

In other articles you can read about symbolic references and barewords in Perl, the other two issues strict helps to avoid.

One of the 3 features of use strict which is also called use strict 'vars'; requires that you declare every variable before you use it. Well, sort of.

PrevNext

Comments

In the comments, please wrap your code snippets within <pre> </pre> tags and use spaces for indentation. comments powered by

One thought on “Perl Variable Declaration And Assignment

Leave a comment

L'indirizzo email non verrĂ  pubblicato. I campi obbligatori sono contrassegnati *