3. Variables

Created Tuesday 15 April 2014

Strict, warnings, diagnostics

For every code snippet assume that it begins with:
use strict;
use warnings;
use diagnostics;

The my Function

Example
my $new_variable = 'I\'m a new variable';

Sigils

$

More sigils to be discussed further...

Identifiers

Things that have identifiers (names):

Naming rules:
Examples:
my $x;
my $foo;
my $_some_1;
my $DontMakeVariableNamesLikeThis;
my $make_names_like_this_instead;
my $item_3;

Some that may confuse:
my $host = $1;
my $this_perl = $^X;
my $taint_mode = ${^TAINT};
Consider to read about these and other special vars:
perldoc perlvar

Scalars

literal is a hard-coded value in a program, as opposed to a variable containing that value. See
perldoc perlglossary

When nothing is assigned to the variable, it has a special value: undef
my $var; # its value is undef

Declaring several scalars at once:
my ( $celsius_temp, $nick_name );

Also assigning values to them:
my ( $celsius_temp, $nick_name ) = ( 37, 'Ovid' );

Strings

Assigning a string to a scalar:
my $string1 = 'string 1';
my $string2 = "string 2";

Example
my $string1 = 'string 1';
my $string2 = "string 2 and $string1";
print "$string2\n";

It's possible to escape quotes with "\"

Quote Operators

Search for "Quote-like Operators" in perldoc perlop

q{}

qq{}

Examples
my $reviewer = 'Adrian';
my $review = qq{$reviewer wrote "This book is wonderful"};
my $review = qq!$reviewer wrote "This book is wonderful"!;
my $review = qq<$reviewer wrote "This book is wonderful">;
my $review = qq[$reviewer wrote "This book is wonderful"];
my $review = qq($reviewer wrote "This book is wonderful");
my $review = qq@$reviewer wrote "This book is wonderful"@;
my $letter = qq{
Dear $editor,

I really liked ...
....
it's:

"Hello, world!"
etc..
};

here-docs

my $letter = <<"QUOTE_TAG";
Dear $editor,

I really liked ...
....
it's:

"Hello, world!"
etc..
QUOTE_TAG

Escape Sequences

See perldoc perlop for the full reference

Numbers

Arrays

Assignment (the list (right) to the array (left)):
my @even = ( 2, 4, 6, 8, 10 );
More:
my $nine = 9;
my @stuff = ( 7, 'of', $nine );
Printing:
print @stuff, "\n";
This will print
7of9
printing every element and a newline.
And this:
print "@stuff\n";
will print
7 of 9
because the array is interpolated into a string while elements by default are separated with a single space (which can be controlled by the $" special variable, see perldoc perlvar).
Accessing elements:
my @words = ("and", "another", "thing");
print $words[0];
my $first = $words[0];
my $second = $words[1];
my $third = $words[2];
Assign individual elements:
$words[1] = "one more";
print "@words\n";
Accessing the elements from the end:
my $last = $words[-1];
The qw() operator ("q"uote "w"ords) is useful when assigning literals and not variables:
my @odds = qw(1 3 5 charlie); # This operator takes a string and separates it on whitespace
my @odds = qw! 1 3 5 charlie !;
my @odds = qw< 1 3 5 charlie >;
my @odds = qw{ 1 3 5 charlie };
my @odds = qw[ 1 3 5 charlie ];
my @punctuation = qw[ . ; ! ( ) { } ];

Iterating over arrays

my @array = ('this', 'is', 'an', 'array');
for my $element (@array) {

print "$element\n";
}

Hashes

my %people = (
"Alice", 1,
"Bob", 2,
"Ovid", 3
);
print $people{'Alice'}

Iterating over hashes

for my $name ( keys %people ) {

print "$name is $people{$name}\n";
}
The keys functions returns a list of keys from the hash. There is also the values function, guess what it does..

Adding a new value

$people{Austen} = 'Jane';
%people = ( %people, Austen => 'Jane', Lincoln => 'Abraham' );

Declaring hashes the perlish way

my %people = (

Alice => 1,
Bob => 2,
Ovid => 3,
);
Or
my %people = (
'Alice' => 1,
'Bob' => 2,
'Ovid' => 3,
);

Slices

Array slices

my @names = ('Alice', 'Bill', 'Cathy', 'Doug');
my @men = @names[ 1, 3 ];
my @women = @names [ 0, 2 ];

Hash slices

my %nationality_of = (

'Ovid' => 'Greek',
'John Davidson' => 'Scottish',
'Tennyson' => 'English',
'Poe' => 'Tacky',
);
my @nationalities = @nationality_of{ 'Ovid', 'Tennyson' };
print "@nationalities";

CONTEXT

Scalar context

my $number_of_things = @things_in_common; # The number of elements
my $number_of_things = scalar @things_in_common; # The number of elements
my $number_of_things = ( 'liars', 'fools', 'certain politicians' ); # The last element
my $number_of_things = %hash_example;
If you have a scalar on the left, you have scalar context.

Arrays in scalar context

my @things_in_common = ( 'liars', 'fools', 'certain politicians' );
my %count_for = ( useless_things => scalar @things_in_common );
print $count_for{useless_things};

Lists in scalar context

Hashes in scalar context

my %hash = ( 1 => 2 );
print scalar %hash; # Will print something like 1/8

List context

Copy an array to another array:
my @copy = @old_array; # Only the top-level elements are copied this way (see chapter 6 for more details)
Assigning a hash to an array:
my %order_totals = (

Charles => 13.2,
Valerie => 17.9,
'Billy Bob' => 0,
);
my @flattened = %order_totals; # That "flattens" the key/value pairs in the hash into a list, the array will containg both keys and values as its elements
Example:
my @swords = ( 'katana', 'wakizashi' );
my $number_of_swords = @swords;
my ($left_hand) = @swords; # Assigning the first element of the array to the scalar
Assigning several scalars:
my ( $left_hand, $right_hand ) = @swords;
Swapping the values:
( $right_hand, $left_hand ) = ( $left_hand, $right_hand );
Mixing scalars and other vars:
my ( $first, @extra ) = ( 1, 2, 3, 4 ); # The scalars must come first!!!

SCOPE

File scoped

Block scoped

WARNING: after version 5.10 (including) it is permitted to use my $_, but not for other built-ins. See perldoc perl5100delta and search for Lexical $_.
WARNING: in expression for my $number (@numbers) {...} the $number var belongs to the {...} block.

Package variables

Example:
package MyCompany::Stuff;

use strict;
use warnings;

%MyCompany::Stuff::department_number_for = (

finance => 13,
programming => 2,
janitorial => 17,
executive => 0,
);
Later other code can reference this with the following:
my $department_number = $MyCompany::Stuff::department_number_for{finance}; # This code may be even in a different file so long as the MyCompany::Stuff package has been loaded
Typing such a long name is error-prone. There are several options to deal with this:

Not use the strict pragma.

Any variable referenced without the my function is automatically a variable in the current package:
package main;
$answer = 42
print "$answer\n";

The vars Pragma

package MyCompany::Stuff;
use strict;
use warnings;
use vars (

'%department_number_for',
'$some_other_package_variable',
);
%department_number_for = (
finance => 13,
programming => 2,
janitorial => 17,
executive => 0,
);
$some_other_package_variable = 42;
print $department_number_for{finance};

3. The our function (starting with version 5.6.0)

package MyCompany::Stuff;
use strict;
use warnings;
our %department_number_for;
our $some_other_package_variable;
%department_number_for = (

finance => 13,
programming => 2,
janitorial => 17,
executive => 0,
);
$some_other_package_variable = 42;
print $department_number_for{finance};

WARNING: Use the vars pragma or our function only if you need to share your variable outside of your package, otherwise:

Local variables

our $answer = 42;
{
local $answer = 57;
print "$answer\n";
}
print "$answer\n"; # The output will be '57\n42\n'
local $MyCompany::Stuff;
our $answer = 42;
{
local $answer = $answer;
print "$answer\n";
$answer = $answer + 2;
print "$answer\n";
}
print "$answer\n"; # 42\n44\n42\n

STRICT, WARNINGS, DIAGNOSTICS

no strict;
no warnings;
But it's recommended to do so only with 2 conditions:
{
no warnings 'uninitialized';
$total = $total + $some_value;
}

strict

In general:
use strict;
Also possible:
use strict 'vars';
use strict 'subs';
use strict 'refs';

warnings

diagnostics

PERL'S BUILT-IN VARIABLES

$_

Example without $_
for my $element (@array) {
print $element;
}
Example with $_ — when not creating a variable for an assignment, the $_ variable is automatically populated
for (@array) {
print "$_\n";
}
The print function, by default, prints the $_ variable if it doesn't have any arguments, so:
for (@array) {
print;
}
Also, there is the feature pragma to import the say function which is just like print, but automatically adds a newline:
use feature 'say';
for (@array) {
say;
}

%ENV

@ARGV

use strict;
use warnings;
print "Hello, @ARGV";
Then on command line:
perl hello.pl John Q. Public

@_

$0

$a, $b

@INC

%INC

$^V

$^X

$1, $2, ...

$!

$@

$/



Backlinks: