These links are collected from the Perlbuzz Twitter feed. If you have suggestions for news bits, please mail me at andy@perlbuzz.com.

Why roles in Perl are awesome

| 2 Comments

by Chris Prather

A question came up recently on a mailing list. I was talking about how Roles are a awesome win for Perl5 considering how few languages implement the concept1. Someone asked what the win was with Roles. I happen to have been thinking about this recently and dashed off a reply.

When you use Inheritance, especially multiple inheritance, for behavioral re-use you run into several problems quickly.

First Inheritance is an explicit modeling of a relationship that carries semantic meaning. Let's say you're developing a game for Biology students to explain to them taxonomy. In this game a Dog class is a subclass of Animal. That is, the Dog class inherits specific behaviors and attributes from the Animal class. This probably isn't even a direct relationship your Dog class may inherit from a Mammal class which inherits from a Vertebrate class which inherits from Animalia which itself inherits from Life. These kinds of hierarchies are common in Taxonomy as well as in Object Oriented programming. However when you need to express something that may cross cut concerns in, you run into issues.

Say for example your marketing department has had trouble selling this product to schools and is attempting to market to parents directly. They have done studies and kids really like Pets2. So your boss comes to you because the company wants you to add the concept of Pet to your Taxonomy model.

Pets don't fit into a Taxonomy, it's obvious that not all Animalias are Pets3 and some Pets may not be animals at all4. In many languages can use Multiple Inheritance to describe this new "I'm an Animalia and a Pet" relationship but often you run into issues there as well. Is a Pet a Life? That would mean our object model would look like:

Life
    Animalia
        Vertebrae
            Canine    Pet
                Dog

Pet stands out like a sore thumb. Obviously we've got issues with this new modeling. We talk to our boss and figure out that the rules for Pet are simple. Pet's are always domesticated versions of the Animalia, but not every class in Animalia is a pet. So for example Dogs are always Pets, Wolves are not. We can solve this with multiple inheritance now, but it's really not a clean way to express the relationship and it requires us to document the special relationship the Pet class would have with the rest off the Inheritance tree. Once you get beyond a few "special cases" like this it becomes hard to see the model for the exceptions.

This is why some languages like to disallow multiple inheritance entirely. In Java for example, Pet could become an Interface.

public interface Pet {
    Date getYearDomesticated;
}

This however means that every class that we want to be a pet needs to have the exact same piece of boiler plate code added to it.

class Dog implements Pet {
    ...
    private Date yearDomesticated;
    public Date getYearDomesticated () { this.yearDomesticated }
    ...
}

If we instead have the concept of Roles then we can apply the concept of a Pet once at any level of the hierarchy we need. A example using a modern Perl5

package Pet {
    use Moose::Role
    has year_domesticated => (
        is => 'ro',
        isa => 'DateTime',
        required => 1
    );
}

package Dog {
    use Moose;
    extends qw(Canine);
    with qw(Pet);
}

The Pet Role here implements everything we need for a default implementation, and doesn't require more boiler plate to our Dog class, that the bare minimum needed. It also avoids the ugly inheritance issues we saw with multiple inheritance by moving the behavior composition onto different tool. In my opinion, Roles aren't a win for every use of inheritance, nor for every time you want to re-use behavior, but they are an excellent tool to have in the box and one that the Moose crowd knows to reach for quite often.


  1. Off the top of my head I only know about Perl5, Perl6, Scala, Javascript, and Smalltalk. There may be other implementations out there. ↩

  2. The Marketing guy's daughter plays on WebKinz nightly. ↩

  3. Pet Shark's would be dangerous to say the least, and where would you keep a pet Blue Whale? ↩

  4. Who doesn't love their Pet Rock? ↩

  5. We're using the the inline package syntax that will be released in 5.14 ↩

Chris Prather is an Owner at Tamarou LLC, a member of the Moose cabal, and responsible for Task::Kensho.

These links are collected from the Perlbuzz Twitter feed. If you have suggestions for news bits, please mail me at andy@perlbuzz.com.

These links are collected from the Perlbuzz Twitter feed. If you have suggestions for news bits, please mail me at andy@perlbuzz.com.

Diversification in bug tracking has come to the CPAN. Module users cannot assume that the bug tracker for an individual module is at rt.cpan.org. Before submitting bug reports, users should check the distribution's page on search.cpan.org for a link to the bug tracker, and also check the documentation for the module. When in doubt, go with the documentation.

It used to be simpler....

Over ten years ago, when CPAN only had a few thousand distributions, and free project hosting was Sourceforge or nothing, Jesse Vincent stepped up to create rt.cpan.org. It was, and is, a fantastic service. Module authors now had free, centralized bug reporting that they didn't have to maintain themselves.

Jesse's RT setup also has the advantage of integrating with PAUSE and the CPAN. CPAN is the Comprehensive Perl Archive Network, and PAUSE is the Perl Author Upload Server. When a module author has a distribution for release, she uploads the file to PAUSE. From there, the servers that make up the network part of CPAN mirror the file for your use. Jesse set up RT to check the PAUSE for new distributions, and when one was found, RT would automatically create a bug queue for that module. It's still a fantastic system, and we should all thank Jesse for maintaining it.

For years, the Perl community has been enjoying the fruits of rt.cpan.org. It's become part of Perl culture. The home page for each module on search.cpan.org includes links to the RT page. When authors create modules with Module::Starter, the module's documentation refers the reader to the specific bug queue. People just knew that it was there. Everyone knew you could email to bug-distro-name@rt.cpan.org to have a bug reported.

But RT has never been the the only bug tracker available, and the alternatives are getting more and more use. SourceForge has had bug tracking for quite a while, but when Google Code came out with project hosting and bug tracking, things started changing. Now, Github has taken the Perl world by storm. For the first time ever, we module authors had solid alternatives to RT that we didn't have to create ourselves.

That leads us to today, where the Perl world is continuing to diversify. Module authors can choose the bug tracking system that suits them, and their users, best. That system may no longer be RT.

Which bug trackers are getting used?

When I checked last week, I found 106 distributions that were using bug trackers other than RT, spread across 10 different domains.

For example:

  • http://code.google.com/p/perldts/issues/list
  • http://github.com/ap/Object-Tiny-Lvalue/issues
  • https://gna.org/bugs/?group=testautobuild
  • http://sdlperl.ath.cx/projects/SDLPerl
  • https://issues.apache.org/SpamAssassin/
  • http://sourceforge.net/tracker/?group_id=199719
  • http://padre.perlide.org/trac/
  • http://www.w3.org/Bugs/Public/
  • https://openmelody.lighthouseapp.com/projects/26604-melody
  • http://www.veripool.org/ipc-locker-bugs

I was surprised the number of distributions was only 106. I suspect that there are many module authors who don't know how to specify an alternate bug tracker in their distributions. In my next article, I'll explain how to do that.

The dual-licensing in much module boilerplate these days is unnecessary. You can simplify your licensing by using only the Artistic License 2.0.

There are plenty of modules out there that license themselves "under the same terms as Perl itself", and there are problems with that approach. For the past year or so I've been using the approach of being explicit about "Artistic or GPL, your choice", but that's unnecessary, too.

According to Allison Randal, one of the architects of Artistic License 2.0, "Artistic 2 allows for any GPL-like license, not just GPL 2. Specifically, it allows for GPL 3 or later, or a completely non-GPL copyleft license. So, the dual license is unnecessary."

There's a page on the Perl Foundation website about CPAN licensing guidelines that explains more options in more detail.

From here on out, my code is going to say:

=head1 LICENSE

Copyright (C) 2010, Andy Lester,

This module is free software.  You can redistribute it and/or
modify it under the terms of the Artistic License 2.0.

This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose.

Allison Randal has some insights from her Twitter stream today about how open source is more than just a way to create and share code.

Open source isn't just a licensing/business strategy, it's a better way of producing software and a better way of training developers. The driving principle of the academic model is to make students fail. The bell curve rules, if all students pass something is 'wrong'. The driving principle of open source is to help each developer reach their own greatest potential. Good developers are good for the project.

These links are collected from the Perlbuzz Twitter feed. If you have suggestions for news bits, please mail me at andy@perlbuzz.com.

How to shuffle a list in Perl

| 1 Comment

If you've got a list of things in Perl, and you want them in random order, don't try to make up a way to do it yourself. Use the shuffle function in the List::Util module. Say you want a list of files from a directory:

use List::Util qw( shuffle );
my @files = glob( '*' );
@files = grep { -f } @files;
@files = shuffle @files;

Of course you can combine that into one expression:

use List::Util qw( shuffle );
my @files = shuffle grep { -f } glob( '*' );

Or from the command line:

perl -MList::Util=shuffle -le'print for shuffle grep {-f} glob("*")'

Don't worry that List::Util is a module, because it's a core module that's been included with Perl since 5.7.3

$ corelist List::Util

List::Util was first released with perl 5.007003

The shuffle function is extremely simple, and how here's a little article that explains why it works.

Sent to editor of DrDobbs/InformationWeek

I enjoy Sid Sidner's article on static code analysis tools, but was surprised to see two big omissions, especially as they may provide a low-cost point of entry to the organization just starting to look at static analysis.

First, PC-Lint is a relatively low-cost tool that does a fine job of C/C++ analysis. It's been around for years, and has found many C bugs in my code back in the early 90s. I've also been using the open source Splint, for years on the Perl 5 and Parrot open source projects. Although Splint's not nearly as complete a package as Coverity's Scan product (Coverity runs Scan on dozens of open source projects for free as a service to the community), it's a great introduction to the power of static code analysis tools. I also suggest readers check the "List of tools for static code analysis" page on Wikipedia.

Second, one crucial point missed is how any tool is going to require tuning. Splint will generate hundreds of errors in each source file on its first run on your code, since nobody in the real world is as pedantic as the tool is. Each organization will have to decide which policies are worth following, and which are just noise.

Finally, static code analysis isn't strictly for C++ and Java. Many dynamic languages have similar tools. For example, Perl::Critic is a fantastic tool for analysis of Perl code, as well as an extensible framework that lets each organization create custom policies to fit its own development practices.