Pinto::Remote and Pinto::Server

Today I was glad to read that the successful merge of Pinto::Remote and Pinto::Server into its main Pinto repository made Pinto::Remote work again.

I wanted to know how difficult a setup of a Pinto server could become. The requirement behind was to access a single cpan-like repository for deploying server machines. The repository should contain company-provided distributions optionally combined with a collection of cpan-available distributions.

Simple Singleton in a few lines

The other day I was working on a library which needed to have a small list of dependencies and guaranteed to run on Perl versions 5.10 and above. In order to keep the dependencies minimal I decided to code a singleton() method like this:

sub instance {
    my $class = shift;
    state $self = $class->new(@_);

    return $self;
}

Just to get me right. This is not a complain to Moo*X::Singleton modules. The snippet above is very primitive, does not provide a separate initialization and has no way of clearing an instance. But sometimes this simplicity might do its job.

Create PDF from many POD files

Using POD as the basis of documentation for Perl projects is the usual way to do. There are many modules available to convert POD into several formats. However, I was not able to find a module that creates a single PDF file from all the documentation available for e.g. a single project. Typically a series of PDF files are the result of a conversion. Combining these files and creating a hierarchical outline can be hard work.

As a simple aid, we peeked into pod2pdf and wrote a little wrapper around it in order to handle many files and create the outline. Well, this solution is not rock solid, as we rely on its internals but at least it is short and usually creating PDFs is not mission-critical.

Maybe some parts can still be improved, but for people interested, here is my first try: https://gist.github.com/2277444. Feedback welcome!

Be nice to your speakers

This year we decided not to disturb our speakers on the german perl workshop during their talks to tell them the time remaining. Instead, we printed simple tags in different colors with a short meaningful text on it. As far as we got feedback from our speakers, they liked it.

Smilies.jpg

Date arithmetic can be dangerous

Every time I review code others have written, I blame people for doing date arithmetic of their own. However, some time ago, I received a pull request for a module that had some date arithmetic inside. As all tests passed, I could not see something dangerous in it and followed the pull request. Today, I found the date tests failing. Why? Why today? Well, this is worth some investigation.

The main part of the module generates an HTTP-Header using this construct ($c is the mocked catalyst context, expire_in is a method containing the nr of seconds to expire in):

$c->response->headers->expires(time() + $self->expire_in)
    if ....some_condition...

Well, adding a number of seconds to an epoch value cannot hurt. Can it? The test looked like this:

my $expected_date =
    (DateTime->now 
     + DateTime::Duration->new(seconds => $controller->{expire_in}
    )->strftime('%a, %d %b %Y %H:%M:%S GMT');
is $c->response->header('expires'), $expected_date,
   'expired header date is OK';

For the test case having an expiry of 3 years, the test failed with a difference of exactly one second:

#   Failed test 'expired header date is OK'
#   at t/5-expire.t line 55.
#          got: 'Thu, 19 Feb 2015 18:27:59 GMT'
#     expected: 'Thu, 19 Feb 2015 18:27:58 GMT'
not ok 4 - expired header date is OK

One second? Do we have a rounding problem? No. After a while, I remembered that DateTime mentioned a leap-second in its Change-Log some time ago. This could explain our difference.

Doing time-calculations by ourselves is wrong. Replacing the header generation with a more complicated but correct construct worked. Using DateTime before 0.71 kept the old date arithmetic-tests working, but actually the tests should have failed, because the leap-second was ignored.

$c->response->headers->expires(
    DateTime->now
            ->add(seconds => $self->expire_in)
            ->epoch
)

My personal conclusion: Date arithmetic is dangerous. Be more strict to any kind of date arithmetic. Never ever do date-math again. Never. Instead: keep all date manipulating modules at a current version and trust in them. Their authors known what they are doing, I don't. I didn't :-(