Symbolic references in Perl

One of the 3 things use strict disables is the use of symbolic references.

Let's see how can that save you time and avoid embarrassment!

Let's see why avoiding symbolic referrences is a good thing!

At another time we'll see a useful example of symbolic references.

In general, symbolic reference is a very powerful tool in Perl, but if used by accident it can cause a lot of head scratching. Best to disable them in every script, and enable them only when we know exactly why we need them.

The danger

A long time ago, in a Perl training session, we had some discussion that led me mention that you can use the same name for both scalar variables and arrays and hashes. It is not a recommended practice but technically it is possible. I got carried away a bit and wanted to show the students that it works. So I wrote the following code:


  my $person = "Foo";
  my %person;
  $person->{name} = 'Bar';

...and explained that I declared the $person scalar, assigned "Foo" to it. Then created a hash with the same name and put a key and a value in it. To further show it works I printed out the content of the hash:


  use Data::Dumper;
  print Dumper \%person;

To my great surprise the following was printed:


  $VAR1 = {};

I was quite baffled. Where did the new key/value pair go?

I had really no idea what happened.

The situation was quite embarrassing.

Luckily we had lunch break and just after I finished the soup it occurred to me that I have not used strict in my code.

The understanding

Returning to the class-room I added use strict and ran the code again:


  use strict;
  use Data::Dumper;

  my $person = "Foo";
  my %person;
  $person->{name} = 'Bar';

I got the following error message:


  Can't use string ("Foo") as a HASH ref while "strict refs" in use at ...

Accidentally I was using a symbolic HASH reference.

In fact, I never touched the %person hash. In the second assignment I used the $person scalar as a reference to a hash. This would be OK if the variable $person was undef but as it already contained a string Perl was trying to use that name, as the name of a hash. Effectively I assigned 'Bar' to the 'name' key of the %Foo hash. This is how you can check it too:


  use Data::Dumper;

  my $person = "Foo";
  my %person;
  $person->{name} = 'Bar';

  print Dumper \%person;
  print Dumper \%Foo;

And the output is:


  $VAR1 = {};
  $VAR1 = {
          'name' => 'Bar'
        };

As you can see, the first print of the %person hash is empty but the %Foo hash sprang to existence and has a 'name' key with 'Bar' as the value.

Since Perl has real references you almost never need this capability and if such thing happens by mistake then it is way better to get an error than to silently do the wrong thing.

So always use strict.


Perl tutorial

For further articles see the Perl tutorial.

Published on 2011-11-19 by Gabor Szabo

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


Google Plus Twitter RSS feed