5.2. Scalars, Arrays, and Hashes
Now that we have discussed the basics of Perl variables (types, visibility, funny characters, etc.), we can look at them in more detail and without (or, should I say, with less) confusion about the quoting mechanism and how quoting affects variable interpretation.
5.2.1. Scalar Variables
Scalar variables hold a single number or string and are preceded by a dollar sign ($). Perl scalars need a preceding dollar sign whenever the variable is referenced, even when the scalar is being assigned a value. If you are familiar with shell programs, using the dollar sign when making assignments may seem a little strange at first.
Assignment
When making an assignment, the value on the right-hand side of the equal sign is evaluated as a single value (i.e., its context is scalar). A quoted string, then, is considered a single value even if it contains a number of words.
Example 5.6.
1 $number = 150;
2 $name = "Jody Savage";
3 $today = localtime();
The numeric literal, 150, is assigned to the scalar variable $number. The string literal Jody Savage is assigned to the scalar $name as a single string. The output of Perl's localtime function will be assigned as a string to $today.
|
Curly Braces
If a scalar variable is surrounded by curly braces ({}), the scalar is shielded from any characters that may be appended to the variable.
Example 5.7.
(The Script)
1 $var="net";
2 print "${var}work\n";
(Output)
2 network
The value net is assigned to the scalar variable $var. The curly braces surrounding the variable insulate it from the string work that has been appended to it. Without the curly braces, nothing would be printed, because a variable called $varwork has not been defined. You could also concatenate the two strings with the dot operator; e.g.,
|
Example 5.8.
(The Script)
# Initializing scalars and printing their values
1 $num = 5;
2 $friend = "John Smith";
3 $money = 125.75;
4 $now = localtime(); # localtime() is a Perl function
5 $month="Jan";
6 print "$num\n";
7 print "$friend\n";
8 print "I need \$$money.\n"; # Protecting our money
9 print qq/$friend gave me \$$money.\n/;
10 print qq/The time is $now\n/;
11 print "The month is ${month}uary.\n"; # Curly braces shield
# the variable
12 print "The month is $month" . "uary.\n"; # Concatenate
(Output)
6 5
7 John Smith
8 I need $125.75.
9 John Smith gave me $125.75.
10 The time is Sat Jan 24 16:12:49 2007.
11 The month is January.
12 The month is January.
The scalar $num is assigned the numeric literal, 5. The scalar $friend is assigned the string literal, John Smith. The scalar $money is assigned the numeric floating point literal, 125.75. The scalar $now is assigned the output of Perl's localtime() function. The scalar $month is assigned Jan. The value of the scalar $num is printed. The value of the scalar $friend is printed. The quoted string is printed. The backslash allows the first dollar sign ($) to be printed literally; the value of $money is interpolated within double quotes, and its value printed. The Perl qq construct replaces double quotes. The string to be quoted is enclosed in forward slashes. The value of the scalar $friend is interpolated; a literal dollar sign precedes the value of the scalar interpolated variable, $money. The quoted string is printed. The $now variable is interpolated. Curly braces can be used to shield the variable from characters that are appended to it. January will be printed. You can also join two strings together with the dot operator (see Chapter 6), called concatenation.
|
The defined Function
If a scalar has neither a valid string nor a valid numeric value, it is undefined. The defined function allows you to check for the validity of a variable's value. It returns 1 if the variable has a value and null if it does not. The function is also used to check the validity of arrays, subroutines, and null strings.
Example 5.9.
$name="Tommy";
print "OK \n" if defined $name;
|
The undef Function
This function undefines an already defined variable. It releases whatever memory that was allocated for the variable. The function returns the undefined value. This function also releases storage associated with arrays and subroutines.
Example 5.10.
The $_ Scalar Variable
The $_ is a ubiquitous little character. Although it is very useful in Perl scripts, it is often not seen. It is used as the default pattern space for searches and to hold the current line. Once a value is assigned to $_, functions such as chomp, split, and print will use $_ as an argument. You will learn more about functions and their arguments later, but for now, consider the following example:
Example 5.11.
1 $_ = "Donald Duck";
2 print; # The value of $_ is printed
Donald Duck
The $_ scalar variable is assigned the string "Donald Duck". The print function has been given nothing to print, so it will print $_, the default if no other string is given.
|
5.2.2. Arrays
When you have a collection of similar data elements, it is easier to use an array than to create a separate variable for each of the elements. The array name allows you to associate a single variable name with a list of data elements. Each of the elements in the list is referenced by its name and a subscript (also called an index).
Perl, unlike C-like languages, doesn't care whether the elements of an array are of the same data type. They can be a mix of numbers and strings. To Perl, an array is a named list containing an ordered set of scalars. The name of the array starts with an @ sign. The subscript follows the array name and is enclosed in square brackets ([]). Subscripts are simply integers and start at zero.
Assignment
If the array is initialized, the elements are enclosed in parentheses, and each element is separated by a comma. The list is parenthesized due to the lower precedence of the comma operator over the assignment operator. Elements in an array are simply scalars.
Perl 5 introduced the qw construct for creating a list (similar to qq, q, and qx). The items in the list are treated as singly quoted words.
$pal = "John"; # Scalar holds one value
@pals = ( "John", "Sam", "Nicky", "Jake" ); # Array holds a list of values
Example 5.12.
1 @name=("Guy", "Tom", "Dan", "Roy");
2 @list=(2..10);
3 @grades=(100, 90, 65, 96, 40, 75);
4 @items=($a, $b, $c);
5 @empty=();
6 $size=@items;
7 @mammals = qw/dogs cats cows/;
8 @fruit = qw(apples pears peaches);
The array @name is initialized with a list of four string literals. The array @list is assigned numbers ranging from 2 through 10. (See Example 5.14.) The array @grades is initialized with a list of six numeric literals. The array @items is initialized with the values of three scalar variables. The array @empty is assigned a null list. The array @items is assigned to the scalar variable $size. The value of the scalar is the number of elements in the array (in this example, 3). The qw (quote word) construct is followed by a delimiter of your choice. Each word in the list is treated as a singly quoted word. The list is terminated with a closing delimiter. This example could be written: @mammals = ( 'cats', 'dogs', 'cows' ); The qw construct accepts paired characters ( ), { },< >, and [ ], as optional delimeters.
|
Special Scalars and Array Assignment
The special scalar variable $#arrayname returns the number of the last subscript in the array. Since the array subscripts start at zero, this value is one less than the array size. The $#arrayname variable can also be used to shorten or truncate the size of the array.
The $[ variable is the current array base subscript, zero. Its value can be changed so that the subscript starts at 1 instead of 0, but changing this value is discouraged by Larry Wall.
Example 5.13.
1 @grades = (90,89,78,100,87);
print "The original array is: @grades\n";
2 print "The number of the last index is $#grades\n";
3 $#grades=3;
print "The array is truncated to 4 elements: @grades\n";
4 @grades=();
print "The array is completely truncated: @grades\n";
(Output)
The original array is: 90 89 78 100 87
The number of the last index is 4
The array is truncated to 4 elements: 90 89 78 100
The array is completely truncated:
The array @grades is assigned a list of five numbers. The $# construct gets the subscript (index) value of the last element in the array. The last subscript in the array has been shortened to 3. Using an empty list causes the array to be completely truncated to an empty list.
|
The Range Operator and Array Assignment
The .. operator, called the range operator, when used in an array context, returns an array of values starting from the left value to the right value, counting by ones.
Example 5.14.
1 @digits=(0 .. 10);
2 @letters=( 'A' .. 'Z' );
3 @alpha=( 'A' .. 'Z', 'a' .. 'z' );
4 @n=( -5 .. 20 );
The array @digits is assigned a list of numbers, 0 through 10. The array @letters is assigned a list of capital letters, A through Z. The array @alpha is assigned a list of uppercase and lowercase letters. The array @n is assigned a list of numbers, –5 through 20.
|
Accessing Elements
To reference the individual elements in an array, each element is considered a scalar (preceded by a dollar sign), and the subscripts start at zero. The subscripts are positive whole numbers. For example, in the array @names, the first element in the array is $name[0], the next element is $name[1], and so forth.
Example 5.15.
Code View: (The Script)
# Populating an array and printing its values
1 @names=('John', 'Joe', 'Jake'); # @names=qw/John Joe Jake/;
2 print @names, "\n"; # prints without the separator
3 print "Hi $names[0], $names[1], and $names[2]!\n";
4 $number=@names; # The scalar is assigned the number
# of elements in the array
5 print "There are $number elements in the \@names array.\n";
6 print "The last element of the array is $names[$number - 1].\n";
7 print "The last element of the array is $names[$#names].\n";
# Remember, the array index starts at zero!!
8 @fruit = qw(apples pears peaches plums);
9 print "The first element of the \@fruit array is $fruit[0];
the second element is $fruit[1].\n";
10 print "Starting at the end of the array; @fruit[-1, -3]\n";
(Output)
2 JohnJoeJake
3 Hi John, Joe, and Jake!
5 There are 3 elements in the @names array.
6 The last element of the array is Jake.
7 The last element of the array is Jake.
9 The first element of the @fruit array is apples; the second element is pears.
10 Starting at the end of the array: plums pears
The @names array is initialized with three strings: John, Joe, and Jake. The entire array is printed to STDOUT. The space between the elements is not printed. Each element of the array is printed, starting with subscript number zero. The scalar variable $number is assigned the array @names. The value assigned is the number of elements in the array @names. The number of elements in the array @names is printed. The last element of the array is printed. Since subscripts start at zero, the number of elements in the array decremented by one evaluates to the number of the last subscript. The last element of the array is printed. The $#names value evaluates to the number of the last subscript in the array. This value used as a subscript will retrieve the last element in the @names array. The qw construct allows you to create an array of singly quoted words without enclosing the words in quotes or separating the words with commas. The delimiter is any pair of nonalphanumeric characters. (See "Perl's Alternative Quotes" on page 75.) The first two elements of the @fruit array are printed. With a negative offset as a subscript, the elements of the array are selected from the end of the array. The last element ($fruit[-1]) is plums, and the third element from the end ($fruit[-3]) is pears. Note that when both index values are within the same set of brackets, as in @fruit[-1,-3], the reference is to a list, not a scalar; that is why the @ symbol precedes the name of the array, rather than the $.
|
Array Slices
When the elements of one array are assigned the values from another array, the resulting array is called an array slice.
If the array on the right-hand side of the assignment operator is larger than the array on the left-hand side, the unused values are discarded. If it is smaller, the values assigned are undefined. As indicated in the following example, the array indices in the slice do not have to be consecutively numbered; each element is assigned the corresponding value from the array on the right-hand side of the assignment operator.
Example 5.16.
(The Script)
# Array slices
1 @names=('Tom', 'Dick', 'Harry', 'Pete' );
2 @pal=@names[1,2,3]; # slice -- @names[1..3] also O.K.
3 print "@pal\n\n";
4 ($friend[0], $friend[1], $friend[2])=@names; # Array slice
5 print "@friend\n";
(Output)
3 Dick Harry Pete
5 Tom Dick Harry
The array @names is assigned the elements 'Tom', 'Dick', 'Harry', and 'Pete'. The array @pal is assigned the elements 1, 2, and 3 of the @names array. The elements of the @names array are sliced out and stored in the @pal array. The @friend array is created by taking a slice from the @names array; i.e., elements 0, 1, and 2.
|
Example 5.17.
Code View: (The Script)
# Array slices
1 @colors=('red','green','yellow','orange');
2 ($c[0], $c[1],$c[3], $c[5])=@colors; # The slice
3 print "**********\n";
4 print @colors,"\n"; # Prints entire array, but does
# not separate elements quoted
5 print "@colors,\n"; # Prints the entire array with
# elements separated
6 print "**********\n";
7 print $c[0],"\n"; # red
8 print $c[1],"\n"; # green
9 print $c[2],"\n"; # undefined
10 print $c[3],"\n"; # yellow
11 print $c[4],"\n"; # undefined
12 print $c[5],"\n"; # orange
13 print "**********\n" ;
14 print "The size of the \@c array is ", $#c + 1,".\n";
(Output)
3 **********
4 redgreenyelloworange
5 red green yellow orange
6 **********
7 red
8 green
9
10 yellow
11
12 orange
13 **********
14 The size of the @c array is 6.
The array @colors is assigned the elements 'red', 'green', 'yellow', and 'orange'. An array slice is created, consisting of four scalars, $c[0], $c[1], $c[3], and $c[5]. Note: The subscripts in the array slice are not numbered sequentially. A row of stars is printed, just for clarity. The elements are not separated when printed. When the array is enclosed in double quotes, the whitespace between elements is preserved. Another row of stars is printed. The first element of the array slice, red, is printed. The second element of the array slice, green, is printed. The third element of the array slice is undefined. Its value is null because it was not assigned a value. The fourth element of the array slice, yellow, is printed. The fifth element of the array slice is undefined. The sixth element of the array slice, orange, is printed. Another row of stars is printed. Even though some of the elements of the @c array are undefined, the size of the array indicates that the elements exist.
|
Multidimensional Arrays—Lists of Lists
Multidimensional arrays are sometimes called tables, or matrices. They consist of rows and columns and can be represented with multiple subscripts. In a two-dimensional array, the first subscript represents the row, and the second subscript represents the column.
In Perl, each row in a two-dimensional array is enclosed in square brackets. The row is an unnamed list. An unnamed list is called an anonymous array and contains its own elements. The arrow operator, also called an infix operator, can be used to get the individual elements of an array. There is an implied –> between adjacent brackets. (Anonymous variables will be discussed in detail in Chapter 13, "Does This Job Require a Reference?")
Example 5.18.
Code View: (The Script)
# A two-dimensional array consisting of 4 rows and 3 columns
1 @matrix=( [ 3 , 4, 10 ], # Each row is an unnamed list
[ 2, 7, 12 ],
[ 0, 3, 4 ],
[ 6, 5, 9 ],
) ;
2 print "@matrix\n";
3 print "Row 0, column 0 is $matrix[0][0].\n";
# can also be written - $matrix[0]->[0]
4 print "Row 1, column 0 is $matrix[1][0].\n";
# can also be written - $matrix[1]->[0]
5 for($i=0; $i < 4; $i++){
6 for($x=0; $x < 3; $x++){
7 print "$matrix[$i][$x] ";
}
print "\n";
}
(Output)
2 ARRAY(0xbf838) ARRAY(0xc7768) ARRAY(0xc77a4) ARRAY(0xc77e0)
3 Row 0, column 0 is 3.
4 Row 1, column 0 is 2.
7 3 4 10
2 7 12
0 3 4
6 5 9
The array @matrix is assigned four unnamed, or anonymous, arrays. Each of the arrays has three values. The addresses of the four anonymous arrays are printed. To access the individual elements of an anonymous array, double subscripts or the arrow operator must be used. The first element of the first anonymous array in the @matrix array is printed. The –> is called the arrow, or infix, operator. It is used to dereference array and hash references. $matrix[0][0] or $matrix[0]–>[0] is the first element of the first row, where subscripts start at zero. The second row, first element of the @matrix, is printed. $matrix[1]–>[0] is another way to say $matrix[1][0]. The outer for loop will iterate through each of the rows, starting at row zero. After the first iteration of the loop, the second for loop is entered. The inner for loop iterates faster than the outer loop. Each element of a row is printed, and then control returns to the outer for loop. Print each element in the matrix. The first index represents the row, and the second index represents the column.
|
5.2.3. Hashes
An associative array, more commonly called a hash, consists of one or more pairs of scalars — strings, numbers, or Booleans. The first set of scalars is associated with the second set of scalars. The first string in the pair of strings is called the key, and the second string is called the value. Whereas arrays are ordered lists with numeric indices starting at 0, hashes are unordered lists with string indices randomly distributed. (When you print out the hash, don't expect to see the output ordered just as you typed it!)
Hashes, then, are defined as an unordered list of key/value pairs, similar to a table where the keys are on the left-hand side and the values associated with those keys are on the right-hand side. The name of the hash is preceded by the %.
% pet = ( "Name" => "Sneaky",
"Type" => "Cat",
"Owner" => "Carol",
"Color" => "yellow",
);
keys | values |
---|
"Name" | "Sneaky |
"Type" | "Cat" |
"Owner" | "Carol" |
"Color" | "yellow" |
Hash Table |
Assignment
A hash must be defined before the elements can be referenced. Since a hash consists of pairs of values, indexed by the first element of each pair, if one of the elements in a pair is missing within the array definition, the association of the keys and their respective values will be affected. When assigning keys and values, make sure you have a key associated with its corresponding value. When indexing a hash, curly braces are used instead of square brackets.
Example 5.19.
1 %seasons=("Sp" => "Spring",
"Su" => "Summer",
"F" => "Fall",
"W" => "Winter",
);
2 %days=("Mon" => "Monday",
"Tue" => "Tuesday",
"Wed" => undef,
);
3 $days{"Wed"}="Wednesday";
4 $days{5}="Friday";
The hash %seasons is assigned keys and values. Each key and value is separated by the digraph operator, =>. The string Sp is the key with a corresponding value of Spring; the string Su is the key for its corresponding value Summer, etc. It is not necessary to quote the key if it is a single word. The hash %days is assigned keys and values. The third key, Wed, is assigned undef. The undef function evaluates to a null string. Individual elements of a hash are scalars. The key Wed is assigned the string value Wednesday. The index is enclosed in curly braces. The key 5 is assigned the string value Friday. Note: the keys do not have any consecutive numbering order, and the pairs can consist of numbers and/or strings.
|
Accessing Elements
When accessing the values of a hash, the subscript consists of the key enclosed in curly braces. Perl provides a set of functions to list the keys, values, and each of the elements of the hash. (See "Array Functions" on page 100.)
Due to the internal hashing techniques used to store the keys, Perl does not guarantee the order in which an entire hash is printed.
Example 5.20.
Code View: (The Script)
# Assigning keys and values to a hash
1 %department = (
"Eng" => "Engineering",
"M" => "Math",
"S" => "Science",
"CS" => "Computer Science",
"Ed" => "Education",
3 );
4 $department = $department{'M'}; # Either single or double quotes
# ok for the keys
5 $school = $department{'Ed'};
6 print "I work in the $department section\n" ;
7 print "Funds in the $school department are being cut.\n";
8 print qq/I'm currently enrolled in a $department{'CS'} course.\n/;
9 print qq/The department hash looks like this:\n/;
10 print %department, "\n"; # The printout is not in the expected
# order due to internal hashing
(Output)
6 I work in the Math section
7 Funds in the Education department are being cut.
8 I'm currently enrolled in a Computer Science course.
9 The department hash looks like this:
10 SScienceCSComputer ScienceEdEducationMMathEngEngineering
The hash is called %department. It is assigned keys and values. The first key is the string Eng, and the value associated with it is Engineering. The closing parenthesis and semicolon end the assignment. The scalar $department is assigned Math, the value associated with the M key. The scalar $school is assigned Education, the value associated with the Ed key. The quoted string is printed; the scalar $department is interpolated. The quoted string is printed; the scalar $school is interpolated. The quoted string and the value associated with the CS key are printed. The quoted string is printed. The entire hash is printed, with keys and values packed together and not in the expected order.
|
Hash Slices
A hash slice is a list of hash keys whose corresponding values are assigned to another list of keys. The list consists of the hash name preceded by the @ symbol. The list of hash keys is enclosed in curly braces.
Example 5.21.
Code View: (The Script)
# Hash slices
1 %officer= ("NAME"=> "Tom Savage",
"SSN" => "510-22-3456",
"DOB" => "05/19/66"
);
2 @info=qw(Marine Captain 50000);
3 @officer{'BRANCH', 'TITLE', 'SALARY'}=@info;
# This is a hash slice
4 @sliceinfo=@officer{'NAME','BRANCH','TITLE'};
# This is also a hash slice
5 print "The new values from the hash slice are: @sliceinfo\n\n";
print "The hash now looks like this:\n";
6 foreach $key ('NAME', 'SSN', 'DOB', 'BRANCH', 'TITLE', 'SALARY'){
7 printf "Key: %-10sValue: %-15s\n", $key, $officer{$key};
}
(Output)
5 The new values from the hash slice are: Tom Savage Marine Captain
The hash now looks like this:
7 Key: NAME Value: Tom Savage
Key: SSN Value: 510-22-3456
Key: DOB Value: 05/19/66
Key: BRANCH Value: Marine
Key: TITLE Value: Captain
Key: SALARY Value: 50000
The hash %officer is assigned keys and values. The array @info is assigned three values. This is an example of a hash slice. The hash officer is assigned an array (@info) of values Marine, Captain, and 50000 to the corresponding keys, BRANCH, TITLE, SALARY. The name of the hash is prepended with an @ symbol because it is a list of keys that will receive its corresponding values from another list, @info. The hash slice is used in the assignment to create an array called @sliceinfo. The array will consist of the hash values associated with keys NAME, BRANCH, and TITLE. The values created by the hash slice are printed. The foreach loop is used to iterate through the list of keys. The keys and their corresponding values are printed. On line 3, the new key/value pairs were created by the slice.
|
5.2.4. Complex Data Structures
By combining arrays and hashes, you can make more complex data structures, such as arrays of hashes, hashes with nested hashes, arrays of arrays, etc. To create these structures, you should have an understanding of how Perl pointers are used. A few examples will be provided here as part of this topic, but a complete discussion of how to build complicated data structures is deferred until Chapter 13.
Hashes of Hashes
A hash can contain another hash. It is like a record that contains records. The nested hash has no name. It is an anonymous hash and can be dereferenced with the arrow operator. Each of the keys in the named hash contains a value, which is itself another hash. This anonymous hash consists of its own key/value pairs.
Example 5.22.
(The Script)
# Nested hashes
values
keys key value key value
1 %students=( "Math" => { "Joe" => 100, "Joan" => 95 },
"Science" => { "Bill" => 85, "Dan" => 76 }
);
2 print "On the math test Joan got ";
3 print qq/$students{Math}->{Joan}.\n/;
4 print "On the science test Bill got ";
5 print qq/$students{Science}->{Bill}.\n/;
(Output)
3 On the math test Joan got 95.
5 On the science test Bill got 85.
1 | The hash %students consists of two keys, Math and Science. The values associated with those keys are enclosed in curly braces. The value contains a set of nested keys and values. The value for the Math key contains two nested keys, Joe and Joan, with their respective values, 100 and 95. The value for the Science key contains two nested keys, Bill and Dan, with their respective values, 85 and 76. The nested keys and values are in an unnamed, or anonymous, hash. | 3 | The arrow (infix) operator, –>, allows you to access the anonymous nested hash value of the %students hash. |
|
Example 5.23.
(The Script)
# Anonymous arrays as keys in a hash
1 %grades=("Math" => [ 90, 100, 94 ],
"Science" => [ 77, 87, 86 ],
"English" => [ 65, 76, 99, 100 ],
);
2 print %grades, "\n";
3 print "The third math grade is: $grades{Math}->[2]\n";
4 print "All of the science grades are: @{$grades{Science}}\n";
(Output)
2 EnglishARRAY(0x8a65128)ScienceARRAY(0x8a650b0)MathARRAY(0x8a6f134)
3 The third math grade is: 94
4 All of the science grades are: 77 87 86
The hash %grades is assigned keys and values. The values are an unnamed list of numbers. Perl knows that this is an anonymous list because it is enclosed in square brackets. The anonymous arrays are stored at a memory location that can be accessed by using the arrow notation. The values of each key are printed as hexadecimal addresses preceded by the data type ARRAY stored at that location. The third element of the first list is retrieved by placing an arrow after the hash key, Math, that points to the index of the anonymous array. Since indices start at zero, $grades{Math}–>[2] references the third element of the array. To access the entire list of Science grades, the key/value pair is enclosed in curly braces and prepended with an @ symbol.
|
Array of Hashes
An array can contain nested hashes. It's like an array of records. Each of the elements of the array is an anonymous hash with a set of keys and corresponding values.
Example 5.24.
Code View: (The Script)
# An array of hashes
1 @stores=( { "Boss" =>"Ari Goldberg",
"Employees" => 24,
"Registers" => 10,
"Sales" => 15000.00,
},
2 { "Boss" =>"Ben Chien",
"Employees" => 12,
"Registers" => 5,
"Sales" => 3500.00,
},
);
3 print "The number of elements in the array: ",
4 $#stores + 1, "\n"; # The number of the last subscript + 1
5 for($i=0; $i< $#stores + 1; $i++){
6 print $stores[$i]->{"Boss"},"\n"; # Access an array element
print $stores[$i]->{"Employees"},"\n";
print $stores[$i]->{"Registers"},"\n";
print $stores[$i]->{"Sales"},"\n";
print "-" x 20 ,"\n";
}
(Output)
3 The number of elements in the array: 2
6 Ari Goldberg
24
10
15000
--------------------
Ben Chien
12
5
3500
--------------------
1 | The array @stores contains two anonymous hashes, one for Ari Goldberg's store and one for Ben Chien's store. Each of the elements of the array is a hash. | 2 | This is the second element of the @stores array. It is a hash. | 4 | $#stores evaluates to the number of the last subscript in the @stores array. Since subscripts start at 0, by adding 1 we get the number of elements in the array, which is 2. | 6 | To access a value in one of the elements of the array, first the number of the index is specified and then the key into the hash. The arrow operator is not required here, but it makes the program a little more readable. |
|