Check Your Facts!

Disclaimer: This is a bit of a rant. Not something I do often, but I feel this particular point is relevant and frustrating to a number of people besides myself.

I am getting tired of reading blatently wrong, un-researched, and yet boldly-declared information posted on the web. Not postings on puny personal blogs (like mine), those I can forgive. Instead, I’ve been seeing news items and statements on supposedly trustworthy sites that just don’t get the facts straight. This has been particularly and most recently true with the slew of press releases covering the release of Perl 5.10.

For example, take this article on LinuxDevices.com. Like several other press releases, they claim:

Just in time for Christmas, there’s a new version of perl, the first in over five years.

Perl 5.10 is not the first release in 5 years — it is the first feature release in that time. That is a big difference. There have been many stable releases since 5.8.0 that fixed bugs and improved Perl’s performance and stability, which paints an entirely different picture from what the article actually says. Their news item makes it sound as though Perl is an unsupported and inactive language, which is entirely untrue.

Also, the paragraphs comparing Perl to Python, Ruby, and PHP is laughable — and I’ve seen this exact text on several sites (eweek.com, for example). Yes, there are a lot more people using those languages today, and they are growing, but Perl still holds a formidable share of the dynamic language job market and that doesn’t appear to be changing rapidly. Don’t claim that Perl is a dying language unless you can show evidence.

Please check your facts before you post! It’s better to be correct than first.

(And FYI: Ruby is not a language “specially-made for use on the Web”.)

Understanding Object-Oriented Perl

Have you ever wondered what it is you’re doing when you write object-oriented Perl? What is the @ISA array for, and what on earth does bless do? About a week ago I was sitting at BW3 with several members of the Grand Rapids Java Users Group who had those same questions. Read on for what I hope are relatively simple answers to those questions and a few others.

Class declaration

Creating a new class in Perl is simple: just declare a package (or a namespace, if you prefer that term) and start adding methods in that package. For example:

package My::Animal;
sub new {
    # ...
}
sub sound {
    # ...
}
1;

Place this code in a file called Animal.pm in the My/ directory and, as long as the parent directory of My/ is in Perl’s include path, it is easy to include this class in other Perl programs:

use My::Animal;
my $animal = My::Animal->new;

Object creation

If you’ve written any object-oriented Perl code, you’re probably familiar with this basic constructor:

sub new {
    my $proto = shift;
    my $class = ref $proto || $proto;
    my $self = {};
    bless $self, $class;
    return $self;
}

First, let me be clear about the name new: it is not special. You could just as easily name your constructor create or build. Again, there is nothing special about the name new. What is special about the constructor is what it does, so let’s step through it line by line.

my $proto = shift;

One of the invisible things happening here involves a special Perl variable often referred to as the default list: @_. We call it the default list because operators like shift and grep operate on this list by default if no other list is given. So, this line could be rewritten as: my $proto = shift @_; and it would mean the same thing.

In the context of a subroutine (or method — they’re basically the same thing) this default array contains the parameters passed in by the caller. When you call a method on an object or class, the first parameter is always the object’s reference or the class name, depending on how it is called. So what we’re doing here is assigning this first parameter to the lexically scoped variable $proto. So now $proto contains either the object that this method was called on or the name of the class.

my $class = ref $proto || $proto;

Because $proto might be either the object (a reference) or the class name (a string value), we have to do something to reliably get the class name for use later. The ref operator takes an object and returns the class name for that object or nothing if it was not given an object. So, what we’re saying here is, “Give me the class of this object or, if it was not an object, assume $proto was the class name to begin with.”

my $self = {};

Create a reference to a hash. People often use this hash as a place to store instance variables because it will be passed to all method invocations for this object.

bless $self, $class;

The bless function takes two arguments: a reference and a class name. What it does is tell Perl that the given reference is actually an instance of a specific class so that, when you call a method on your object, it knows where to start looking for the method definitions.

return $self;

Return our newly created and blessed object.

Calling object and class methods

I’m assume that you are familiar enough with object-oriented programming to understand the difference between an object method and a class method…

Class methods

These are all ways to call a class method:

$dog = My::Animal->new(@args) # my preference;
# Or, using indirect object syntax
$dog = new My::Animal @args;
$dog = new My::Animal(@args);

Class methods receive a list of arguments in @_ (the default list — remember?). The first of those arguments is the name of the class the method was called on. Going back to our constructor, the class name is stored in $proto and then in $class when the ref function returns nothing.

Object methods

These are all ways to call a method on a specific object:

$sound = $dog->sound(@args);
$sound = sound $dog @args; # Indirect object syntax (discouraged)

Object methods also receive a list of arguments in @_, though this time the first argument is the object that the method was called on. That is why, in most object method definitions, you will see the first line is something like my $self = shift;. The object, because I use a blessed hash reference, can be used to store and retrieve our instance data during object method invocations. For example:

package My::Animal;
sub new {
    my $proto = shift;
    my $name = shift;
    my $class = ref $proto || $proto;
    my $self = {
        name => $name,
    };
    bless $self, $class;
    return $self;
}
sub name {
    my $self = shift;
    print "Hello, my name is $self->{name}n";
}

Note that indirect object syntax is discouraged when calling object methods due to potentially ambiguous syntax, and possibly other issues I’m not aware of. I prefer the first invocation method using the arrow operator for both object and class methods.

Inheritance

Inheritance in Perl works a lot differently than any other language I’ve ever used (Java, Ruby, Python, C++). Let’s set up a simple example to work through.

package Animal;
sub new { ... }
sub live { print "I'm alive!n"; }
sub speak { print "Animals can't speak.n"; }

package Dog;
use Animal;
use vars qw(@ISA);
@ISA = qw(Animal);
sub speak { print "BARK!n"; }

package Beagle;
use base qw(Dog);

So, we have a base class Animal that provides a constructor called new, a Dog class that inherits from Animal, and a Beagle class that inherits from Dog. As you can probably guess by looking at the Dog class, the @ISA array declares what classes we inherit from. That’s right: Perl supports multiple inheritance — more on that in a minute. You probably also noticed that there are two ways to set up inheritance.

Package Dog does things the older way by use-ing the package and then manually placing it into the @ISA array. This has some downsides, not the least of which is that it clobbers anything that happened to already be in the inheritance list. The preferred method is to use use base as demonstrated in the Beagle class.

Method resolution order

Like I said before, Perl does things its own way. Remember the bless function from our constructor? It tells Perl that a given reference belongs to a specific class. When a method is called on that reference, Perl starts with its class and looks for a method definition with that name. If it doesn’t find it, Perl checks the first class in the @ISA array. If not found there, it checks that class’ first @ISA array entry. Continuing this pattern, Perl performs a depth-first search until it finds a method with the correct name and executes it.

See Class::C3’s documentation on CPAN for more discussion on the topic of method resolution order.

In the end

Hopefully you’re feeling a bit more confortable with OO Perl now and understand some of the unique pieces that make this language what it is. If you’re still craving more information, try the following sources:

Looking toward Perl 5.10

I haven’t been paying a lot of attention to the development of core Perl lately, but a few headlines caught my attention this week and I decided to do some catching up. Per Perl Buzz, Perl 5.10’s first release candidate is coming soon. This will be the first feature release of Perl since 5.8 in 2002 and there are several interesting new features worth mentioning.

What did you say?

I’ll start with something simple but useful: the new built-in command say. It operates the same as print, but adds a newline to the end of the string printed. My pinky finger will enjoy that added convenience.

Not just a case statement

I’ve never been one to complain about Perl’s lack of a proper case statement, though I can understand why it might be nice to have. Let’s take a look:

my @in_here = qw(one two three);
my $blah = 'blather';
given ($blah) {
    when ('blather') { say "it equals blather" }
    when (/something/) { say "it matches 'something'" }
    when (/^d$/ && $_ < 100) { say "it is less than 100" }
    when (@in_here) { say "it is in the array" }
    default { "Didn't match anything" }
}

In typical Perl fashion, the code reads nicely but is a bit different from other languages. We have given, which kicks off the case statement and identifies what we’ll be switching on. The word when declares each case and default is an optional construct to handle the case when no others match. The most interesting part, though, is the way it tries to do what you want when matching each individual case. It does this using the another interesting new operator called the smart match.

Smart matching

Smart matching is perhaps the most innovative new feature in Perl 5.10. It is a new operator that can be used to inteligently compare two arguments of nearly any type. Take a look at a few examples:

$a ~~ $b; # same as $a eq $b or $a == $b
          # depending on whether one is a number
%a ~~ %b; # are keys identical?
@a ~~ @b; # do arrays contain same values in same order?
@a ~~ %b; # hash value slice truth
⊂ ~~ $a # truth of ⊂($a)

See the full table if you’re curious about the rules it uses to run its comparisons. I’m a bit concerned that this new feature tries to be too smart, but I’ll wait a while to pass final judgement.

Defined vs. truth

Back to something a bit simpler, there is a shiny, new “or” operator for Perl users to flaunt. It is very similar to the existing || operator but concerns itself with definededness instead of truth value. For example:

$a = 0;
$b = 'blah';
$c = undef;

$a || $b # 'blah'
$a // $b # 0
$c || $b # 'blah'
$c // $b # 'blah'

This looks like a very useful shortcut and I think will help clear up some of the confusion around what is considered true/false or defined/undefined. Again, I will probably find myself wishing I could use this in my perl 5.8 scripts.

That’s not all!

For a more comprehensive list of new features in Perl 5.10, I recommend Ricardo Signes’ presentation: Perl 5.10 for people who aren’t totally insane. Until next time…

Perl Survey Results: US Perl Mongers

Because I am the vice president of our local Grand Rapids Perl Mongers group and also because I believe that participation in local user groups is extremely valuable, I was curious to see what the Perl Survey 2007 data would show with regard to user involvement in Perl Mongers user groups across the United States. In Part I, I also promised a more interesting analysis — one without a focus on salary information: this is it.

Types of Involvement

First, let me define what I mean when I say someone is involved with a Perl Mongers group. There were four questions on the survey regarding Perl Mongers:

Have you, in the past year,

  • Attended a Perl Mongers meeting?
  • Attended a non-local Perl Mongers meeting?
  • Posted to a Perl Mongers mailing list?
  • Subscribed to a Perl Mongers mailing list?

For the sake of simplicity, I reduced those four questions into two types of involvement: attending meetings, and using the mailing list. If a survey taker did not answer in the affirmative to at least one of the four questions I consider them not involved in a Perl Mongers group. Otherwise, they are involved in at least one of the two ways I presented. The following pie chart shows the relative proportions of the different types of involvement.

Pie chart of PM participation types

It appears most people who attend meetings are also involved in using the e-mail list, making the list the most common method of involvement for Perl Mongers groups.

There is also a large contingent, 61.2% of reporting Perl users, who are not involved in a Perl mongers group. Is that a significant level of involvement? I have nothing to compare it to, but 38.8% involvement in Perl Mongers sounds reasonably good.

Age of Participants

Who participates in Perl Mongers? That is a good question, and I will start by painting a picture of the age distribution of Perl Mongers participants.

Number of PM Participants by Age Group

It is easy to see that the different types of involvement follow each other closely. A large percentage of participants are in the range of 25 to 39 years old, which looks relatively close to what I expected and represents our local group well. I also put together a graph to show, for each age bracket, what percentage of respondants were involved in Perl Mongers.

Percent PM Participation by Age Group

The range of 20 to 39 years old shows a relatively steady upward trend in involvement that tapers off slowly from 40 on, though I do not find the variance extremely significant. I am curious about the dip at 45 to 49 years, though I have yet to find any meaning in it.

In general, Perl Mongers shows consistant involvement from most age groups. If there is an age group we should target in our marketing I think it is the 18- to 24-year-olds (e.g. college students and recent graduates) because their involvement percentage is slightly lower and they likely have a lot to learn and contribute.

Involvement vs. Experience with Perl

Another angle I wanted to see was the correlation between the number of years of Perl programming experience and the respondants participation in Perl Mongers. Much like the percent participation by age above, this graph shows the percent participation broken down by number of years of experience writing Perl.

Percent PM Participation by YOE Perl

There is a steady increase in involvement from 0 years up through 8 years of experience. It dips slightly at 9 years and then shoots way up at 10 before settling back down to a more normal level until we reach the outliers around 20 years and on. There were fewer than ten responses for the entries out past 20 years, so I would not place too much emphasis on them as they do not contribute much to the analysis of the trend.

I have to admit that the huge spike at 10 years is puzzling. It could be that 10 years is just a common answer for people who have been writing Perl for “a long time,” and that they happen to be a very involved crowd. Or, perhaps there was a marketing push or general excitement over Perl about 10 years ago and we see now the results of that. I just don’t know.

We see here that, once again, the distribution of participation is fairly even, especially above 5 years of experience. For that reason, I suggest we have the most to gain by marketing to new Perl users (less than 5 years of experience) and getting them involved in our local groups.

Averages and Conclusions

The average US Perl Mongers participant, whether on the mailing list or in person, is a 36-year-old man with about 9 years of Perl experience and 18 years of general programming experience.

After looking over the various graphs and averages, I can say with confidence that Perl Mongers groups are a fantastic resource for the beginner and expert alike. My involvement with the Grand Rapids Perl Mongers group also confirms that. Still not convinced? Fine, I’ll bring out the salary information again: the average Perl Monger makes $6,445 (7.88%) more than their non-participating counterparts. That figure jumps to $7,336 (8.97%) if you attend meetings. Do I have your attention now?

I highly recommend that you check out your local Perl Mongers group if you have not already. Or, if there is not a group near you, consider starting one.

Perl Survey Results: Part I

Take note, all you aspiring statisticians! The Perl survey data has been released and it’s time to get to work. I expect nothing less than a horde of different and interesting break-downs and mashups in the coming weeks, so to get things rolling I thought I’d put together a quick overview of the programming experience and salary information for the five countries that sent in the most responses.

To start, I had to find a way to represent the pay ranges the survey takers were given to chose from as a single value, so I went with the average of the minimum and maximum for the range. Not perfect, I know, but it should suffice for the purpose of this relatively high-level comparison.

Quick Overview

The following table shows the five countries that sent in the most responses to the survey, in order of number of responses, along with the average salaries and years of experience of their respective Perl programmers. Not very complex, but a fun first look at this new information.

Country (responses) Years Programming Years with Perl Salary
United States (1279) 16.9 8.3 $84,257
UK (384) 17.0 8.0 $76,431
Australia (187) 17.0 8.3 $70,775
Germany (150) 16.6 8.3 $57,400
Canada (96) 15.7 7.7 $64,114

80% or more Perl

So what happens if we restrict this to people who said their job was 80% or more Perl? First of all, a little less than half the responses fall out of scope. Also, it appears both the average salary and years of experience with Perl increase slightly. The experience and salary increase is most prominent in Canada — interesting…

Country (responses) Years Programming Years with Perl Salary
United States (709) 16.7 8.6 $86,255
UK (183) 16.4 8.2 $81,065
Australia (102) 16.8 8.6 $72,401
Germany (86) 16.3 8.4 $57,209
Canada (45) 17.0 8.6 $69,555

That’s all for now, but check back again because I hope to have far more interesting information to present the next time around, focusing more on community participation and less on the salary figures. After all, that’s not why we write Perl. Okay, at least not the only reason.

Related posts: