Showing posts with label references. Show all posts
Showing posts with label references. Show all posts

2012/04/08

use Perl; Guide to references: Part 5

This is the final part in my five part guide to Perl references. It's a complete program that contains a menu system along with the card game 'war'. This is pretty serious spaghetti code, so I will likely replace it as soon as I come up with something that uses all of the examples in this series but has a more logical flow and is easier on the eyes :)

  • Part 1 - The basics
  • Part 2 - References as subroutine parameters
  • Part 3 - Nested data structures
  • Part 4 - Code references
  • Part 5 - Concepts put to use (this document)

Please leave any corrections, criticisms, improvements, additions, questions and requests for further clarity in the comments section below, or in an email.

The following program code can be copy/pasted without all of the comments from my scripts repository.

#!/usr/bin/perl

use warnings;
use strict;
use 5.10.0;

# create a master dispatch table, using a reference to an
# external sub, and two inline subs

my %dispatch_table = (
                        play    => \&play_game,
                        hello   => sub { say "\nHello, world!\n"; },
                        'exit'  => sub { say "\nGoodbye!\n"; exit; },
                    );

# create an href to the dispatch table hash

my $dt_ref = \%dispatch_table;

# take a reference to the closure within the games_played() sub

my $games_played = games_played();

# loop over the menu until the user exits

while ( 1 ){

    system( "clear" );

    # get the dispatch table options by dereferencing the
    # dispatch table href

    my @options = keys %{ $dt_ref };

    say "Enter one of these options: " . join( ' ', @options );
    chomp ( my $command = <STDIN> );

    # exit if an illegal option was entered by the user

    exit if ! exists $dt_ref->{ $command };
    
    # otherwise, execute the sub the user selected

    $dt_ref->{ $command }->();

    # check to see if any games have been played through
    # the $games_played closure cref

    if ( $games_played->() ){
        say "You've played " . $games_played->() . " games.\n";
    }

    print "Please press ENTER...";
    <STDIN>;
}
sub play_game {

    # this is the main game sub, called through the dispatch
    # table

    system( "clear" );

    # create a deck of cards using a hash, and assign
    # a numeric value to the face value key

    my %deck;
    my $card_value = 14;

    for ( qw( A K Q J ), ( reverse 2..10 ) ){

        $deck{ $_ } = $card_value;
        $card_value--;
    }

    # a list of the card faces (without their numeric values)
 
    my @cards = keys %deck;

    print "Enter your name: ";
    chomp ( my $player = <STDIN> );

    print "Enter number of rounds (default: 5): ";
    chomp ( my $rounds = <STDIN> );
    $rounds = 5 if $rounds !~ /\d+/;

    # create a nested HoH for the players, using an href as
    # the top level

    my $players = { 
                    $player => {
                                score    => 0,
                                card     => undef,
                            },
                    npc      => {
                                score    => 0, 
                                card     => undef,
                            },
                    };

    my @player_names = keys %{ $players };

    for my $round ( 1 .. $rounds ){

        print "Round $round: ";

        for my $player ( @player_names ){

            # call deal(), passing in an aref of the cards array

            my $card = deal( \@cards );
            print "$player $card   ";

            # set the players current card in their card slot in the
            # players HoH

            $players->{ $player }{ card } = $card;
        }

        # call the compare_hands() sub by passing in an anonymous
        # hash (reference) inline in the call, with three parameters.
        # All three values are references

        compare_hands({ 
                        player_names => \@player_names,
                        players      => $players,
                        deck         => \%deck,
                     });

        print "\n";
    }

    print "\n";

    # loop over players, and get each of their final
    # scores out of the players HOH

    for my $player ( @player_names ){

        my $score = $players->{ $player }{ score };
        say "$player won $score rounds.";
    }

    print "\n";

    # update games played

    $games_played->( 1 );
}
sub deal {

    # take an aref of @cards, and return a random one

    my $deck_of_cards = shift; # aref
    return $deck_of_cards->[ rand @{ $deck_of_cards } ];
}
sub compare_hands {

    my $named_params = shift;
    
    # separate out the data from the named parameters
    # in the href we got passed in

    my $player_names    = $named_params->{ player_names };
    my $players         = $named_params->{ players };
    
    # we convert the last named param back into a hash
    # by dereferencing it

    my %deck            = %{ $named_params->{ deck } };

    my ( $player1, $player2 ) = @{ $player_names };

    # get each player's card

    my $p1_card = $players->{ $player1 }{ card };
    my $p2_card = $players->{ $player2 }{ card };

    # check the face of the card to the %deck hash to
    # retrieve the numerical value

    my $p1_card_val = $deck{ $p1_card };
    my $p2_card_val = $deck{ $p2_card };

    # nobody wins this round... its a tie

    return if $p1_card_val == $p2_card_val;

    if ( $p1_card_val > $p2_card_val ){
        # player 1 wins
        $players->{ $player1 }{ score }++;
    }
    else {
        # player 2 wins
        $players->{ $player2 }{ score }++;
    }
}    
sub games_played {
    
    # state data

    my $games_played = 0;

    # our games_played closure

    return sub {
                my $add = shift;
                $games_played += $add if $add;
                return $games_played;
               }
}

Thank you very much for reading. I have received a lot of great feedback on the series, both from people informing me they have learnt a great deal, and others with corrections and additions. I appreciate you all. I hope you have enjoyed my Guide to reference tutorials. Please feel free to provide me feedback so I may improve on my style for future posts.

Regards and thanks,

-stevieb

2012/04/07

use Perl; Guide to references: Part 4

This is part four in my five part series on Perl references. In this post, we will be discussing code references (coderef, or just cref), some of the benefits they provide, and some interesting use cases, including closures and dispatch tables. If you haven't already, you may want to review the other parts in the series:

  • Part 1 - The basics
  • Part 2 - References as subroutine parameters
  • Part 3 - Nested data structures
  • Part 4 - Code references (this document)
  • Part 5 - Concepts put to use

As with all of the other parts in the series, I request that you leave corrections, criticisms, improvements, additions, questions and requests for further clarity in the comments section below, or in an email.

CODE REFERENCES

A code reference in Perl is no different than any of the other references we've discussed in the previous episodes, but instead of pointing to a data variable, the ref points to a subroutine. You take a reference to a subroutine the same way you take a reference to anything else:

sub hello {
    say "Hello, world!";
}

my $cref = \&hello;

The & sigil represents a sub, and it is needed when we take the reference. As with taking the ref, using the ref is the same as before as well. We must use the -> deref operator to access the item the reference points to.

# use an aref
$aref->[ 0 ];

# use an href
$href->{ a };

# use a cref
$cref->();

We can also assign an anonymous sub to a cref in cases where we don't necessarily have to define the function with a name:

my $cref = sub { say "Hello, world!"; }

Now that we have that out of the way, lets move on to some practical and interesting uses for code references.

CLOSURES

The most common type of closure is a sub that returns a reference to an inner sub. They are often used in Object Oriented Programming (OOP) (which is outside the scope of this tutorial) to keep state data. State data is data that persists after the program has exited the scope in which the data was defined. I can explain it better with some code:

sub persist {

    my $count = 0;
    return sub { say $count++; }
}

my $count_cref = persist();

$count_cref->();
$count_cref->();
$count_cref->();

First, we define a subroutine named persist(). Inside that sub we define a lexical variable $count (a lexical variable is one that can not be seen outside the scope of the block it is declared in. In this case, nothing outside of persist() can see the $count variable). After defining $count, we create an anonymous sub that prints the result of $count, and then adds one to it. We then call persist(), assigning its return value to $count_cref. The return of persist is a reference to the anonymous subroutine.

Because $count_cref points to the inner anonymous sub returned from persist() and not to persist() itself, the $count variable is never reset, and the sub that $count_cref points to will always keep its own version of $count, incremented each time the anon sub is executed through the reference.

To show how the $count variable retains its value as long as $count_cref is alive, here is the output from the above code snip:

0
1
2

Closures aren't only handy for OOP. We can use the same persist() sub to create multiple counters.

sub persist {

    my $count = 0;
    return sub { $count++; }
}

my $count_a_cref = persist();
my $count_b_cref = persist();
my $count_c_cref = persist();

say "Count A: " . $count_a_cref->();
say "Count A: " . $count_a_cref->();
say "Count B: " . $count_b_cref->();
say "Count B: " . $count_b_cref->();
say "Count B: " . $count_b_cref->();
say "Count C: " . $count_c_cref->();

Output:

Count A: 0
Count A: 1
Count B: 0
Count B: 1
Count B: 2
Count C: 0

Calls to the individual cref do not affect the state variables of the other cref state variables.

Here's an example that shows a more practical case where closures with state variables could be useful. If you're thinking that globals would do the trick here, you're right; that isn't the point of this tutorial though ;). I'm sticking with simple here. In my fifth and final installment, we'll write something far more realistic that brings all aspects of the series together.

sub write_line {

    my $count = 0;
    return sub { return ++$count; }
}

# call the function twice, each time receiving
# a separate anonymous sub, along with separate
# state variables

my $steve_lines = write_line();
my $sarah_lines = write_line();

# steve writes two lines of code

my $steve_total;
$steve_total = $steve_lines->();
$steve_total = $steve_lines->();

# sarah writes one

my $sarah_total;
$sarah_total = $sarah_lines->();

say "Steve wrote $steve_total lines of code";
say "Sarah wrote $sarah_total lines of code";

Output:

Steve wrote 2 lines of code
Sarah wrote 1 lines of code

As an aside: In the preceeding example, I had to declare the sub prior to using it. To understand why and how to get around that, see my Purpose and practical use of Perl's named blocks post.

Closures aren't limited to being returned from outer subs though. Any function that can return an inner anonymous sub that can contain its own lexical data can be used to create a closure. Here's an example:

my %h;
for my $color ( qw(red green blue) ){
   $h{$color} = sub { say $color };
}

$h{ blue }->();
$h{ red }->();
$h{ green }->();

In that example, we iterate over three colours. For each colour, we set a hash key as the colour and set that key's value as an anonymous sub that when called, prints the colour. The following three lines execute the closures. Although we could have, we didn't use any lexical data to keep track of anything. Also note that this code auto generated a dispatch table, which we are going to learn about next.

DISPATCH TABLES

Dispatch tables are hashes who's key's values are references to subroutines. It is like a table of contents that allows you to execute code through the hash keys.

my %dt = (
            hello => sub { say "Hello, world!"; },
            add   => \&add,
        );

# call the functions

my $more = $dt{ add }->( 5, 5 );
$dt{ hello }->();

sub add {

    my $x = shift;
    my $y = shift;
    return ( $x + $y );
}

First we define the dispatch table hash. The first key has a value of an anonymous sub. The second key contains a cref that points to the add() sub. This shows how short, one-line type subs can be housed within the dispatch table. The add sub has been defined to take two parameters. When we call the add sub, you can see how we call the sub through the hash key, which executes the sub through the cref it contains as its value. We then insert the parameters as normal.

An example of the benefits of a dispatch table is a menu system, where a user must select from a range of options. You give the user a list of options to select from, and in your dispatch table, you name your keys as the options you provided the user with. Each option to the user is dropped directly into the key field of the hash, and the subsequent subroutine runs.

In the following example, we have three operations the user can perform where the hash value is a cref to an external sub. The fifth option, exit, is short and simple, so we create it as an anonymous sub within the table itself. A couple sanity checks to ensure the input is legal, and running the correct operation is as simple as putting the users input into the dispatch table.

Here is a fully working menu program based on the concept of a dispatch table. I've kept it as simple and as basic as possible for clarity.

#!/usr/bin/perl

use warnings;
use strict;
use 5.10.0;

my %dt = (
            add      => \&add,
            subtract => \&subtract,
            multiply => \&multiply,
            'exit'   => sub { say "\nGoodbye!\n"; exit; },
        );
    
while (1) {

    system( "clear" );
    
    print "Please enter either add, subtract, multiply or exit: ";
    chomp ( my $operation = <STDIN> );

    # exit if told to

    $dt{ $operation }->() if $operation eq 'exit';

    # exit if illegal param

    if ( ! exists $dt{ $operation } ){
        say "\nIllegal input... exiting\n";
        exit;
    }
    
    print "Type in your first number: ";
    chomp ( my $x = <STDIN> );

    print "Type in your second number: ";
    chomp ( my $y = <STDIN> );

    # run the command selected by the user

    my $result = $dt{ $operation }->( $x, $y );

    say "\nPerforming $operation on $x and $y = $result\n";

    print "\nPress ENTER to continue...\n";
    <STDIN>;
    
}
sub add {
    my ( $x, $y ) = @_;
    return $x + $y;
}
sub subtract {
    my ( $x, $y ) = @_;
    return $x - $y;
}
sub multiply {
    my ( $x, $y ) = @_;
    return $x * $y;
}

Hopefully that simplistic example was enough to at least give you an idea of what dispatch tables could be capable of.

That's it for this episode, thanks for reading. In my next and last post in the series, we'll bring everything together in a single program that utilizes most of the concepts of what we have learnt throughout.

Update: Thanks to maximum-solo for pointing out that I had limited my definition of closures to only a single use case, and for the example code that returns closures from a for loop.

Update: Thanks to Jay Scott for sending typographical and grammatical corrections, and for numerous logical code description fixes.

use Perl; Guide to references Part 2

This is part two in my five part series on Perl references. In Part 1, we went through the basics; how to take references to items and access the items through their references. In this episode, we'll explain some of the differences and benefits of sending references into subroutines, as opposed to the list-type data variables themselves. It s divided up into three sub-sections: references as subroutine parameters, named parameters and anonymous data.

  • Part 1 - The basics
  • Part 2 - References as subroutine parameters (this document)
  • Part 3 - Nested data structures
  • Part 4 - Code references
  • Part 5 - Concepts put to use

This episode assumes that you have at least a minimal understanding of how subroutines (functions) work in Perl; both how to send data into a function, and the standard methods of accessing the data once the function has accepted it. As before, I urge you to leave corrections, criticisms, improvements, questions and requests for further clarity in the comments section below, or in an email.

From this point forward, I will often substitute certain terms with abbreviations: ref for reference, deref for dereference, aref for array reference, href for hash reference and sub or function for subroutine.

REFERENCES AS SUBROUTINE PARAMETERS

Let's start off this section with a sample piece of code:

my @a = ( 1, 2, 3 );
my %h = ( a => 10, b => 20, c => 30 );

hello( @a, %h );

sub hello {

    my @array = shift;
    my %hash  = shift;

    # do stuff
}

As it appears, you are calling the hello() function with two parameters; an array as parameter one, and a hash as parameter two. We then proceed to take the parameters and assign them accordingly. However, in Perl, this does not work as you may think. Perl doesn't keep the parameters as separate parts. Instead, it flattens all the parameters together into a single list. In the case above, if we printed the parameter list before we took anything from it, it would appear as one long list of individual items:

1 2 3 c 30 a 10 b 20 

So in the above code, @array would contain 1, while we would have forced 2 into %hash. The rest of the flattened parameters (that are essentially one long list of scalar values) remain unused.

Because refs are simple individual scalars that only point to a data structure, we can pass the ref in as opposed to the list of the data structure's contents.

my @a = ( 1, 2, 3 );
my %h = ( a => 10, b => 20, c => 30 );

my $aref = \@a;
my $href = \%h;

hello( $aref, $href );

sub hello {

    my $aref_param = shift;
    my $href_param = shift;
}

In the first example, we thought we were passing in two parameters, but perl took the values from our parameters and merged them into one long list. By passing refs, our sub receives only two parameters as intended, and we can easily differentiate our array data and our hash data. This is termed "passing by reference", and it is the most common method to pass parameters to a function when the function needs more than just a few scalar values. We can now work on the refs within the sub the same way we were doing in Part 1.

When passing by reference, any changes made to the data the ref points to will be permanently changed, even after the subroutine returns. Passing data into a sub directly (not via a ref) makes an internal *copy* of the data, and when the sub returns, the original data is not modified. If it is necessary to keep your original data intact, you can make a copy of the data by dereferencing it within the function, and returning either the copy, or a reference to the copy:

my @a = ( 1, 2, 3 );

my $aref = \@a;

my @b = hello( $aref );

say "Original array:";
for my $x ( @a ){
    print "$x ";
}

say "\nReturned copy:";
for my $y ( @b ){
    print "$y ";
}

sub hello {

    my $aref = shift;
    
    # make a copy of the referenced array
    my @array = @{ $aref };

    $array[ 0 ] = 99;

    return @array;
}

Output:

Original array:
1 2 3 
Returned copy:
99 2 3

Although we've now modified our code so that we can take data structures as a parameter via their refs, we're still using "positional" function arguments, meaning that the parameters must be sent into the function in a specified order. Here's a brief code snippet of a similar example:

sub goodbye {
    my $mandatory_param_aref = shift;
    my $optional_param_aref  = shift;
}

# call it like this

goodbye( $aref1, $aref2 );

Now, what happens if we want to modify the code to accept a second optional argument?

sub goodbye {
    my $mandatory_param_aref = shift;
    my $optional_param_aref  = shift;
    my $second_optional_aref = shift;
}

# call it like this

goodbye( $aref1, $aref2, $aref3 );

No problem. However, what happens if you don't want to use the first optional parameter? You can't just do this:

goodbye( $aref1, $aref3 );

Because the function would take $aref3 and shift it off as the first optional parameter causing potentially all kinds of grief. You could send in undef in the optional positions that you don't want to supply data for so that the second optional parameter is assigned appropriately to the correct variable within the function:

goodbye( $aref1, undef, $aref2 );

But how about in a case with five optional parameters where you only want to supply the third and fifth?

goodbye( $param1, undef, undef, $param4, undef, $param6 );

Not only is that unsightly, but it is potentially very unstable code. You can see that it wouldn't be hard to position those incorrectly. There is a solution though.

NAMED PARAMETERS USING HASH REFERENCES

my %data = (
            user => 'stevieb',
            year => 2012,            
        );

my $data_ref = \%data;

user_of_the_year( $data_ref );

sub user_of_the_year {
    my $p = shift;

    my $user = $p->{ user };
    my $year = $p->{ year };

    say "Our luser of $year is $user";
}

We created a hash with the data we want to send in to our function, then we take a reference to that hash. The hash reference is what we send into the function. Inside the function, we shift off the only parameter we received (the href), and proceed to extract the values and assign them to lexical variables through the ref using the deref operator ->.

A few things to note here. First, the positional problem is gone. The function will only ever accept a single parameter; the href. Also, if the function has optional parameters, there's no undef trickery to reposition the remaining parameters. Simply omit the named key in the hash.

In the above function definition, it isn't mandatory to dereference the hash and extract its values to scalars right away. The last line could just as easily have been written like this:

say "Our luser of $p->{ year } is $p->{ user }";

However, I personally opt to extract immediately, therefore I can very quickly see what the function expects the data to look like without having to wade through the function code. Extracting in one place also makes it very easy to visually verify that your POD function use statements are accurate.

ANONYMOUS DATA

Often it is the case that you need to make a data structure on the fly, but don't need to assign a temporary name to it. We can skip steps by using references.

Instead of this two step process:

my %h = ( a => 1, b => 2 );
my $href = \%h;

We can take a reference directly from an unnamed (anonymous) hash:

my $href = { a => 1, b => 2 };

So, to create an href to an anonymous hash, we surround the data within braces instead of parens. Note that the braces are also used to distinguish hash keys. Arrays are similar, but they use their element brackets instead:

my $aref = [ 1, 2, 3 ];

In the function example above, I created the hash, took a ref to the hash, and passed the ref into the function as a parameter. Using anonymous data, I can skip creating the hash and taking a ref to it by inserting the ref to the anonymous data right within the function call:

user_of_the_year( { user => 'stevieb', year => 2012 } );

Or for more complex function calls with named parameters, you can put it on multiple lines:

sub user_of_the_year ({
                        name    => 'stevieb',
                        year    => 2012,
                        score   => 199,
                        awards  => 3,
                    });

Thank you for reading. Again, if you have any improvements or questions, leave me comments or send me an email.

2012/04/06

use Perl; Guide to references: Part 1

Understanding references and their subtleties in Perl is one of the more difficult concepts to fully wrap one's head around. However, once they are fully understood by the blossoming developer, they find a whole new level of capability and power to exploit and explore.

I often see newer programmers struggle with the concept of references on the Perl help sites I frequent. Some still have a ways to go, but many are at the stage where perhaps one more tutorial may push them over the edge and give them that 'Ahhhh' moment of clarity. My moment of clarity came when I read Randal Schwartz's "Learning Perl Objects, References & Modules" book for the something like the 8th time. Although once the concept of references is understood, the syntax and use cases can still be confusing for quite some time, especially in Perl, because There Is More Than One Way To Do It.

This tutorial is the first in a five part series. This part will focus on the basics, preparing you for more complex uses in the following four parts. I've created a cheat sheet that summarizes what you'll learn in this document.

  • Part 1 - The basics (this document)
  • Part 2 - References as subroutine parameters
  • Part 3 - Nested data structures
  • Part 4 - Code references
  • Part 5 - Concepts put to use

I will stick with a single consistent syntax throughout the series and will refrain from using one-line shortcuts and other simplification techniques in loops and other structures in hopes to keep any confusion to a minimum. Part one assumes that you have a very good understanding of the Perl variable types, when they are needed, and how they are used. Some exposure to references may also prove helpful, but shouldn't be required.

If you find anything in this document that you feel could use improvement, or if you have any questions or you feel the document needs further clarity, please feel free to provide any and all feedback via the comments section below, or send me an email.

THE BASICS

References in Perl are nothing more than a scalar variable that instead of containing a usable value, they 'point' to a different variable. When you perform an action on a reference, you are actually performing the action on the variable that the reference points to. A Perl reference is similar to a shortcut to a file or program on your computer. When you double click the shortcut, the shortcut doesn't open, it's the file that the shortcut points to that does.

We'll start with arrays, and I'll get right into the code.

We'll define an array as normal, and then print out its contents.

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

for my $elem ( @array ){
    say $elem;
}

Prepending the array with a backslash is how we take a reference to the array and assign the reference to a scalar. The scalar $aref now is a reference that points to @array.

my $aref = \@array;

At this point, if you tried to print out the contents of $aref, you would get the location of the array being pointed to. You know you have a reference if you ever try to print a scalar and you get output like the following:

ARRAY(0x9bfa8c8)

Before we can use the array the reference points to, we must dereference the reference. To gain access to the array and use it as normal, we use the array dereference operator @{}. Put the array reference inside of the dereference braces and we can use the reference just as if it was the array itself:

for my $elem ( @{ $aref } ){
    say $elem;
}

The standard way of assigning an individual array element to a scalar:

my $x  = $array[0];

To access individual elements of the array through the reference, we use a different dereference operator:

my $y = $aref->[1];

Assign a string to the second element of the array in traditional fashion:

$array[1]  = "assigning to array element 2";

To do the same thing through an array reference, we dereference it the same way we did when we were taking an element from the array through the reference:

$aref->[1] = "assigning to array element 2";

You just learnt how take a reference to an array (by prepending the array with a backslash), how to dereference the entire array reference by inserting the reference within the dereference block @{}, and how to dereference individual elements of the array through the reference with the -> dereference operator. That is all there is to it. Hashes are extremely similar. Let's look at them now.

Create and initialize a normal hash, and iterate over its contents:

my %hash = ( a => 1, b => 2, c => 3 );

while ( my ( $key, $value ) = each %hash ){

    say "key: $key, value: $value";
}

Take a reference to the hash, and assign it to a scalar variable:

my $href = \%hash;

Now we'll iterate over the hash through the reference. To access the hash, we must dereference it just like we did the array reference above. The dereference operator for a hash reference is %{}. Again, just wrap the reference within its dereferencing block:

while ( my ( $key, $value ) = each %{ $href } ){

    say "key: $key, value: $value";
}

Access an individual hash value:

my $x = $hash{ a };

Access an individual hash value through the reference. The dereference operator for accessing individual elements of a hash through a reference is the same one we used for an array (->).

my $y = $href->{ a };

Assign a value to hash key 'a':

$hash{ a }  = "assigning to hash key a";

Assign a value to hash key 'a' through the reference:

$href->{ a } = "assigning to hash key a";

That's essentially the basics of taking a reference to something, and then dereferencing the reference to access the data it points to.

When we operate on a reference, we are essentially operating on the item being pointed to directly. Here is an example that shows, in action, how operating directly on the item has the same effect as operating on the item through the reference.

my @b = ( 1, 2, 3 );
my $aref = \@b;

# assign a new value to $b[0] through the reference

$aref->[0] = 99;

# print the array

for my $elem ( @b ){
    say $elem;
}

Output:

99
2
3

As you can see, the following two lines are equivalent:

$b[0] = 99;
$aref->[0] = 99;

CHEAT SHEET

Here's a little cheat sheet for review before we move on to the next part in the series.

my @a = ( 1, 2, 3 );
my %h = ( a => 1, b => 2, c => 3 );

# take a reference to the array
my $aref = \@a;

# take a reference to the hash
my $href = \%h;

# access the entire array through its reference
my $elem_count = scalar @{ $aref };

# access the entire hash through its reference
my $keys_count = keys %{ $href };

# get a single element through the array reference
my $element = $a->[0];

# get a single value through the hash reference
my $value = $h->{ a };

# assign to a single array element through its reference
$a->[0] = 1;

# assign a value to a single hash key through its ref
$h->{ a } = 1;

This concludes Part 1 of our Guide to Perl references. My goal was not to compete with all the other reference guides available, but instead to complement them, with the hope that perhaps I may have said something in such a way that it helps further even one person's understanding. Next episode, we'll learn about using references as subroutine parameters.

Update: An astute reader sent me an email after noticing that this tutorial does not mention scalar references at all. This was a design choice. I didn't feel it necessary to justify the extra space to explain them, as they are very rarely used. They do exist though :) Thanks Asbjørn Thegler for the kind email!