Understanding Values and Variables

Perl uses Duck-typing (if it quacks like a duck, it must be a duck) to determine data types. If you use a variable as a string, Perl will treat it as a string and so on.

It provides three basic types of storage, a scalar variable (defined with the $ symbol) which holds a single value, an array (defined with an @ symbol) or a hash (defined with a % symbol).

A hash is an unordered collection of key value pairs and is designed to be quick to access via a key and easy to sort and search.

References are very important in Perl. These are scalar variables that point to another object and make it possible to manage very complex data structures in Perl.

Numeric Variables

Consider the code shown in figure 11.

		1.	#!/usr/bin/perl
		2.	## numbers.pl by Philip Osztromok <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my $var = 42;
		8.	say $var;
		9.	 
		10.	$var *= 2;
		11.	say $var;
		12.	 
		13.	$var .= "foobar";
		14.	say $var;
		15.	 
		16.	$var += 100;
		17.	say $var;
		18.	 
		19.	$var = 42;
		20.	$var += 100;
		21.	say $var;

Figure 11 - numbers.pl, this demonstrates the use of numeric variables

In line 7, we declare the variable $var and give it the value 42. Since we have given it a numeric value, we can treat this as a numeric variable. We see this on line 10 where we double the value of $var and when we print it out, we see that it now has a value of 84.

On line 13, we perform a string concatenation operation with $var and a literal string, “foobar”. Since this is a string operation, we are using $var as if it were a string so it is treated as such and when we print it out, we see the result 84foobar.

On line 16, we add 100 to $var, but $var now has a value which cannot be treated as a numeric value so we get an error.

On line 19, we give $var the value 42 so now it has a numberc value again. We can then add 100 to its value, as we attempted to do in line 16, but this time it works and we can display the value as 142.

For reference, the output of this code is shown in figure 12.

		1.	izoom@localhost:perl5EssTraining $ perl ./numbers.pl
		2.	42
		3.	84
		4.	84foobar
		5.	Argument "84foobar" isn't numeric in addition (+) at ./numbers.pl line 16.
		6.	184
		7.	142

Figure 12 - the output from running numbers.pl

So, as we saw by running numbers.pl, as long as a variable has a numeric value, we can treat is as a numeric value. We also saw that by giving it a non-numeric value (in this case a string value), it was no longer a numeric variable, but by reassigning it a numeric value, it is a numeric variable again.

This demonstrates an important aspect of Duck typing. We can effectively convert a variable from numeric to string simply by changing its value, so data types are not fixed.

Character Strings

As with numeric variables, we can define a variable as any variable that can be treated as a string.

Often, when we are using a string variable, we will embed it in another string as the following example shows.

say "This is a string: $s.";

If we print the string, for example, the variable is expanded so that its value is printed and this is called string interpolation. It is fairly common for the variable to be separated from the string with spaces but as we saw earlier, we can also delimit it with curly braces. We can also use square brackets, parentheses, forward slashes or even pipe characters.

If we want to display a string that includes quote marks as in the following

This is a string: "Hello World!".

We can do that using a method that is pretty much universal these days which is to escape the quote marks. Similarly, we could mix the quote marks, that is, put the string in single quotes so that the double quotes we want to display are simply part of the string.

However, there is another method which is probably unique to Perl and that is to use qq, the quote interpolation operator. The syntax for this is

qq(insert string here, no quote marks required);

So, assuming we have a scalar variable called s which holds the string, “Hello World!”, we might print the string shown above which includes double quotes with

say "This is a string: \"$s\".";

or

say (qq|This is a string: "$s".|);

Either statement will accomplish exactly the same thing.

This is used quite often in Perl simply because it is so convenient. Again, we can use other characters to delimit the string, although in this case we are delimit the whole string rather than just the variable. So we can use square brackets, curly braces, forward slashes or pipe characters. This is handy because, of course, our string might vibration any convincing of these characters so we have options which make it more likely we will be able to use a delimiter that doesn’t appear in our string. Actually, the pipe character is quite commonly used for that reason, it isn’t often used inside a string!

Logical Values

Similar to C, Perl considers 0 to be equivalent to false and everything else to be equivalent to true. One of the practical consequences is that you can use just about any value or expression as though it were a Boolean variable. For example, in an if statement you could use a straightforward string value like

if($filename) { code}

Here, the code will be executed if the variable, $filename, has any value. In other words, if it is not an empty string. Note that in the case of a collection such as a list or array or even a string, we can say that it is effectively equivalent to zero if it is empty.

To demonstrate this, the code in figure 13 creates two variables and uses them in an if condition which returns a Boolean result and outputs true or false, depending on the value of the result.

		1.	#!/usr/bin/perl
		2.	# logical.pl by Bill Weinman <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my $x = 1;
		8.	my $y = 1;
		9.	 
		10.	if ( $x == $y ) {
		11.	    say 'true';
		12.	} else {
		13.	    say 'false';
		14.	}	

Figure 13 - logical.pl - straightforward comparison of two numerical values

As might be expected, the condition here evaluates to true and so true is output.

Now let’s consider another example shown in figure 14.

		1.	#!/usr/bin/perl
		2.	## logical.pl by Bill Weinman <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my $string = "Hello World!";
		8.	 
		9.	if ( $string ) {
		10.	    say 'true';
		11.	    } else {
		12.	        say 'false';
		13.	}	

Figure 14 - logical.pl - testing a non-empty string

In this example, we are not using a comparison in the condition, we are using the value of $string. This is not an empty string so we would expect it to return true and indeed, that is what happens when we run the script with true being output.

The next snippet of code shown in figure 15 is identical to the code shown in figure 14, except that the value of $string is an empty string.

		1.	#!/usr/bin/perl
		2.	## logical.pl by Bill Weinman <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my $string = "";
		8.	 
		9.	if ( $string ) {
		10.	    say 'true';
		11.	    } else {
		12.	        say 'false';
		13.	}	

Figure 15 - logical.pl - testing an empty string

This time, $string returns a false value and false is output.

Now, let’s look at something similar but with an array rather than a string as shown in figure 16.

		1.	#!/usr/bin/perl
		2.	## logical.pl by Bill Weinman <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my
		8.	@array=( 1, 2, 3 );
		9.	if ( @array ) {
		10.	    say 'true';
		11.	    } else {
		12.	        say 'false';
		13.	}

Figure 16 - logical.pl - testing a non-empty array

As with the string, we expect a non-empty array to return a true value and therefore output true and it does. If we run the same code again with an empty array as shown in figure 17, we will expect to see false output.

		1.	#!/usr/bin/perl
		2.	## logical.pl by Bill Weinman <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my @array=(  );
		8.	if ( @array ) {
		9.	    say 'true';
		10.	    } else {
		11.	        say 'false';
		12.	}

Figure 17 - logical.pl - testing an empty array

As expected, the output is false. Incidentally, if we declare the array as follows:

my @array;

this has the same effect and gives us the output as false.

Finally, let’s see this with numeric variables starting with what we expect to give a false result (see figure 18.

		1.	#!/usr/bin/perl
		2.	## logical.pl by Bill Weinman <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my $num=0;
		8.	 
		9.	if ( $num ) {
		10.	    say 'true';
		11.	    } else {
		12.	        say 'false';
		13.	}

Figure 18 - logical.pl - testing a number, zero

It would be meaningless to describe the value of $num as empty but it is zero and it gives the expected output of false.

Let’s try this again with a value which is more or less zero as shown in figure 19.

		1.	#!/usr/bin/perl
		2.	## logical.pl by Bill Weinman <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my $num=0.000000001;
		8.	 
		9.	if ( $num ) {
		10.	    say 'true';
		11.	    } else {
		12.	        say 'false';
		13.	}

Figure 19 - logical.pl - testing a number, not zero

Here, the value of $num is very close to zero but it is not zero so the output is true. We can run this again with any positive or negative number but as long as the number is not zero, the output will be true.

Lists and Arrays

A list is a fixed series of scalar values. For example, if we execute the following code

say (1, 2, 3);

we see the list elements output, one after the other. This illustrates the fact that a list is enclosed in brackets and the individual elements are separated by commas.

We can also iterate through a list with foreach as in

say foreach (1, 2, 3);

The output here is similar, but in this case, each element is output on a separate line. So, say is being called for each element of the list. I guess that in the first example, say is only being called once and that’s why we see the output on one line (only one list)!

The elements of a list can be any scalar values including numbers and strings and they don’t all have to be the same data type. The code shown below

say foreach (1, "two", 3);

Is perfectly valid and works as expected, outputting each element on a separate line as before.

For creating a list of strings, we can use a Perl-specific (as far as I know) which is quote word (qw), which looks like this

say foreach qw( one two three );

Note that here, the elements are separated by spaces (actually white space so tabs, for instance would work, although I’m not sure why you would want to use them and the spaces (or white space) between the parentheses and the first or last element seems to be optional (really optional this time)! Quote marks are optional, but not in the sense that it makes no difference whether you use them or not. If you add quote marks as in

say foreach qw( "one" "two" "three" );

this works fine, but the quote marks are interpreted as being part of the string so when the elements of the list are output, the quotes are included in that so you will see something like.

		1.	izoom@localhost:perl5EssTraining $ perl ./lists.pl
		2.	"one"
		3.	"two"
		4.	"three"	

We can also use the subscript operator to access an individual element of a list so

say qw( one two three ) [1];

will output the second element in the list (as with other programming languages, indices normally start from 0).

An array is similar to a list, but is actually mutable.

We can create an array and, similarly to lists, we can iterate through it with foreach as follows:

		my @array = (1, 2, 3);
		say foreach @array;	

There are some similarities with lists, the elements are enclosed in parentheses and separated by commas, elements can be any scalar values and we can use qw to create an array of strings (as with lists, when using qw, the elements are separated by white space rather than commas).

We can also use the subscript operator to access an individual element and this would look something like the code shown below.

		1.	my @array = qw ( one two three );
		2.	say foreach @array;
		3.	say $array[1];	

It’s worth noting that with lists, unlike arrays, there is no symbol to indicate the type of the variable. Here, we have used the @ symbol to indicate an array but when we access an individual element, we use the $ symbol.

Bear in mind that an array is a collection of scalar variables so when we do access an individual element, we are accessing one of these scalar variables, so this is why we used the $ symbol here.

It is important to note that if we change the code as follows

		1.	my @array = qw ( one two three );
		2.	say foreach @array;
		3.	say @array[1];

the output is the same which suggests the two versions of the code are equivalent, however, this is not the case and you may not always find that you get the same output if you use @ rather than $.

The difference here is that in the second version, when we see ‘two’ as the last line of output, we are not seeing the second element of the array, we are actually seeing a new array with a single element.

So, if we use the $ symbol with the subscript operator, we will get an individual element from the array which is a scalar variable. If we use the @ symbol, we will see a single element array.

We can also use the subscript operator to modify the value of an array element like this

$array[1]=“element one”;

This is the major difference between an array and a list. We cannot change the values in a list.

In contrast to how an array behaves in most other languages, a Perl array is also mutable in the sense that we can add elements to it, which we do with push. Note that push adds elements to the end of an array so you could consider this to be a stack operation.

Consider the code in figure 20, below.

		1.	#!/usr/bin/perl
		2.	 
		3.	use warnings;
		4.	use 5.16.0;
		5.	 
		6.	my @array = qw ( one two three );
		7.	 say foreach @array;
		8.	 
		9.	say "";
		10.	 
		11.	push @array, qw ( four five six );
		12.	say foreach @array;

Figure 20 - demonstrating push to add elements to the end of an array

Here, we are creating an array with three string values and displaying the values with a foreach loop.

We then use push to add three additional elements to the array. Note that we are actually creating a new three element array and adding it to the existing array. We then output the contents of the array which now contains 6 values. This gives us the output shown in figure 21.

		1.	izoom@localhost:perl5EssTraining $ perl ./arrays.pl
		2.	one
		3.	two
		4.	three
		5.	 
		6.	one
		7.	two
		8.	three
		9.	four
		10.	five
		11.	six

Figure 21 - the output from arrays.pl which displays the 3 valies originally in the array followed by the 6 values after an additional 3 values have been pushed onto the end of the array

Conversely, we can use pop to remove the last element of the array and this is demonstrated in the code shown in figure 22.

		1.	#!/usr/bin/perl
		2.	 
		3.	use warnings;
		4.	use 5.16.0;
		5.	 
		6.	my @array = qw ( one two three );
		7.	 
		8.	push @array, qw ( four five six );
		9.	 
		10.	pop @array;
		11.	pop @array;
		12.	my $x = pop@array;
		13.	 
		14.	say foreach @array;
		15.	 
		16.	say "The removed element was $x";	

Figure 22 - using pop to remove three elements from the array (using an array as a stack)

Here, we have an array with six elements. On lines 10 and 11, we use pop to remove an element from the array. Notice that we are not assigning the removed element to any variable so these values are effectively lost. We have no way of adding them back to the array (at least, not without knowing the value in which case, we can pop that value back on).

On line 12, we also use pop, but this time we have assigned the popped value to a variable called $x. We can now reference that variable, as we do in the say statement on line 16. We could also push this value back on to the array with

push @array, $x;

Note the syntax here, after the push command, we have the name of the array we want to perform the operation on followed by a comma and then the value to be added to the end of the array. Here, that value is a scalar value, but as we saw previously, this can also be another array or it could be a list.

I mentioned, previously, that push and pop are essentially stack operations. What I mean by that is that if we want to simulate a stack (I don’t know if Perl has any better way to implement one), we can create an array and use push and pop operations with it.

Similarly, we can use shift (which we saw used earlier to retrieve a filename from an array of arguments (an array of one argument in all likelihood) and unshift with an array. The shift operator removes an element from the front of the array and the unshift operator adds an element to the front of the array. These are essentially queue operations so they allow us to implement a queue using an array.

Be aware, though, that there is nothing to prevent you using push and unshift or pop and shift on the same array. So, if you implement a stack in this way, for instance, you can still perform queue operations on it. This makes it less than ideal for implementing these data structures but hopefully, we will learn a method to implement them safely later. However, if you google, ‘how to implement a stack in Perl, some of the results returned are from GeeksforGeeks and Perl Monks and they give the same method I’ve just described. This suggests that there is no better way to implement either a stack or a queue.

The code in figure 23, is similar to the code in figure 22, but this time we are treating the array as a queue and therefore using shift and unshift.

		1.	#!/usr/bin/perl
		2.	 
		3.	use warnings;
		4.	use 5.16.0;
		5.	 
		6.	my @array = qw ( one two three );
		7.	 
		8.	unshift @array, qw ( four five six );
		9.	 
		10.	shift @array;
		11.	shift @array;
		12.	my $x = shift@array;
		13.	 
		14.	say foreach @array;
		15.	 
		16.	say "The removed element was $x";
		17.	 
		18.	unshift @array, $x;
		19.	 
		20.	say foreach @array;	

Figure 23 - using shift to remove three elements from the array (using an array as a queue)

The output from unshift.pl, the code shown in figure 23, is

		1.	one
		2.	two
		3.	three
		4.	The removed element was six
		5.	six
		6.	one
		7.	two
		8.	three	

Note that the value of the array after the three elements on line 8 of figure 23 is ( four five six one two three ). On lines 10 and 11, we have removed the first and second elements without assigning them to any variable. On line 12, we have removed the the third element and assigned it to the variable $x and we have then used unshift to put that element back.

So the final state of our array (or queue) is ( six one two three ). I should perhaps point that when I refer to removing the first, second or third element of the array, I mean this in reference to the original array but this is, strictly speaking inaccurate.

Every time shift it used, it will remove the first element and leave the array in a new state. This can be demonstrated in the table in figure 24.

OPERATION ARRAY STATE
--- ( one two three )
unshift ( four five six ) ( four five six one two three )
shift ( five six one two three )
shift ( six one two three )
shift (assign to $x) ( one two three )
unshift $x ( six one two three )

Figure 24 - a table of operations showing how the array is modified by shift and unshift

Similarly, the table in figure 25 shows how this works when we are treating the array as a stack.

OPERATION ARRAY STATE
--- ( one two three )
push ( four five six ) ( one two three four five six )
pop ( one two three four five )
pop ( one two three four )
pop (assign to $x) ( one two three )
push $x ( one two three four )

Figure 25 - a table of operations showing how the array is modified by push and pop

Now, consider the following line of code.

my $count = @array;

This takes the value of array and assigns it to a scalar variable. On the face of it, you might expect to see this generate an error, but it is actually valid code in Perl. It has the effect of assigning a numeric value to $count where that value is the number of elements in the array. We could then output this value with

say "There are $count elements in the array.";

As expected, the output here tells us that there are four elements in the array.

Slices of Arrays

An array slice is a subset of the elements of an array which may or may not be contiguous. For instance, let’s say we create an array with

my @array = qw( one two three four five six seven eight nine ten );

We have already seen how we can assign a single element of this array to a variable using the subscript operator and we can also reference an element using the same method. For example, we might output the first element of this array with

say "The first element of the array is $array[0].";

As expected, this outputs

The first element of the array is one.

As before, we are using the $ symbol because each element of an array is a scalar value. If we wanted to access more than one element, we would use the following syntax.

say foreach @array[1,2,3];

This time, we used the @symbol because we are returning an array of values from the original array rather than a single value. So, we are still returning scalar values, but we are returning them as an array. In this example, the second, third and elements will be returned and output.

Note that we did not assign this array slice to any variable so we cannot subsequently reference it but we could do that with something like.

my @arrayslice = @array[0, 1, 2, 3];

We could then display the contents of this array with

say foreach @arrayslice;

So this is doing in two lines what we previously did with one, but it does mean that we have a new array with the elements selected from the original array and we can reference it or perform operations on it as desired.

We can also use the range operator for contiguous value so the above example could have been written as

my @arrayslice = @array[0..3];

This would work in exactly the same way. However, if we do specify each element individually as we did the first time, this has the advantage that the elements don’t have to be contiguous or, indeed, in order. So we could do something like

my @arrayslice = @array[3, 1, 7, 9, 0];

If we output this with foreach, we see

		1.	four
		2.	two
		3.	eight
		4.	ten
		5.	one

Hashes or Associative Arrays

Hashes, sometimes known as associative arrays, are very common and very powerful in Perl. As has been mentioned, the symbol for a hash variable is the % sign. A hash is quite similar to an array, but where an array element is referenced by index (effectively, by its position in the array), a hash value is referenced by the key associated with it so each element comprises of a key and the associated value.

We can see this in the example shown in figure 26.

		1.	#!/usr/bin/perl
		2.	# hash.pl by Bill Weinman >http://bw.org/contact/<
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my %hash = ( one => 'uno', two => 'dos', three => 'tres', four => 'quatro', five => 'cinco' );
		8.	 
		9.	while( my ($k, $v) = each %hash ) {
		10.	    say "$k -> $v";
		11.	}

Figure 26 - the code for hash.pl

Looking at line 7, we can see a hash being declared and four elements (that is, four key value pairs) being added. Note that the keys are bare strings, but you can add quotes if you want to, for instance if there is an embedded space in the key. This is followed by an association symbol, => and then a value which can be any scalar value. Key value pairs are separated by commas and everything is enclosed in parentheses.

The while loop is defining two variables, one for the key and one for the value and each returns each key value pair one at a time. Each time, the key is assigned to $k and the value to $v, both of which are output with say.

The values are not stored in any particular order. When I run the code, I get the output as

		1.	izoom@localhost:perl5EssTraining $ perl ./hash.pl
		2.	three -> tres
		3.	five -> cinco
		4.	one -> uno
		5.	two -> dos
		6.	four -> quatro	

There is no guarantee that you will get the same order every time you run this although, for me, this does seem to be remaining constant.

Technically speaking, a hash uses a hash table to translate a key to a value and this allows us to search the keys quickly and efficiently. They are, as we saw in the above demonstration, not ordered in any natural way (eg, alphabetically or numerically, assuming keys can have numeric values) and are unique.

We can add a key value pair simply by defining a new one with code such as:

$hash{six} = 'seis';

Actually, if I run the amended code I get the same order as I did previously except the new pair has appeared in the second position.

Going back to the point about whether it is possible to use a numeric value as a key, given that the values are usually represented as a bare string, I would guess not. If you tried to use a value of 2, for instance, it would probably be represented as “2”.

To test this, I have amended the output in the while loop to use the string concatenation operator so it becomes

say "$k.' concat '.$v";

Now, I will also amend the line of code seen above which added a sixth element so that it becomes

$hash{6} = 'seis';

My theory is that this will still work which would demonstrate that the key is “6” rather than 6. If it generates an error, this is because we are using a string operator on a numeric value (this is not completely clear, there may be some duck typing involved).

It does work so the value is either a string or is being treated as a string. I’m pretty sure that values can be numbers so I have amended the code again so that the key, 6, has an associated value of 6. This also works which suggests duck typing is being used.

As a final investigative step, I have tried to use both the keys and values as numbers by adding this line to the while loop.

my $num = $k + $v;

The result of this sum is being output with

say "$k + $v = $num";

When I run this, it works perfectly well for the numeric key value pair. The other key value pairs all give an error since they are strings that cannot be treated as numbers, so duck typing will not help here.

My conclusion is that using numbers as keys works perfectly well. This was just an interesting aside for me, I would imagine that in practice, you wouldn’t want to do this, especially if you are using a numeric sequence (such as 1 to 10 or 0 to 9, for example) since this would simply be an array without the natural ordering an array gives you!

We can change the value currently associated with a key with something like

$hash{one} = "foo";

Given that this code is identical, syntactically, to the code to add a key value pair, we could say that it would have the effect of updating the associated value if the specified key already exists or adding the key and its value, if it doesn’t.

This guarantees that keys will be unique, but it is also potentially dangerous since you may believe that you are adding a key value pair when you are actually updating an existing value associated with the key, effectively deleting the old value so you may want to be careful with this.

It is possible to check first. As an exercise, I wrote the following code

		1.	## while loop to check whether a potential key is already in use
		2.	my $potentialKey = "four";
		3.	my $dup=0;
		4.	while ( my ($k, $v) = each %hash ) {
		5.	    if ( $k eq $potentialKey ) {
		6.	        say "Warning : $k already in use";
		7.	        $dup=1;
		8.	    }
		9.	}
		10.	 
		11.	if (!$dup) {
		12.	    say "$potentialKey is valid as a new key";
		13.	} 	

Figure 27 - code to check whether a potential key already exists

This creates a value called $potentialKey and a numeric value $dup (acting as a simple Boolean variable, set to 0 for false, initially). The while loop compares each existing key with $potentialKey and if it matches, issues a warning to this effect and sets the value of $dup to 1 (true).

When the loop finishes, the value of $dup is checked and if it is false (I guess, strictly speaking, the test is whether it is not true), this indicates that the value was not changed in the while loop so a match was not found. A message is therefore output to let the user know that the key is valid.

Note that this code was created purely for exercise purposes. At this stage, I don’t know if there is a simple test to check whether a key exists or not, but I suspect that there probably is.

Another thing we can do with a hash is to delete a key which you can do with something like

delete $hash{one};

Obviously, we are only deleting the key, not the value. However, since the key is the only reference we have to the value, we can no longer access it once the key has been deleted.

We can sort the hash by keys using its sort command. This is shown in figure 28.

		1.	#!/usr/bin/perl
		2.	## sorthash.pl by Bill Weinman <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	my %hash = ( one => 'uno', two => 'dos', three => 'tres', four => 'quatro', five => 'cinco' );
		8.	 
		9.	foreach my $k ( sort(keys %hash ) ) {
		10.	    my $v = $hash{$k};
		11.	    say "$k -> $v";
		12.	}

Figure 28 - the code for sorthash.pl which demonstrates sorting of the keys in a hash

Sort will be covered in more detail later, but for now, this sorts they keys and when they are displayed, we can see that they are ordered. However, the keys are string values, not numerical values, so they are sorted alphabetically.

Constants

Perl doesn’t include constants in its language definition, but the standard distribution does include a pragma which can be used to create a constant. This is shown in the code in figure 29.

		1.	#!/usr/bin/perl
		2.	## hello.pl by Bill Weinman <http://bw.org/contact/>
		3.	 
		4.	use 5.16.0;
		5.	use warnings;
		6.	 
		7.	use constant PI => 3.141592653589793238462643383279;
		8.	use constant TRUE => 1;
		9.	use constant FALSE => '';
		10.	 
		11.	say PI;
		12.	 
		13.	if (TRUE) {
		14.	    say 'true';
		15.	    } else {
		16.	        say 'false';
		17.	}	

Figure 29 - constant.pl demonstrating the use pragma to create constant values in Perl

The syntax for defining a constant is similar to the syntax for defining a hash, as we can see in figure 29 on lines 7, 8 and 9. We have the use keyword followed by constant then the name of the constant (effectively the key), the same operator we saw when associating a key with a value, the association operator, => (note, this is a single operator although it is written with two symbols) and finally we have the value.

We can also define several constants with a single pragma. If we rewrite the code in figure 29 to define our three constants with a single pragma, we can replace all three lines (7, 8 and 9) with this single line.

		use constant {                                                                                                            
				PI => 3.141592653589793238462643383279 ,
				TRUE => 1,
				FALSE => '' ,
		};	

There are a couple of important points to note about this. Firstly, although this snippet of code is enclosed in curly braces, it is not a block of a code, it’s a pragma (a statement) so we do need the semi-colon after the closing curly brace. Also, note the comma after the last value. This is not required but it has been added for a similar reason why we add a semi-colon after the last statement in a block. It means that if we add another constant to the same pragma, we don’t have to worry about adding the comma to the end of what would have previously been the last constant. So this avoids a problem with a missing comma which can cause a little bit of stress!

Note that it is not a requirement, but it is conventional to use all upper-case letters for constants. It is a good idea to follow this convention because it does make the constants easier to see and because it is a more or less universal convention, it is also easier to recognise as a constant.

Now, consider this line of code.

sub PI{3.141592653589793238462643383279};

If we remove PI from our list of constants in the use pragma and insert this line of code and then run the program, the output is the same. This harks back to the fact that almost everything in Perl returns a value. Here, we have declared a function called PI and inside the block of code (note, it is a block of code here so we do need the semi-colon at the end) which simply includes the number, the value of PI. When called, the function simply returns the value so the effect is the same.

In fact, this is how the use pragma works, it creates the function for you, although you won’t see it in the source code. So you can by-pass this and simply create the function yourself, and this is actually a common method of creating a constant in Perl. Even if you don’t follow this method yourself, it is useful to know about it because you will likely see it if you work with Perl code created by someone else.

This function definition method may be useful if you are only creating one or perhaps a few constants. However, if you need to create a lot of constants, the use pragma is probably more suitable and would be more concise than a lot of individual functions.