Two New Modules

Vive la Revolution

There was a London Perl Mongers meeting at ZPG about ten days ago. I gave a short talk explaining why (and how) a republican like me came to be running a site about the Line of Succession to the British Throne. The meeting was great (as they always are) and I think my talk went well (I’m told the videos are imminent). The photo shows the final slide from my talk. I left it up so it was a backdrop for a number of announcements that various people gave just before the break.

In order to write my talk, I revisited the source code for my site and, in doing so, I realised that there were a couple of chunks of logic that I could (and should) carve out into separate distributions that I could put on CPAN. I’ve done that over the last couple of days and the modules are now available.

MooX::Role::JSON_LD

The first is called MooX::Role::JSON_LD. It’s a Moo role that you can add to your classes in order to make it easy to generate JSON-LD from your objects. What’s JSON-LD? I hear you ask. Well, it’s JavaScript Object Notation for Linked Data. The most popular use for it is to add structured data to web sites. Adding structured data to your web site makes it easy for Google (other search engines are available) to understand what your web site is about and that, in turn, will hopefully persuade Google to list your site higher than it otherwise would. You can see JSON-LD in action on a couple of my recent projects – https://lineofsuccession.co.uk/ and https://towerbridge.dave.org.uk/ (you’ll need to look at the source to see it).

I’ve written the module as a Moo role, which means it should be usable in Moose classes too. To add JSON-LD to your class, you need to do three things:

  • Add the role to your class
  • Define a method called json_ld_type() which defines the type of JSON-LD object that you want to generate (see Schema.Org for a list of types)
  • Define a method called json_ld_fields() which defines the fields that you want to include in your JSON-LD. There are a few ways to define that which allow you to do things like mapping an output field to a method of a different name. The details are in the documentation.

Your class inherits two methods from the role – json_ld_data() returns the data structure which will be encoded into JSON (it’s provided in case you want to massage the data before encoding it) and json_ld() which returns the actual encoded JSON in a format that’s suitable for embedding in a web page.

Genealogy::Relationship

One of the most satisfying parts of the Line of Succession site to write was the code that shows the relationship between a person in the line and the current sovereign. Prince Charles (currently first in line) is the son of the sovereign and Tāne Lewis (currently thirtieth in line) is the first cousin twice removed of the sovereign.

That code might be useful to other people, so it’s now on CPAN as Genealogy::Relationship. To be honest, I’m not sure exactly how useful it will be. The Line of Succession is a rather specialised version of a family tree – because we’re tracing a bloodline, we’re only interested in one parent (which is unlike normal genealogy where we’d be interested in both). It also might be too closely tied to the data model I use on my site – but I have plans to fix that soon.

Currently, because of the requirements of my site, it only goes as far as third cousins (that’s people who share the same great, great grandparents). That’s five generations. But I have an idea to build a site which shows the relationship between any two English or British monarchs back to 1066. I think that’s around forty generations – so I’ll need to expand the coverage somewhat!

But anyway, it’s there and I’d be happy if you tried it and let me know whether it works for you. The documentation should explain all you need to know.

The Line of Succession site doesn’t get much traffic yet – I really need to do more marketing for it. So it’s satisfying to know that some of the code might, at least, be useful outside of the project.

Installing Modules

If you’ve seen me giving my “Kingdom of the Blind” lightning talk this year, then you’ll know that I’ve been hanging around places like the LinkedIn Perl groups and StackOverflow trying to help people get the most out of Perl. It can be an “interesting” experience.

One of the most frequent questions I see is some variant of “I have found this program, but when I try to run it I get an error saying it can’t find this module”. Of course, the solution to this is simple. You tell them to install the missing module. But, as always, the devil is in the detail and I think that in many cases the answers I seen could be improved.

Most people seem to leap in and suggest that the original poster should install the module using cpan (advanced students might suggest cpanminus instead). These are, of course, great tools. But I don’t think this is the best answer in to these questions.

In most cases, the people asking questions are new to Perl. In some cases they don’t even want to learn any Perl – they just want to use a useful program that happens to be written in Perl. I think that launching these people into the CPAN ecosystem is a bad idea. Yes, eventually, it would be good to get them using perlbrew, local::lib and cpanminus. But one step at a time. First let’s show them how easy it can be to use Perl.

In many of these cases, I think that the best approach is to suggest that they use their native package manager to install a pre-packaged version of the required module.

Yes, I know the system Perl is evil and outdated. Yes, I know that they probably won’t get the latest and greatest version of your CPAN module from apt-get or yum.  And, yes, I know there’s a chance that the required module won’t be available from the package repositories. But I still think it’s worth giving it a try. Because in most cases the module will be  there and available as a recent enough version that it will solve their immediate problem and let them get on with their work.

There are three main reasons for this suggestion:

  1. People in this situation will almost certainly be using the system Perl anyway. And the  system Perl will already have pre-packaged modules installed alongside it. And installing modules using cpanminus alongside pre-packaged modules in the same library installation is a recipe for disaster. The package manager no longer knows what’s installed or what versions are installed and hilarity ensues.
  2. The pre-packaged versions will know about non-Perl requirements for the CPAN module and will pull those in as well as other required CPAN modules. One of the most common requests I see is for GD or one of its related modules. Your package manager will know about the underlying requirement for  libgd. cpanminus and friends probably won’t.
  3. The user is more likely to be used to using their package manager. Teaching them about the CPAN ecosystem can come later. Let’s ease them into using Perl by starting them off with tools that they are familiar with.

I know that both Fedora/Centos/RHEL and Ubuntu/Debian have large numbers of CPAN modules already pre-packaged for easy installation. Let’s suggest that people make use of this work to get up and running with Perl quickly. Later on we can show the the power and flexibility that comes with using the Perl-specific tools.

Of course there’s then a debate about when (and how) we start to wean these people off of the system Perl and pre-build packages and on to perlbrew/cpanminus/etc. But I think that having a community of people who are used to using CPAN modules (albeit in this slightly restricted manner) is an improvement on the current situation where people often avoid CPAN completely because module installation is seen as too difficult.

What do you think? Are there obvious errors in my thinking?

Perlanet Improvements

I can be a bit of a lazy open source author at times. I love it when someone improves my code and then just emails me patches. I love it even more now that I’m using Github so that people can just fork my code and send me pull requests.

That happened over the weekend. I got a pull request from cycles saying that he’d been refactoring Perlanet and asking if I’d be interested in merging his changes. These refactorings had come out of a mini-hackathon that had been run by the North West England Perl Mongers. I knew that they had been interested in using Perlanet to power the Iron Man aggregator, but that the monolithic nature of  the code made it hard for them to subclass the bits that they needed to change.

So what cycles has done is to take my code and break it down into a number of smaller functions (and a couple more classes) so that people can subclass it and override methods where they want different behaviour to the defaults that I use. I can see this leading to a little ecosystem of Perlanet subclasses where people release their favourite tweaks to CPAN. I see this as a good thing.

I liked cycles’ changes so I merged them into my repository. They’re available there now if you want to look. I haven’t yet released a new version to CPAN as there are a few things I want to check out first.

Firstly, this new update seems to have increased the version of Moose required. With the version of Moose that I was running on my system (0.88), a lot of the tests were failing. Updating to 0.93 solved that problem. I need to work out exactly what the problem was and update the “requires” line in Build.PL appropriately.

Secondly, the newer version of Moose gave a deprecation warning when used with CHI. Updating to the latest version of CHI fixed that (but that, in turn, meant upgrading a few modules in the Log::Any family). This is all starting to get a bit too close to the bleeding edge of CPAN for a module that I want as many people as possible to use.

Finally, cycles had started to use TryCatch in the module. Not, of course, that I object to high quality exception handling in my code, but this is another module that isn’t yet in general use. It’s something that you won’t find in a “standard” (whatever that means) Perl installation.

I’m in the process of building RPMs of all of the missing modules (or later versions for the modules where the Fedora/Centos build is just lagging CPAN a bit). They’ll be available from rpm.mag-sol.com in the next few days.

Currently I’m leaning towards just releasing the new version and hoping that the people who want to use it will have enough enthusiasm that they won’t complain about the updated and new modules that are required. But I thought it would be interesting to ask for your opinions too.

As a user of CPAN modules, how do you decide when a module is too cutting edge for you to use? Do you just install newer versions of modules automatically when an installation asks you too? Or are you a little more careful than that? Would the constraints in this latest version of Perlanet prevent you from using it?

And as a writer of CPAN modules, how cutting edge do you allow yourself to be? Are you happy to release stuff that only works with the very latest versions of Moose or other fast-moving modules? Or do you like to ensure that your stuff is usable by people who might be a little behind the curve?

I should make it clear that I’m very grateful for the work that cycles did and I’m not disparaging his efforts at all. I’m just dithering a bit about how cutting edge I want to be.

New CPAN Releases

I haven’t been particularly prolific in releasing new versions of my CPAN modules recently. But over the last couple of days I finally got my act together and release new versions of three modules.

In all three cases, I’ve fixed pretty obscure bugs, added minor functionality or fixed the documenation. There’s nothing there that is a particularly compelling reason to upgrade.

Joining the Github Massive

I got tired of hosting my own Subversion repostories and having to deal with setting up access for anyone who wanted to work on my CPAN code (ok, honestly, that was two people in the last five years!)

So I’ve moved all of my CPAN modules (and a few other random bits and pieces to Github. Let them deal with the hosting issues and, more importantly, let anyone who wants to hack on my code.

You’ll find it all in my Github account. Feel free to dabble.