Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Aristotle (5147)

Aristotle
  pagaltzis@gmx.de
http://plasmasturm.org/

Blah blah blah blah blah [technorati.com]

Journal of Aristotle (5147)

Sunday August 31, 2008
06:13 PM

This is me gloating (about our proper block scoping)

Erik Meijer :

The semantics and differences in variable capture mechanisms for closures between various programming languages is a fascinating topic. One of my favorite examples is^H^Hwas Ruby’s scoping mechanism for blocks. The problem is acknowledged and eloquently explained on page 105 in the second edition of the pickaxe book. I am particularly amused by the proposed pragmatic solution; keep your code small so that it is easy to spot any potential problem, and use some form of Hungarian notation to put local variables and block parameters in a different lexical namespace. Fortunately, this issue is fundamentally fixed in Ruby 1.9

He then goes on to explain how C# and Javascript made this very same mistake in slightly different ways. (Python, of course, has phenomenally worse mistakes in its closure capture semantics.)

Perl 5 got this right from the start.

Thursday August 07, 2008
12:38 AM

15 minutes

Tuesday August 05, 2008
02:11 PM

Stringifying URI objects to relative URIs by default

You only need a trivial subclass of URI::WithBase:

{
    package URI::WithBase::Rel;
    our @ISA = qw( URI::WithBase );
    use overload '""' => sub { shift->rel->as_string(@_) }, fallback => 1;
}

If you stringify objects of this class URI::WithBase::Rel, the stringified URI will always come out relative to the base URI of the object. (If you happen to need a non-relative URI out of it, you can call the as_string method explicitly.)

Next, if you happen to be using Catalyst, put something like this in your MyApp.pm:

sub uri_for {
    my $c = shift;
    return URI::WithBase::Rel->new( $c->NEXT::uri_for( @_ ), $c->req->uri );
}

Now all the unadorned uri_for calls in your templates will produce nice relative URIs.

(The alternative would be to install URI::SmartURI and Catalyst::Plugin::SmartURI… but for this very simple use case of “relative URIs nearly all the time,” the amount of code in those modules alone, much less the huge pile of code they pull in via prerequisites, seems completely unjustifiable.)

Saturday June 21, 2008
07:27 AM

Help get Perl onto Google App Engine

Stephen Adkins :

I have been promoting the idea of a community project to get Perl supported on Google App Engine.

I have made various contacts with people inside Google, and it seems that the core App Engine team is busy with plenty of other things. However, this does not stop the community from getting something started. We will likely attract perl advocates within Google as we go along, even if they are not on the App Engine team. I would like to see the effort advance until the point where it becomes a simple matter for the App Engine team to embrace Perl.

I have started a project for all people interested in following this effort or contributing toward it.

http://code.google.com/p/perl-appengine/

Please visit the website, sign up for the mailing list, spread the word, and start contributing.

Sunday June 15, 2008
12:42 AM

Clean encapsulation for old URI redirects in Catalyst apps

At work, I develop and maintain a web application that I recently ported to Catalyst. One of the problems that showed up after the transition was broken links. The few most important ones were fixed at the source, but we have quite a few of them as literal strings in user content that sits in the database (possible but not easy to edit programmatically), and of course there are links on external sites (foremost being Google, of course) that we don’t control. So I needed to find a way to recognise the old URIs and redirect them to wherever they map to in the new structure – basically, a job for mod_rewrite.

However, I run the app standalone using Catalyst::Engine::HTTP::Prefork (andyg++), so mod_rewrite itself is out. There is an Apache reverse proxy in front, but I don’t want these redirects to depend on any particular deployment configuration, and I want them to be easily testable. So they need to be part of the application.

Where do I put them?

At first I did this in the regular way, creating some new controllers and writing actions in them. Catalyst’s Chained dispatch provides quite detailed control over URI structures, so this mostly worked. But it turned out to be quite clumsy: it took a lot of code for a relatively simple task, cluttered up the Catalyst dispatch table, and didn’t really work right. This is because the URI structure of the old app was slightly polymorphic in a way that could only awkwardly be made to fit into Catalyst, and dispatch became sensitive to the load order of controllers.

No good.

I puzzled over how to handle this, shuffling actions around in a number of ways before inspiration struck me. See, I have an e404 action in my root controller. The default action forwards there unconditionally, and many other places in the application do so conditionally, eg. when the request URI maps to a database record that doesn’t exist. Now you can already see where this is going: rather than just showing the 404 page, as this action used to do, it now runs a bunch of pattern matches against $c->req->path to see if the URI corresponds to the old apps’ structure. If it does, bits and pieces of the URI are captured and used to construct a new-style URI using $c->uri_for, and this is sent to the client as a permanent redirect. Basically, the 404 handler now makes a last-ditch attempt to salvage the request.

This works very well: all of the logic is isolated in a single spot where it is invisible to Catalyst’s dispatcher. It’s a minor design decision but nevertheless pleases me as it turned out so very right.

Tuesday April 22, 2008
09:13 PM

Jim Weirich, author of Rake, on “DSLs”

InfoQ :

I feel the term has probably been overused. I like to consider a Domain Specific Language to be something that talks about [a] problem domain, such as configuring workflow to solve some business problems or […] something that is business related in the problem space. And I see a lot of us using Domain Specific Languages to solve programmer problems, which are really problems in the solution space.

[…]

What I want to use a DSL for is I want to be able to take a problem that a user comes to me and […] create a DSL that describes it. I don’t think that the business person needs to be able to write the DSL, but I should be able to write it in the DSL, show it to a business person and they can say: “Yes, that’s what I want” and it is something that is immediately obvious to them that it solves their problem domain. It’s Domain Specific Language and if it is not addressing a domain, the term DSL seems kind of loose for me.

[…]

So I think you can have libraries with good interfaces but that doesn’t necessarily make them DSLs, certainly dropping parenthesis off a library call doesn’t make it a DSL.

What a refreshing perspective.

This is the first time I have heard someone give a definition of “DSL” that is restrictive enough to have actual meaning. Later on he also gives a similarly reasonable definition of BDD, Behaviour-Driven Development. (His first statement? There’s no difference between BDD and TDD.)

[The transcript is kinda hidden; you need to click show all at the bottom of the inset frame to read it.]

Wednesday April 09, 2008
03:22 PM

Derivative? What does that mean?

Here is something I personally never really figured out:

When does derivative code cease to be derivative?

Several times I have taken code written by other people and put it through so many cycles of refactoring that, even though each of the intermediate steps is clearly derivative from the previous one, the result bears no resemblance to the original whatsoever. Is it still derivative? The original code served as a springboard, and for that certainly continues to deserve credit. But both the computational expression of the problem in question and the understanding that led to that particular expression is entirely my own. The credit I owe in that case seems like the credit a successful pupil might owe to a teacher: the work is still the pupil’s. I learned from the code – by scrapping it piecemeal, in a gradual process of transformation, in which the result feels like mine.

Who has copyright on that work?

When does imitation end and inspiration begin?

Tuesday April 01, 2008
07:02 AM

RFC: DateTime::Weekdays

I just went to set up a cron script to automatically mail the date of our next Perlmonger meeting to our mailing list, and was boggled to find that DateTime includes no way to do things like finding the next Tuesday past a given date, nor is there anything for that on CPAN. Instead you are apparently expected to copy-paste some slightly fiddly code from an FAQ and tweak it.

Sorry, that’s just not acceptable. So I whipped this up:

#!/usr/bin/perl
package DateTime::Weekdays;
use strict;
use DateTime ();
BEGIN { our @ISA = qw( DateTime ) }

sub set_day_of_week {
    my $self = shift;
    my %a = @_;

    my ( $dow, $wanted_dow ) = ( $self->day_of_week(), $a{ dow } );

    if( $a{past} ) { $_ = -$_ for $dow, $wanted_dow }

    my $delta = ( $wanted_dow - $dow + 7 ) % 7;

    return $self if $delta == 0 and not $a{always_differ};

    $delta += 7 if $a{always_differ};
    $delta = -$delta if $a{past};

    return $self->add( days => $delta );
};

sub next   { $_[0]->set_day_of_week( dow => $_[1] ) }
sub prev   { $_[0]->set_day_of_week( dow => $_[1], past => 1 ) }
sub coming { $_[0]->set_day_of_week( dow => $_[1], always_differ => 1 ) }
sub last   { $_[0]->set_day_of_week( dow => $_[1], always_differ => 1, past => 1 ) }

1;

__END__

=head1 NAME

DateTime::Weekdays - find nearby DateTimes by weekday

=head1 SYNOPSIS

use DateTime::Weekdays;
my $dt = DateTime::Weekdays->now;
my ( $Thu, $Fri ) = ( 4, 5 );

print 'First Friday of this month: ',
   $dt->clone->truncate( to => 'month' )
             ->next( $Fri );

print 'Last Friday of this month: ',
   $dt->clone->truncate( to => 'month' )
             ->add( months => 1 )
             ->subtract( days => 1 )
             ->prev( $Fri );

print 'The Friday before today: ',
   $dt->clone->last( $Fri );

print 'London.pm heretics meeting this month: ',
   $dt->clone->truncate( to => 'month' )
             ->coming( $Thu );

=head1 DESCRIPTION

A subclass of L<DateTime> that includes a few methods for weekday-based
calculations.

=head1 INTERFACE

The workhorse method in this class is C<set_day_of_week>. You are not expected
to call this directly; instead, use the convenience methods provided. They all
expect a single parameter: a weekday number.

=head2 next

The nearest future date with the given weekday. May be the current date
itself.

=head2 prev

The nearest past date with the given weekday. May be the current date itself.

=head2 coming

The next future date with the given weekday. This is always at least one day
in the future.

=head2 last

The most recent past date with the given weekday. This is always at least one
day in the past.

=head2 set_day_of_week

This method implements the calculation. It accepts the following named
parameters:

=over 4

=item C<dow>

The desired weekday number in DateTime convention (ie. a value in the range of
1..7 meaning Monday..Sunday). This parameter is requirement.

=item C<past>

A boolean specifying whether to look for a date with the desired weekday is in
the past, relative to the starting date.

=item C<always_differ>

A boolean specifying whether the date returned must always be in the future
(or past).

F.ex., if the date in question is a Friday and you ask for a Friday in the
future, then normally the date itself will be returned with no changes. If
you set this parameter, however, then the Friday in the following week will
be returned.

=back

=head1 AUTHOR

Aristotle Pagaltzis L<mailto:pagaltzis@gmx.de>

=head1 COPYRIGHT AND LICENCE

Copyright (c) 2008, Aristotle Pagaltzis. All rights reserved.

This module is free software; you can redistribute it and/or modify it under
the same terms as Perl itself. See L<perlartistic>.

=head1 DISCLAIMER OF WARRANTY

BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE
SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE,
YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO
LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER
SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

Look good? Anyone willing to write a test suite for me? :-P

Wednesday March 12, 2008
11:13 AM

Polymorphism != Inheritance (or, Paging chromatic)

Reginald Braithwaite :

In other words, whenever you declare that Child IS-A Person, the compiler writes “Child HAS-A Person” and “Child BEHAVES-LIKE-A Person” and “Child DELEGATES-TO Person” for you.

Monday February 25, 2008
10:52 PM

The 7th circle

Kaare Rasmussen :

My last visit to SOAP in Perl land was some 5-6 years ago when the World was young and Perl land was unstructured as Hell. (Actually I don’t know if Hell is unstructured or not, perhaps it’s written in Java. That would make sense, I guess).

Hell is both: an enterprise system written in Java that uses a 3,000-class hierarchy to abstract away the generation of obfuscated Perl code which actually does the job. Savour the taste.