Showing posts with label cpan. Show all posts
Showing posts with label cpan. Show all posts

Thursday, 30 April 2015

My March & April CPAN PR Challenge dists

As I got ready to blog about my PR Challenge assigned dist for April, I realized I had forgotten to blog about my last month's assigned dist, so I have decided to write a joined march/april report :)

March distribution: Web::Library::UnderscoreJS


This neat module by Marcel Grünauer is a wrapper for the Underscore JavaScript library, which itself provides over a 100 functional helpers and goodies for your frontend programming like function binding, JS templating, quick indexes, and much more.

The wrapper comes from Web::Library, a general manager for client-side dependencies. Say you have a web application. You spawn the Web::Library singleton and mount the libraries you want to use (Underscore in our case):

    my $library_manager = Web::Library->instance;
    $library_manager->mount_library({ name => 'UnderscoreJS' });


Then you set the include_paths() from the instance as directories to search for static files. In Catalyst, this can be achieved with Catalyst::Plugin::Static::Simple, like so:

    __PACKAGE__->config(
        'Plugin::Static::Simple' => {
            include_path => [ $library_manager->include_paths ] },
        ...
    );


Then pass the instance to your templates and call the appropriate methods to print the required CSS/JS lines:

    <head>
        ...
        [% web_library.css_link_tags_for('UnderscoreJS') %]
   
</head>
    <body>
        ...
        [% web_library.script_tags_for('UnderscoreJS') %]
   
</body>

My pull requests for this distribution involved bumping up the copyright year, some minor pod formatting issues, updating the UndescoreJS library versions (up to 1.8.2), and adding a Travis-CI code badge. I also investigated some CPAN Testers failure reports for this distribution on MS Windows, but they turned out to come from Web::Library itself. Nevertheless, I also send a PR with a fix and another one that reduced the minimum perl version to 5.6, which was asked in an open issue.


April distribution: Mojolicious::Plugin::ServerStatus


This is a plugin for Mojolicious that shows server status information, similar to Apache's mod_status. It is based on the general Plack::Middleware::ServerStatus::Lite middleware and works on multiprocess servers like morbo and hypnotoad. It's not able to monitor keepalive sessions and network I/O wait, but it still gives some nice output in different formats.

All you have to do is load the plugin and tell it which route path to render. Optionally, for security, you can set which IPs to allow:

    plugin 'ServerStatus' => {
        path => '/server-status',
        allow => [ '127.0.0.1', '192.168.0.0/16' ],
    };


That's it! After the server is up, all you have to do is query the proper path:

    % curl http://server:port/server-status
    Uptime: 1234567789
    Total Accesses: 123
    BusyWorkers: 2
    IdleWorkers: 3
    --
    pid status remote_addr host method uri protocol ss
    20060 A 127.0.0.1 localhost:10001 GET / HTTP/1.1 1
    20061 .
    20062 A 127.0.0.1 localhost:10001 GET /server-status HTTP/1.1 0
    20063 .
    20064 .


You can also ask for JSON output format:

    % curl http://server:port/server-status?json
    {"Uptime":"1332476669","BusyWorkers":"2",
     "stats":[
       {"protocol":null,"remote_addr":null,"pid":"78639",
        "status":".","method":null,"uri":null,"host":null,"ss":null},
       {"protocol":"HTTP/1.1","remote_addr":"127.0.0.1","pid":"78640",
        "status":"A","method":"GET","uri":"/","host":"localhost:10226","ss":0},
       ...
    ],"IdleWorkers":"3"}


Unfortunately, this distribution didn't have any contents in the main github repository, so instead of making several branches off of master, I used my own master branch and made one commit per change in a single pull request. The first commit of course was just a sync between the repository and the version available on CPAN. Other commits included updating the README, setting up the proper dependencies (which should fix current failure reports from CPAN Testers), adding a Changes file which was missing from the dist, and some minor pod fixes.

That's it! Hopefully those commits and pull requests will be useful to the authors (and users too). And now I can't wait to see what Neil Bowers have picked for me next month :)


Saturday, 14 March 2015

How to add online code badges to your Perl projects


If you hang around Github you might have seen a lot of projects adding extra information to their README files in the form of badges, like so:

screenshot of badges shown on Clone's README file













Not only do they make your project's Github page look cooler, they also help developers, from curious potential users to regular contributors, easily spot how active and healthy is the code.

Wanna join in on the fun? There are several free code badges out there for you to use, and these are the ones (that I know of) that work for your awesome Perl code! \o/

Travis CI


Travis CI is a continuous integration service used to build and test projects hosted on Github. They'll let you know whether your code builds and tests pass in many different versions of perl (but, unlike CPAN Testers, they'll do it in only one platform). Using their service is super simple:

1. Go to the Travis CI homepage and sign in with your Github account. It's the big link in the top right corner of the page, you can't miss it :)

2. If this is your first rodeo, you'll see Travis CI asks for some permissions on Github. You must allow it to proceed. They have outlined the whys and hows if you're feeling cautious.

3. Go to your Travis CI profile page and wait for all your repositories to sync. Once they're all listed in there, it should look something like this (with, of course, your own name, groups and projects):

 4. See that "on-off" switch next to each of your repositories? Just flick the ones you want to have a Travis CI report. We're almost done!

5. Add a file named .travis.yml to the root of your project repository (note the "." in front of the filename!). It should contain valid YAML with the main language and the different versions of Perl 5 you want to test against. For example, if you want to test against 5.14 and 5.20, your ".travis.yml" should look like this:

language: perl
perl:
  - "5.14"
  - "5.20"

If you need any extra information or customization of your perl builds, just read Travis CI's Perl specific documentation. Note that if something goes wrong (e.g. you make a typo in the filename or its contents), Travis will assume you're testing against the current stable version of Ruby, which is definitely not what you want :)

A few moments after you commit it to your repository and push it to Github, go back to your Travis CI profile page and you should be able to see the build results! If you skipped a step and added the ".travis.yml" file to your repo before enabling the project in the Travis CI page, just push any commit to trigger it.

6. Badge time! Make sure your README file is in Markdown - just rename it to README.md and adjust it as you see fit (it's also a great way to make your project stand out while still making it readable as plain text). Then go to your Travis CI profile and click on the project you want to add the badge. You should see the badge right next to the project's name. Click on it and it's going to let you copy the badge for your project in several formats:



Choose "Markdown" and paste it on your README.md file. The one from Clone, as you can see from the picture above, looks like this:

[![Build Status](https://travis-ci.org/garu/Clone.svg?branch=master)](https://travis-ci.org/garu/Clone)

After pushing your changes, go to your project's Github page and see the badge in all its glory!

Coveralls


Now that we have Travis CI doing some tests for us, how about we get some test coverage reports also? That's where coveralls.io comes in!

1 & 2. Just like we did with Travis CI, go to the Coveralls home page and sign in with Github, granting them access to your repositories.

3. The Coveralls repository page will list all projects being analyzed for coverage, and now is probably the time to click the "add repos" button on that page and add the ones you want coverage analysis of.

4. Adjust your .travis.yml file to add code coverage. Coveralls is engine agnostic so we'll use the not nearly enough praised Devel::Cover suite to do the hard work, together with the Devel::Cover::Report::Coveralls interface. Basically, Travis CI gives us a lot of granularity while building and testing our projects, so we tweak it to include coverage commands in the appropriate build steps.

There are a few ways to go about it: in the manual way we export the environment variables we need and install the coverage dependencies. For instance, we could update our file above to look something like this:

language: perl
perl:
  - "5.14"
  - "5.20"

install:
     - export RELEASE_TESTING=1 AUTOMATED_TESTING=1 AUTHOR_TESTING=1 HARNESS_OPTIONS=c HARNESS_TIMER=1
     - cpanm --quiet --notest Devel::Cover::Report::Coveralls
     - cpanm --quiet --notest --installdeps .

script:
     - PERL5OPT=-MDevel::Cover=-coverage,statement,branch,condition,path,subroutine prove -lrsv t
     - cover

after_success:
    - cover -report coveralls


in the automatic way, we delegate most of the work to some fine-tuned helper scripts created just for Perl projects on Travis and Coveralls. The same original .travis.yml file would, in this case, look like this:

language: perl
perl:
  - "5.14"
  - "5.20"
matrix:
  include:
    - perl: 5.20
      env: COVERAGE=1
before_install:
  - eval $(curl https://travis-perl.github.io/init) --auto


To me this one looks much easier to read, as most of the complexity is enclosed in the "init" script of the well maintained travis-perl project. I highly recommend it. In fact, after you get it right for your code, I suggest you go read their helper intro and play with some settings, you won't regret it. Also, check out Moo's .travis.yml file for a glimpse of all the cool stuff you can get, from testing against blead perl to reporting on a specific irc channel!

5. Now that your commits are tested on Travis CI and reported by Coveralls (mind you, it might take several minutes for a build coverage to show up, and they only start after you push to Github *after* having activated Coveralls and pushed your .travis.yml file), let's put a badge on your README!

On the project listings on Coveralls, click on the project to go to its page, and you should see a badge right at the top, with a "BADGE URLS" link next to it. Click on that link to copy your badge in several different formats, like so:


Put the markdown code on your README.md file next to the Travis CI badge (or wherever you see fit) and that's it!

Version badge


This one really comes in handy for Github, as it lets your users know exactly what's the current stable version on CPAN and how to get it, and it's also by far the easiest to set up: just go to the Version Badge link for Perl projects and type in the name of your target dist (note that it's The-Distribution-Name, not The::MainModule::Name). Once you click on "Find", it's going to give you the badge in several different formats ready for use:


Showing your badges on MetaCPAN


Now that your README.md is all shiny and colorful with badges, your project's Github page is starting to look even cooler than the MetaCPAN page, and that's just not cool. MetaCPAN's web interface is awesome and it will look even better when you put your brand new badges in it, so let's get on with that.

Perl's Pod format allows us to to specify sections that will only show when a given format is supported. For instance, if you write this in your pod:

=for html
<img src="http://example.com/path/to/some/image.png" />

Then this block will render the image when the renderer supports html (like the MetaCPAN web interface), and not do anything on renderers that don't support it (like your command line "perldoc"). Pretty cool, right? Graphic modules and tutorial-like documentation have been taking advantage of this feature for years, and we should too!

So go to the links above and find the HTML version of the badges, then put them in a "=for html" paragraph at the top of your Pod. For the Clone module they look like this:

=head1 NAME

Clone - recursively copy Perl datatypes

=for html
<a href="https://travis-ci.org/garu/Clone"><img alt="Build Status" src="https://travis-ci.org/garu/Clone.png?branch=master" /></a>
<a href="https://coveralls.io/r/garu/Clone?branch=master"><img alt="Coverage Status" src="https://coveralls.io/repos/garu/Clone/badge.png?branch=master" /></a>
<a href="https://metacpan.org/pod/Clone"><img alt="CPAN version" src="https://badge.fury.io/pl/Clone.svg" /></a>

=head1 SYNOPSIS 
 
   ... 

As soon as you push the new version to CPAN, you'll see the badges right there on MetaCPAN!
















If you are too lazy to go back and copy the HTML version from all those sites, just run the following one-liner on your README.md to print the html version of the markdown links in there:

perl -nE 'BEGIN{ say q(=for html) } say qq(<a href="https://www.blogger.com/$3"><img alt="$1" src="$2" /></a>) if /\[!\[([^\]]+)\]\(([^\)]+)\)\]\(([^\)]+)\)/' README.md

Then copy the block to your pod and make a new CPAN release :)

That's all there is to it. Have fun with your badges! \o/

(oh, and let me know if you find any other Perl-related badges you know of)

Saturday, 28 February 2015

My February CPAN PR Challenge: Template::Plugin::Autoformat

For this month's CPAN Pull Request Challenge I was assigned with  Template::Plugin::Autoformat, a module that lets you easily format text and numbers in your Template Toolkit templates, using Damian Conway's excellent Text::Autoformat. If you ever needed to adjust text right/left/center justification, alignment, capitalization, bullets, indenting, without being able to resort to CSS - for example, if your templates are not for HTML or if said text is inside a <pre> tag - this module could make your life much easier!

A different challenge


It was an unusually busy month for me and I didn't get a chance to tackle it until yesterday - I even got Neil's "One week left!" email reminder, which was nice. Even so, I figured it would be ok, because the original PR Challenge email mentioned this module had several CPAN Testers FAIL reports, CPANTS issues, and hadn't seen an update in several years.

Except now when I finally checked it out and it saw it was last released a month ago, had zero failures on CPAN Testers, no open issue on either RT or Github, no CPANTS issues, pristine documentation, even complete META resource information! I thought I had been assigned to a dist needing help, but instead what I was looking at was a stable and well-maintained one.

As it turns out, Template::Plugin::Autoformat hadn't seen a single update between 2008 and 2014, when it was adopted by Peter Karman. Peter started making several developer releases until he was satisfied with the results, and released a stable version in January 2015 (which is probably why it was still in the CPAN PR Challenge's list, created prior to said release). His new version fixed all open issues, had a great test coverage and felt like one of those modules that do one thing and do it very well.

And now I had 1 day to send a nice pull request to a module that looked like it needed no pull requests, or I'd lose the challenge :X

Starting small


Okay, instead of being caught in analysis paralysis, I cloned the repo and looked for low hanging fruits. Turns out there were some!

  1. The copyright year was still 2014. This is the first place I look because it's also the first place I overlook in my own projects :) It's such a simple patch that it almost feels like cheating, but you have to start somewhere, right? Done.
  2.  The README was not in Markdown. I love markdown READMEs, because they make the Github project page look *so* much nicer without compromising reading it from the terminal. Even better, "README.md" is fully supported by PAUSE & CPAN \o/. As I was making the conversion, I noticed the README's contents were just a copy of the pod, so I tweaked it a bit to include installation instructions and just a teaser pointing to the full docs, online and via perldoc. This is a good thing for the developer too, as there's less duplicate content to worry about. Done.
  3. The distribution did not declare a minimum perl version. CPANTS Kwalitee is a terrific free service for the Perl community, letting users and authors know whether a given module passes or fails several quality assurance metrics. While, as I mentioned before, Template::Plugin::Autoformat passed all core CPANTS metrics, this extra metric was not being met. In fact, it was the only extra metric not being met. Thankfully, the excellent perlver tool makes it very easy to find the minimum perl version for your module or app. It reported 5.6.0 as being the minimum version so, after a very simple addition to the Makefile.PL, I had my third pull request of the night.
  4. The Changes file was not fully compliant with the CPAN::Changes spec. This was also an easy one to fix, since the only standing issue was formatting the release dates to something CPAN::Changes would understand. Next!
  5. Test coverage was almost 100%, but not exactly 100%. This is another great way to help other projects: check the code coverage and see if you can improve it in any way. In this case, after running the great cover tool, I found out it had 100% statement coverage, but 50% pod coverage and 91.6% branch coverage. The pod coverage was actually a mistake - there was a private function being counted as public. Adding the missing branch test was also pretty straightforward. After the patch, Template::Plugin::Autoformat got 100% coverage in everything - which is pretty cool!
  6. The "NAME" key in Makefile.PL had the distribution name, not the main package's name. Now, the builder is clever enough to do the right thing, but nevertheless it was triggering a warning every time I ran "make" - which was quite a bit while I played with test coverage. Easy fix again, just s/Template-Plugin-Autoformat/Template::Plugin::Autoformat/ and I was done for the night.
So after a couple of hours having fun with Template::Plugin::Autoformat, I had 6 PRs to show for on the PR Challenge. Woot! Best of all, just a few hours later Peter Karman merged all my PRs and made a new release \o/

Thursday, 29 January 2015

My CPAN Pull Request Challenge for January: Fuse


So! Back in December I subscribed to Neil Bowers' CPAN Pull Request Challenge. In a nutshell, throughout 2015 every participant will get an email in the first days of each month with a CPAN module that needs a little bit of love, and we have until the end of the month to submit at least one pull request for that module's Github repository.

The module I got was "Fuse".

What is Fuse?


I must admit to my ignorance as I have never heard of Fuse before. So the first thing I did was jump to Fuse's page on MetaCPAN and have a look. Fuse is a Perl interface to the FUSE library (Filesystem in USErspace), and lets you implement filesystems in Perl. Wow! That's pretty cool, right?!

Where to start


If Neil was pointing me to Fuse, it means there's probably work for me to do. So what I did was read the documentation, CPAN Testers reports, open issues and the Github page. Then I downloaded the source code and grep'd for tags like "FIXME" and "TODO". In the end it was a very well-thought distribution and I think the authors did - and are still doing - a pretty nice job. Still, this is what I thought I could help with:
  • The (external) FUSE kernel/lib doesn't seem to be linked anywhere in the main doc, just on the README;
  • The SYNOPSIS and DESCRIPTION could be a bit more verbose - maybe I'm just not used to the FUSE library, but I felt a lot was being taken for granted;
  • The README (displayed on github) doesn't point to a lot of useful places in the Perl-sphere (other than the examples and how to install);
  • There is no license information on the main pod - though it's there on the META resources;
  • The latest version is not indexed for some reason;
  • There are a lot of FAIL and UNKNOWN reports on CPAN Testers.

First things first


There were several small things for me to attempt here, so rather than making a huge bundled Pull Request for Fuse, I chose to compartmentalize them into smaller, separate, PRs. This way the authors'd probably be more comfortable reviewing my changes and I wouldn't depend on all of them being accepted. This is super easy with git and github: just create a branch from master and make the pull request from your specific branch to the author's master. This will let you easily go back to their master (instead of to the one you might have changed) and work on something else independently.

1. Doc fixes

Since I was really short of free time this month, I decided to start with the lowest hanging fruit. So I created a "garu/doc_patches" branch and tried my best to improve on the existing documentation. I expanded the SYNOPSIS, put external links whenever I missed them, and did some minor tweaks here and there with the pod formatting to improve readability. I also moved the README to markdown so it looks awesome on Github while still being nice to read on the console. When I was satisfied, I sent out the pull request.

This was great and really helped me understand what Fuse was all about and how to use it. I recommend anyone trying to learn and contribute to a project to first read the docs and try to improve them whenever you find something you don't quite understand. Most of the time the ones writing the documentation are too familiar with the code and API so they can take a lot of it for granted.

2. WHY U NO INDEX?

There was an open ticket saying 0.16.1 was not indexed. Upon further investigation, I saw versions 0.16_01 and 0.16.1 were in fact indexed, but available as if they were older releases. Why weren't they showing up as the latest? I went to #metacpan on irc.perl.org and asked around.

As haarg++ pointed out, Fuse inadvertently mixed single dotted and double dotted version formats, releasing '0.16' (instead of '0.16.0') and '0.16.1'. When the CPAN indexer compares version numbers, 0.16.1 becomes 0.016001 and plain 0.16 becomes 0.160000, and as such, "0.16" is indeed greater than "0.16.1".

While I believe version numbers should be boring, I understand why some people go for the major.minor.revision semantic versioning format. So I went ahead and filed a pull request bumping up the version to 0.160.2, and another one that bumps it to 0.17. Both numbers are greater than 0.16 so they'll definitely show as latest, and the authors can just pick whichever format they prefer and discard the other PR.

3. Making tests pass

Finally, I noticed that all the UNKNOWN tags on CPAN Testers were there because FUSE was not installed. Implementing an Alien::FUSE module seems like a good idea, but it is a bit out of scope for the PR Challenge and the limited free time I had. So I went on and installed FUSE for OS X using homebrew. For my surprise, the Makefile.PL was still not finding it:

    $ perl Makefile.PL
    Cannot build for platform: darwin
    Please install OSXFUSE from http://osxfuse.github.com/

I checked Makefile.PL's source and found out what was wrong: it's trying to find libfuse using the "pkg-config" tool. Although "pkg-tool" is rather ubiquitous in major Linux systems, my OS X did not have it. So a made another PR that checks for the existence of either 'pkg-config' or 'ppkg-config' (a Pure-Perl alternative to 'pkg-config' available with the excellent PkgConfig CPAN module) early on the Makefile.PL, dying with an explanatory message if none are available. There's even an opportunity here to simply depend on PkgConfig and use the module version of the commands instead of relying on external "(p)pkg-config" tools, but I thought I rather wait a bit and see how well received this change is first.

Now the module compiles on OSX, but I still can't make the tests pass. I dug a bit and found some commands like read_buf and write_buf are required for testing, but are only available in libfuse versions 2.9.0 and above. However, osxfuse seems to use a different version equivalence and the latest version (released just a month ago) is still 2.7.4. I couldn't find an osxfuse <=> libfuse version equivalence, and because of this, the Fuse module doesn't create the proper bindings for such functions and the tests fail. There might be other issues still, but I stopped there, filing a ticket and hoping someone else will pick it up where I left off.

Wrapping up


I had a lot of fun finding out about Fuse and playing with it. By the end of January I was able to file 4 pull requests and 1 RT ticket to the main repo. I'm sad I wasn't able to get the tests to pass on OS X, but hopefully someone else will read this and be inspired :)

I'd like to thank Neil for this awesome PR Challenge idea, Graham "plicease" Ollis for the great PkgConfig module and for quickly replying to and merging the small changes I proposed that allowed me to use it on Fuse, and Graham "haarg" Knop and everybody from #metacpan for their amazing support.

Also, of course, a huge thank you to Dobrica Pavlinušić, Derrik Pates, Mark Glines and the entire Fuse team for such a great module, and for allowing me the opportunity to be a part of it.

Can't wait to see which module I'll get next month! :)

Sunday, 6 April 2014

Perl Dancer on Media Temple (gs)

Recently I was asked by a friend to install Dancer on Media Temple Grid Service (gs), and after I couldn't find a tutorial to do so, I decided to write one myself :)

Hopefully, you'll be able to get up an running in seven easy steps. I am assuming you know how to use remote *nix shells via ssh, editing files, etc.

You should be aware that none of this is really supported by Media Temple so if you run into trouble or if something changes on the grid, you're on your own. For anything other than simple dynamic websites (in PHP), Media Temple recommends their more robust (and expensive) dedicated virtual (dv) server solution.


Step #1 - Login with SSH on Media Temple


At the time of this writing, Media Temple's GS runs on Perl 5.10.1, which is not very recent, but is good enough for us. Teaching you how to setup ssh is a bit beyond the scope of this tutorial, but thankfully Media Temple provides a very nice ssh guide.

Media Temple runs Apache, but error logging is not enabled by default, so you should probably enable error_log on Media Temple. If you run into any trouble on the following sections of this tutorial, following the error log (by something like running "tail -f $HOME/../../logs/error_log" on another window) is definitely going to help you!

Step #2 - Sanity check


After you log in, you'll see Media Temple's domains come with 2 directories (at least that's how they showed up to me): "cgi-bin" and "html". This structure implies that dynamic content should be under cgi-bin and static content should be under "html". Just to make sure everything is sane, up and running, let's create a very simple pure-perl script and place it under the "cgi-bin" directory:

    #!/usr/bin/perl
    # ^^^ Media Temple requires the shebang!
    use strict;
    use warnings;
    print "Content-type: text/html\n\n";
    print "Hello, Media Temple";

Save this file as "test.cgi" and set permissions to 700 (required, apparently):

    chmod 700 test.cgi

The owner of the file should be the main account for that domain as well:

    chown $USER:$USER test.cgi

(where $USER is the username of the main account)

You should also make sure the cgi-bin directory's permissions is set to exactly 755, otherwise things won't work.

Now try and run it from your web browser, by opening "http://your-domain/cgi-bin/test.cgi", where "your-domain" is your Media Temple domain. If you see an "Internal Server Error" message, try checking out your error_log and review the previous steps (for example, make sure the script is exactly as it is above, and all permissions are right).

Step #3 - Installing Perl modules on Media Temple (mt) Grid


Media Temple provides a Knowledge Base tutorial on how to install Perl modules on the Grid, but it only lists manual installations which are boring and error prone. After all, we live in the future, where it's simple to install Perl modules as a user on a shared hosting service. All you have to do is type the following on your server's command line (it's just one line, and you can cut and paste as it is):

    curl -L http://cpanmin.us | perl - --local-lib=~/perl5 local::lib App::cpanminus && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)

 This is going to install local::lib and cpanm into your home directory, and enable you to install any other modules there by simply typing "cpanm My::Module" (where "My::Module" is, of course, the name of the module you want to install).

While you're at it, remember to add the line:

    eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)

to your ~/.bash_profile file (create it if necessary, of course).

Step #4 - Installing Dancer (and everything else!)


After the previous step, installing Dancer is easy as pie:

    cpanm Dancer

Done! Let's also install Plack::Runner, in case we need it:

   cpanm Plack::Runner

You can take this moment to install all your app's dependencies. For instance, my friend's app is also using Template Toolkit and DBIx::Class

   cpanm Template DBIx::Class

Step #5 - Making a default Dancer app (or moving your current one)


If you already have a Dancer app, just move it to Media Temple's domain directory. For example, if your Dancer app is called "my-app", move it to:  "/home/XXXXX/domains/mydomain.com/my-app" (replacing XXXXX and "mydomain.com" to the appropriate values for your grid account).

Otherwise, just go there (/home/XXXX/domains/mydomain.com) and create your Dancer app by typing "dancer -a appname".


Step #6 - Change "html" to a symlink:


Your Dancer app's base directory is usually "appname/public", but Media Temple forces you to have an "html" directory as base. So we remove the original (just rename it instead if you're not brave enough :) and create it again, only this time as a symbolic link to "appname/public":

    cd ~/domains/mydomain.com
    mv html html_old
    ln -s myapp/public html

Step #7 - Add the appropriate .htacess files


Media Temple runs Apache on the grid server, so we control what runs with .htaccess files. This is the content we put in the file "myapp/public/.htaccess":

    # Allow /public to run Perl code
    Options +ExecCGI +FollowSymLinks
    AddHandler cgi-script .cgi .pl


    # Initialize mod_rewrite
    RewriteEngine On
    RewriteBase /
 

    # If file doesn't exist on the server, dispatch!
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.+)$ dispatch.cgi/$1 [L]



At this point I bumped into trouble. Media Temple's Apache doesn't seem to let Perl see variables such as PERL5LIB. There's likely a clean way to fiddle with "SetEnv" on .htaccess to fix this (let me know if you get it working!),  but what I did was add a "use lib" line on top of public/dispatch.cgi, like so:

#!/usr/bin/env perl
use 5.10.0;

# Media Temple doesn't read our environment
use lib qw(
   /home/XXXXX/users/.home/perl5/lib/perl5
   /home/XXXXX/users/.home/perl5/lib/perl5/x86_64-linux-gnu-thread-multi
);

That's the basic setup! If everything went well, you should be able to point your web browser to your domain and see Dancer's main page \o/

You should notice we're running Dancer on standard cgi, which means it's going to be somewhat slow, specially when loading modules.

Appendix: Perl with FastCGI on the Media Temple Grid


Sadly, Media Temple doesn't seem to provide proper FastCGI support for Perl - at least from my understanding. Of course, that didn't stop me from trying, so here's what I did:

First, enable PHP FastCGI on the GS. It should have created a .htaccess in your domain root (i.e. the parent of your "html" dir) with some basic FastCGI settings. I changed them to this:

    # BEGIN (mt) controlled settings
    <IfModule !mod_fcgid.c>
      AddHandler cgi-script .cgi .pl
    </IfModule>
    <IfModule mod_fcgid.c>
      AddHandler fcgid-script .fcgi
      <Files *.fcgi>
        Options +ExecCGI
      </Files>
    </IfModule>
    # END (mt) controlled settings


(this is basically their default script, with "php" replaced with "cgi", "pl" and "fcgi").

Then I went to our own html/.htaccess file (it's a symlink to myapp/public/.htaccess, remember?) and replaced "dispatch.cgi" with "dispatch.fcgi" on the rewrite rules described in step 7 above. Finally, I updated the file "dispatch.fcgi" to include the same "use lib" I did for dispatch.cgi, deleted dispatch.cgi and voilá :)

Done!


Again, Media Temple recommends that any serious app go to their dedicated virtual server (dv) solution. Still, the current gs setup should be enough for you to have some fun and play around with possibilities before moving to a more expensive plan.

There are tons of other cool things you can do, such as creating remote git repositories and making hooks to do automatic deploys, but that's a bit out of the scope of this tutorial :)

Have fun, and happy Perl hacking!

Wednesday, 5 December 2012

Are you relying on hash keys being ordered?

tl;dr - if you rely on Perl 5, and plan to eventually upgrade to the upcoming 5.18, do this *now*:

  1. Install 5.17.6 (you do use perlbrew, right?);
  2. Try your modules and apps in it (you do have tests, right?);
  3. If  anything breaks, it's likely because you're relying on keys(), values() or each() being in some particular order. You really shouldn't, so go sort() your keys or something :)
  4.  If some CPAN module you depend on suddenly fails on 5.17.6, make sure to let the author know;
  5.  Spread the word!

On Hashes & Security


The Perl 5 core team has always put security as one of its top priorities. To put things under perspective, in late 2011, an algorithmic complexity remote denial of service attack (original paper, advisory, slides, video) was found on major language implementations like PHP, Ruby, Python, Java, even JavaScript. It's been fixed in Perl 5 since... 2003.

That was then. What about now?


Still thinking about security, Yves Orton pushed some important changes these past few weeks, changes that are going into perl 5.18.0. Among other things, to quote 7dc8663964, it:

  • Introduces multiple new hash functions to choose from at build time. This includes Murmur-32, SDBM, DJB2, SipHash, SuperFast, and an improved version of the original One-at-a-time.
  • Rips out the old HvREHASH mechanism and replaces it with a per-process random hash seed.

Optimizations aside, the ability to change hash functions easily is important because, if, for whatever reason, the active function is found vulnerable to an attack, you don't have to wait until the Perl Core Team (or your specific vendor/system) releases a fix: just recompile your perl setting another hash function as default.

The important bit, however, is the per-process random hash seed. Until now, perl was using a not-so-great hash seed, one that was set during compilation. All hashes would use this seed, and if a collision attack was detected it would trigger a rehash, where every item in the hash would have its hash value recalculated, with corresponding effects performance and memory. Of course, when too many collisions were found, the rehash would switch to a random seed instead.

Now, after this change, every process is guaranteed to use a random seed.

Hash randomization should make perl even more robust to complexity attacks, and with simpler code. But, as you may have predicted, there's a side effect to it: the order of hash keys changes more often than before.

Sweet! But, what does it mean to my code?


As it is stated in perlsec since version 5.8.1 (that one from 2003), Perl has never guaranteed any ordering of the hash keys, and in fact the ordering has already changed several times throughout its history. The problem, however, is that a lot of developers end up inadvertently relying on hashes being ordered, or rather in some random but constant order, simply because that particular order worked on their machine. Talk about a subtle bug!

This may not be your case, but you should check nonetheless. Andreas König, Father Chrysostomos and the rest of the P5P/CPANTesters gang have gone through the enormous effort of testing several major CPAN distributions for this and letting authors know whenever it failed a test while running on a patched version of perl, but they can only do so much, and there's *your* code to test, too.

You know, code your app runs, code that you haven't checked to CPAN.

Oddly enough, it looks like most of the found issues are on test cases themselves, tests that expect keys() to be in a particular order. Now, keys() is guaranteed only to return items in the same order as values() or each(), and even that is only true for the same process, so make sure you're not shooting yourself on the foot.

LIES! My code is perfect, you're the ones that broke Perl!


Well, not really. Like I said, it's a subtle bug, one that might be hitting your production code right now, but only on some very specific scenarios, and be very hard to reproduce and debug. If you don't trust me, there's a very simple experiment you can run on your system perl:

First, let's create a simple one liner that creates 15 key/value pairs, and print them on the screen:

   > perl -E 'local $,=q[, ]; $hash{$_} = $_ for 1..15; say keys %hash'
     6, 11, 3, 7, 9, 12, 2, 15, 14, 8, 1, 4, 13, 10, 5

You may have gotten a different order (did you?), but you'll probably get that same order no matter how many times you run it:

   > perl -E 'local $,=q[, ]; $hash{$_} = $_ for 1..15; say keys %hash'
     6, 11, 3, 7, 9, 12, 2, 15, 14, 8, 1, 4, 13, 10, 5
   > perl -E 'local $,=q[, ]; $hash{$_} = $_ for 1..15; say keys %hash'
     6, 11, 3, 7, 9, 12, 2, 15, 14, 8, 1, 4, 13, 10, 5
   > perl -E 'local $,=q[, ]; $hash{$_} = $_ for 1..15; say keys %hash'
     6, 11, 3, 7, 9, 12, 2, 15, 14, 8, 1, 4, 13, 10, 5
   > perl -E 'local $,=q[, ]; $hash{$_} = $_ for 1..15; say keys %hash'
     6, 11, 3, 7, 9, 12, 2, 15, 14, 8, 1, 4, 13, 10, 5
   > ...

What happens, however, if your code adds a 16th key and then, realizing its mistake, removes it right afterwards (highlighted code below)? There are still 15 keys, the very same 15 keys as before, so surely they'll be in the same order, right? Right? Wrong:

   > perl -E 'local $,=q[, ]; $hash{$_}=$_ for 1..15;
             $hash{16}=16; delete $hash{16}; say keys %hash'
     11, 7, 2, 1, 13, 6, 3, 9, 12, 14, 15, 8, 4, 10, 5


This can happen anywhere, like when reusing a hash variable:

    sub init { ( 1=>1, 2=>2, 3=>3, 4=>4, 5=>5 ) }

    my %hash = init();
    say "original: " . join ', ' => keys %hash;
    $hash{$_} = $_ for 6..100;

    %hash = init(); # restores original values
    say "original? " . join ', ' => keys %hash;


This is what I get on my good old 5.14.3:

    original: 4, 1, 3, 2, 5
    original? 2, 1, 3, 4, 5


As you can see, it's a real problem and it could be lurking in your code right now. What Yves' patch does is simply expose the issue more explicitly to you. This is a good thing, because, aside from the extra security protection, it will let you spot buggy code much easier. If you try that previous one-liner on 5.17.6, you'll get a different key order every time you run it:

   > perl -E 'local $,=q[, ]; $hash{$_} = $_ for 1..15; say keys %hash'
     1, 5, 15, 12, 6, 4, 10, 9, 3, 13, 7, 14, 11, 2, 8
   > perl -E 'local $,=q[, ]; $hash{$_} = $_ for 1..15; say keys %hash'
     5, 11, 7, 3, 15, 6, 12, 2, 13, 9, 8, 14, 10, 1, 4
   > perl -E 'local $,=q[, ]; $hash{$_} = $_ for 1..15; say keys %hash'
     2, 15, 14, 13, 5, 1, 9, 10, 3, 11, 6, 8, 12, 4, 7
   > perl -E 'local $,=q[, ]; $hash{$_} = $_ for 1..15; say keys %hash'
     8, 2, 14, 10, 1, 9, 4, 3, 6, 15, 5, 13, 7, 12, 11


Uh-oh... looks like my code is broken.


Not to worry, the fix is usually pretty easy! Look for the failing test and see if whatever is being tested calls keys(), values() or each() at some point. You'll likely want to sort() the results or change your code algorithm to something more deterministic.

I don't really have that many tests... What can I do?


Look for calls to keys(), values() or each() in your code, and make sure they are not relying on the order of the elements being returned. It is ok to do something like:

  my @keys   = keys %hash;
  my @values = values %hash;
  say "hash key $keys[3] is $values[3]";

because, as I said before, keys() and values() will always use the same order for the same process, whatever that order is. However, this is not ok:

  if ($keys[0] eq 'some_key') {
     ...
  }

simply because there's no way to guarantee the order of the list returned by keys(). The code above might have worked, however, if you always sorted the returned value, like so:

  my @keys = sort keys %hash;
 

Indirect usage


Sadly, your code is not safe just because you don't use those functions (or have them properly sorted). Sometimes you expect lists of values from external modules, and those lists might be affected by the change. So make sure you look for arrays that are populated by external functions and see if you rely on their order being a particular one. For example, you might have code like:

   my ($name, $age, $rate) = Some::Module->new->get_list( 'some_user' );
   
And, within Some::Module, you'll find the suspect:

  sub get_list {
    my ($self, $username) = @_;
    return values $self->{data}{$username};
  }

Make a failing test for it, push a fix, rinse and repeat :)

I hate this! Switch it back!


This is hardly going to happen. Remember: hash randomization is a good thing! Please take another look at the sections above and try to fix your code. If you need help, ask for it at the usual places, like your local mailing list or IRC - heck, even Facebook has a Perl group!

But if you really really really need the previous behavior, you can simply stick to 5.16, or try compiling perl defining PERL_HASH_FUNC_ONE_AT_A_TIME_OLD to simulate the old algorithm, but the entire rehashing mechanism is gone, so specifying your own PERL_HASH_SEED value is probably as close as you'll get :)

Many thanks to the nice folks at P5P for their continuous effort in keeping us safe!

Wednesday, 30 May 2012

Moving modules across perlbrew installations

This short post was triggered by a conversation I had on Twitter with a friend:


He does strike a nerve there. Ever since Gugod's amazing perlbrew came to life, installing your custom perl - or several perls for that matter - is *really* easy. However, a new problem surfaced: updating your installation so your applications work again. This is, of course, per design. After all, perlbrew is supposed to give you completely separate installations, and this includes installed modules.

So, what can you do? Copying your lib directory is out of the question if you have any module that does XS, and chances are you probably do. I'm also not sure if an external local::lib directory would play nice either.

Luckily, there's a quick-and-dirty recipe to migrate your installed modules from one perlbrew installation to another. Say I just upgraded from 5.14.2 to 5.16.0 and want to install the same modules I had before:

    $ perlbrew switch 5.14.2
    $ perl -MExtUtils::Installed -E 'say for ExtUtils::Installed->new->modules' > /tmp/installed.list
    $ perlbrew switch perl-5.16.0
    $ perlbrew install-cpanm
    $ cat /tmp/installed.list | cpanm --interactive

Done!

What I did there was use the core module ExtUtils::Installed to create a list of installed modules in the file "/tmp/installed.list", then feed that list to cpanm. I used "--interactive" because some modules I have (like SDL) ask a few questions during installation, but whatever rocks your boat.

Also worth noticing that depending on the amount of modules you have installed, that last step can take quite a while, so go watch a movie, read a book or something :)

I think this tip is particularly pertinent if you're trying out a Release Candidate (RC) for a future perl release and want to make sure your toolchain builds properly - which is always a good idea.

I'm going to bug gugod for a bit to see if we can come up with something bundled into perlbrew to make this even easier, but for now you can use this :)

Hope it helps! Happy Perl Brewing!

Tuesday, 3 January 2012

The Perls of 2011

Following my 2010 post, I thought I should register some of the great things that happened in the Perl programming world in 2011. Only this time instead of turning it into a timeline, I'm going to place things in topics so you can just concentrate on what really matters :)

Also, I'm only going to write about Perl 5. If you're looking for a Perl 6 retrospective, Moritz Lenz already did a very nice job with that :)

Apologies if I missed something - it's really hard to keep track of all the wonderful projects and conferences going on! Make sure to add them in the comments section below.

So, without further ado, here are the "Perls of 2011".

Some Perl & CPAN stats

According to Ohloh, over the course of 2011 there were nothing short of 5975 commits to the main Perl 5 repository. Wow! For comparison, Ruby had 3153 commits and PHP, 4461. We were a little short from our friends in the Python community, though, which had 6974 commits. Not bad, huh?

The Perl 5 bugtracking system reports a total of 915 tickets created in 2011, and 928 tickets closed in that same period. That was close, but the awesome folks at p5p once again managed to keep the stats positive :)

By the way, can you guess how many perl releases we had in 2011? 1? 3? more? 10? Try 21. Twenty one, including development and stable releases!

One of the coolest ones was, of course, perl 5.14, which brought us Unicode 6.0 support, new regex flags, the sugary "package Foo { }" syntax, improved IPv6 support and, as if these weren't enough, it uses even less memory and CPU than previous releases!

How about CPAN? 16197 distributions uploaded, of which 1873 were brand new!

Security

The Common Vulnerabilities and Exposures had 5 entries tagged "perl" in 2011, of which only 2 were actually regarding perl itself (namely, CVE-2011-0761 and CVE-2011-1487). Again, for comparison, python also had 2 records, ruby had 7, and php had 36.

Perl's commitment to stability and security was showcased in late december, when Alexander “alech” Klink and Julian “zeri” Wälde delivered a very nice talk at the 28th Chaos Communication Congress security conference in Berlin, entitled "Efficient Denial of Service Attacks on Web Application Platforms". Their work builds on top of an attack vector described in perlsec and fixed back in 2003 (the long-since-deprecated 5.8.1), and shows the issue affects almost every other popular language for the web, including Python, Java, PHP, ASP.NET and JavaScript. Ruby fixed their code in 2008 and people should be fine as long as they use CRuby 1.9 and above.

The King is dead. Long live the King!

For the past two years Jesse Vincent (obra) was our beloved Perl 5 Pumpking. Back in october he passed the torch to the incredibly prolific Ricardo Signes (rjbs), who will undoubtedly make us all very proud! A huge thanks is in order to both of them for the remarkable work they did last year - and that they'll undoubtedly keep on doing.

TPF Grants & Donations

Dave Mitchell once again did an astounding work with his "Fixing Perl 5 Core Bugs". Last year alone he worked more than 470 hours, closing 29 tickets. Great job, Dave!

In the middle of the year Nicholas Clark jumped on the wagon with his "Improving Perl 5" grant, approved with praise. So far Nick reported more than 380 hours of work, and tons of code to make Perl development even smoother.

None of this would be possible without the wonderful support from several companies that are proud to use Perl, giving out not only their public praise but also donating infrastructure and money to help further develop the language. This year we saw some incredible support from Booking.com, cPanel, Dijkmat, Liquid Web, Net-A-Porter, the Oslo Perl Mongers, perl-services.de, and the Vienna Perl Mongers.

Google Summer of Code (GSoC)

Every year The Perl Foundation participates on the Google Summer of Code program, and 2011 was no exception. This time, 6 students were accepted and all of them made their mentors proud - 100% success rate! A huge thanks is in order for everyone that participated.

Google Code-in

Another great initiative from Google in 2011 was the Code-in program, aimed at 13-17 year old school/college students with the idea of getting them involved with open source. The project is still running but we can already see some impressive results, such as over 135 completed tasks.

These numbers are great, and show that there's a big niche for Perl in schools and undergrad courses. I had the opportunity to teach Perl to undergrads in a one-week course at the Federal University of Rio de Janeiro and the receptivity was incredible! If you have the chance to give a short free workshop at your local college/university, I highly recommend you do so :)

Conferences! Conferences! Conferences!

All over the world, the vibrant Perl open-source community and their corporate sponsors filled the year 2011 with conferences showing the best modules, tools, techniques and design patterns, talking about a lot of bleeding-edge features and how to make Perl help with innovation and productivity for your enterprise.

January: Orlando Perl Workshop (OPW - a.k.a. The Perl Oasis)
February: Frozen Perl, Bulgarian Perl Workshop
March: Dutch Perl Workshop
April: Toronto Perl Workshop, QA Hackathon
May: São Paulo Perl Workshop
June: Nordic Perl Workshop, French Perl Workshop, YAPC::NA
August: YAPC::Europe
September: Italian Perl Workshop, Portuguese Perl Workshop
October: Ukrainian Perl Workshop, Pittsburgh Perl Workshop, Belgian Perl Workshop, German Perl Workshop, YAPC::Asia
November: YAPC::Brasil, TwinCity Perl Workshop, London Perl Workshop
December: Russian Perl Workshop

Only July had no perl-centric conference. Quite impressive! And we're not even counting general conferences in which we participated such as FOSDEM, FISL, OSDC, OSCON, or even Perl Mongers tech meetings. Speaking of which...

Perl Mongers

The number of active Perl Mongers group just keeps growing and growing. In 2011 alone, 15 new groups were spawned! Good luck to all our friends from AtlanticCity.pm (US), Makati.pm (PH), Bordeaux.pm (FR), HradecKralove.pm (CZ), Goiania.pm (BR), Petropolis.pm (BR), Brno.pm (CZ), Logan.pm (US), Tolyatti.pm (US), LGBT.pm, SouthernOregon.pm (US), Plzen.pm (CZ), Sendai.pm (JP), WestVirginia.pm (US) and Kerman.pm (IR).

With these new additions, our tiny planet hosts 251 active Perl Mongers groups :)

Prominent Perl People in 2011

This year we had some well-deserved White Camel Award winners: Leo Lapworth, Daisuke Maki and Andrew Shitov. Congratulations and thanks for making the Perl world better!

There are several others whom also deserve a huge praise for last year's work, amongst them Mark Keating of Shadowcat/EPO/TPF, who is tirelessly working on quality Perl marketing; Gábor Szabó who started the Perl Weekly mailing list and a series of Video Tutorials; and Thiago Rondon, who did huge things for the OpenData initiative, leading us (and Perl) into projects that added a lot of transparency to the Brazilian government and even resulted in a W3C Brazil OpenData Developer's Manual (of which I'm proud to have been a part of) and in winning the Latin America OpenData hackathon.

A couple of new, fun and downright useful websites were born in 2011, including Perl News by Dave Cross, Github-Meets-CPAN by Johannes Plunien; and PrePan, by Kentaro Kuribayashi. Important to notice that learn.perl.org was relaunched with a beautiful look and a lot of updated content. Great job, everyone!

But there are also the silent workers, the ones that are mostly behind the scenes but whose efforts were paramount for the Perl 5 ecosystem. People like Karen Pauley, president of The Perl Foundation; and Barbie, who worked really hard in keeping the incredible CPAN Testers service up and running.

In fact, a *HUGE* thanks are due to everybody involved in CPAN Testers in 2011: Barbie, Dave Golden, Chris Williams, David Cantrell, Slaven Rezić and just about everyone else. I had the great opportunity to help Dave Golden upgrade the cpan-reporter module to use metabase and I could see how intricate the whole thing is. By the way, did you know that in 2011 CPAN Testers crossed the barrier of over 1 million test reports in a single month? That's incredible!

Speaking of which, what would be of Perl 5 without its core developers? Several of them were already mentioned and praised here, but you can check the full list of contributors in the AUTHORS file, or in perldelta for a more recent list. This year we had the pleasure of seeing commits from Father Chrysostomos, Florian Ragwitz, H.Merijn Brand, Karl Williamson, Claudio Ramirez, Vladimir Timofeev, Nobuhiro Iwamatsu and many, many others. Thanks, guys!

Perl Games

The Perl gaming scene got yet another massive overhaul in 2011. Coming from all the hard work Kartik Thakore, Tobias Leich and everyone else at the SDL Perl project put in 2010, game development in Perl has never been this easy or fun.

The SDL Perl Manual was finished early in the year, and we were having so much fun we threw together the SDL Perl Game Contest in march, resulting in a total of 16 new games written from scratch in just one month!

The year also saw the coming of a Box2D wrapper for Perl, letting us add some fast physics to games and simulations.

But the best was yet to come. Construder, a jaw dropping 3D game created by Perl hacker Robin "elmex" Redeker, features futuristic settings with some nice graphics and an (almost) infinite world for you to build and play with. Make sure to check it out if you haven't already!

A Web of Perl

Perl's most widely adopted web frameworks also kept extremely busy, and 2011 marked some pretty cool releases and announcements:

Catalyst 5.9 was released back in august, incorporating Plack as its default Engine. This change benefits Catalyst significantly by reducing the amount of code inside the framework, getting upstream bug fixes in Plack, and automatically gaining support for any web server which a PSGI compliant handler is written for.

Mojolicious saw a total of 122(!) releases, including its 2.0 one, and now features updated websockets support, documentation enhancements and several asynchronous/non-blocking features. You can check out the official Mojolicious 2011 retrospective for the full monty.

The nice folks of Dancer started working on a massive core rewrite that will help the project tremendously. Among the changes being made, there will be no more globals in the core, 100% object-oriented backend, better scoping for sub-applications, and a better design overall.

Advent Calendars

The tradition remains, and the 2011 Perl Advent Calendars are filled with great content ranging from beginner tips to advanced hacks. The Japanese Perl Community once again delivered several high-quality articles in 9 different tracks, while the Brazilian Perl Community scattered their great articles throughout the two months of the Equinox.

Books

O'Reilly has been busy in 2011, with the updated 6th edition of Learning Perl - the Llama - by Randal Schwartz, brian d foy and Tom Phoenix, and Johan Vromans' handy Perl Pocket Reference. They're also getting ready for the 4th edition of Programming Perl - the Camel - to be released in early 2012. Heck, at O'Reilly they even used Perl to pick their Secret Santa :)

Speaking of upcoming titles, Ovid's Beginning Perl and chromatic's Little Plack Book are ones to keep an eye for. Who knows, maybe I'll get to talk a bit more about them in the 2012 wrap-up? I look forward to it!

Rise of The MetaCPAN

If you were one of the early adopters, you know MetaCPAN was actually born on late 2010 (november 3rd, to be precise). The project had some ambitious goals: provide a free and open sourced alternative search engine to the ever-glorious CPAN. But in 2011 it became more. So much more.

Moritz "Mo" Onken, a student at the Karlsruhe Institute of Technology (KIT), applied for the GSoC and quickly became a hero. Sure, he already had several years of Perl background, but what Clinton Gormley, Olaf Alders and himself achieved in 2011 exceeded all expectations and revolutionized the Perl world.

MetaCPAN is not only a sophisticated and fast CPAN search engine, but also offers a full featured REST API that lets you build on top of it making all sorts of complex search queries for extracting data from and about the CPAN. Another (very) important aspect: an active and vibrant community that actually encourages people to send patches fixing bugs and adding new features.

Featured Perl Modules

Wrapping up the retrospective, I should go about some of the cool new modules that spawned in 2011. This is not meant to be a thorough list, just a small snippet for your viewing pleasure:

Mason 2 - The traditional HTML::Mason distribution received a major overhaul and became just "Mason". The new distribution is being very actively developed and has a much more modern architecture. Check out the changes and give it a try!

dip - this nifty new tool offers dynamic instrumentation like DTrace, using aspects. Marcel Grünauer builds on top of Adam Kennedy's awesome Aspect Oriented Programming (AOP) Perl interface (that also reached 1.0 in 2011) to provide a tool that lets you change application's behavior without actually touching the source code. Very nice!

Lucy - David Wheeler released a nice Perl wrapper for Apache Lucy, a high-performance, modular full-text search engine library that assimilated the KinoSearch codebase and community.

Data::Printer - I don't like to talk about stuff I wrote doing general retrospectives, but I'm going to open an exception here. Data::Printer provides a simple and powerful - not to mention, colorful! - way to view your data structures. It's highly customizable and if you ever used Data::Dumper to view variable contents on the screen, you should give it a try :-)

There were also some visible trends on CPAN last year:

Towards a lighter Moose: everybody loves Moose (which also reached 2.0 in 2011!), but sometimes you just want - or think you just want - the sugary OO syntax, not the full-blown object system. Or maybe your particular environment doesn't let you install it, and you still need some small piece of it to make everything better. In 2011 there were a lot of uploads for Moose and Mouse alternatives, including Moo, Mo, and Mite. This definitely shows an itch that needs some scratching.

On a somewhat related note, Stevan Little is developing a proposal and a functioning prototype for a Meta Object Protocol, or MOP, to be perhaps included in a future version of Perl 5. Comments are welcome!

Sysadmin tools: Matt S. Trout took the time to bolt some modules together and bring us Tak, a multi-host remote control over ssh. But he wasn't the only one, and new sysadmin tools and modules sprouted all over the perlverse. Some fine examples include helm, providing easy server and cluster automation, and the great Rex (or, rather, "(R)?ex"), that lets you manage all your boxes from a central point through the complete process of configuration management and software deployment. Check out rexify.org for a quick glimpse of some of its features!

Simple ORMs: another trend in 2011 was to create simple DBI wrappers providing ORM-ish features, resulting in lightweight frameworks somewhere between DBI and DBIx::Class. Among the new distributions are Teng and DBIx::Sunny.

Dependency Managers: Finally, following Ingy's "only" pragma from back in 2003, a lot of effort has been put into making new and improved dependency managers for Perl applications and distributions. Miyagawa's carton and Gugod's perlrocks deserve particular attention.


That's it for this 2011 Perl retrospective. Hope you guys had as much of a nice time reading it as I had writing it. Let 2012 be the year of the Velociraptor!!

Friday, 18 February 2011

Teaching Perl to Undergraduates

Perl is an amazing programming language. And, with its growing worldwide re-popularization, it was an easy sell to the Computer Science Department of the Federal University of Rio de Janeiro, one of the best and most famous universities in Brazil, when I offered to give a free Perl summer class to the undergrads.

The idea was to give students the opportunity to learn a new language, presenting the concepts, structure, best practices and design patterns of modern Perl 5. It was also my response to seeing so many companies here complaining about the lack of Perl developers, forcing them to use other languages even when Perl would be the best alternative for them.

And what a huge success it was!

The course was given by Bruno Buss and myself, with me doing the talk and him preparing and giving exercises to the students and helping them with their code. At first we were hoping to get about 10 students interested, specially since we didn't have time to advertise the summer class at all. In fact, due to uncontrollable events, we could only confirm it and open registration two weeks before the class itself started. Even so, we decided to carry on with it. Later that night I got a message from Buss: "we're gonna need a bigger room".

Turns out that in less than 24 hours we already had over 25 undergrad students registered for the course! We kept registration open as a waiting list, since we couldn't find an available lab with more than 25 PCs in such a short timeframe. A day before the beginning of the class there were over 50 students applying for a spot, even though they already knew the class was full!

And this is Perl competing against student vacations, during summer, in Rio.

The course was one week long, from 1pm to 5pm (yes, we had to compensate $dayjob during nighttime, but it was well worth it). Slides for all 5 days are available. It's mostly Perl, with a little Portuguese here and there like variable names, values and complementary information whenever necessary. Here's what we covered:

  • Day 1 (slides) - What's Perl all about; how to use perldoc; the modern and safe header (use 5.12.3; use warnings); basic I/O; scalar variables; manipulating numbers and strings; conditionals; loops; and file I/O, with autodie to capture exceptions. We also spoke about the Perl community, showed off a bit of Padre, the Perl IDE, and encouraged students to use chromatic's brilliant "Modern Perl" book as reference material.
  • Day 2 (slides) - Running external programs; arrays (and how to manipulate them); hashes (and how to manipulate them); scalar x list x void context. That, and lots of exercises to fixate what they learned so far.
  • Day 3 (slides) - References; building complex data structures; functions (subroutines); stack traces with Carp and Carp::Always; and retrieving command line arguments with Getopt::Long. While explaining anonymous subs we also mentioned/demonstrated closures and state variables, but didn't really get into it as it was a beginners class. The day ended with an explanation of Perl's sweetheart, the CPAN. We showed students not only how to install modules (with local::lib), but included an explanation of the full CPAN stack, including web search, CPAN Testers, Deps, Ratings and Bug/Request Tracking. We also discussed how to exploit those features (and other common tips) to pick a good module (and, of course, Task::Kensho).

Students were mostly from Computer Science, with around 6 of them being from Biology/Biophysics/Bioinformatics, and one or two from Electric Engineering and Applied Mathematics. In the end, there were 27 undergrads. Yes, 27. It was very rewarding to see 2 booted students showing up anyway, with their laptops, asking if they could sit on the back and participate. Of course they could :)