Getting Moose and Rose::DB::Object to play together

April 9, 2011

I’m fairly new to both Moose and Rose::DB::Object. and have been poking around trying to find a simple way to marry the two. Delegation and roles do the trick here.

I created a parameterized role, so that I could tell the role what Rose::DB::Object-derived class to delegate to.

package My::DB::Role;
use MooseX::Role::Parameterized;

parameter 'table' => (
is => 'ro',
isa => 'Str',
);

role {
my $p = shift;

my $class =
$p->table =~ /^My::DB/
? $p->table
: join '::', 'My::DB', $p->table
;

eval "require $class";
$class->import;

has 'db_obj' => (
is => 'rw',
isa => $class,
handles => [ $class->meta->column_names, qw(save load delete) ],
default => sub {
$class->new;
},
);
};

no Moose;
1;

In my consuming class, I specify the role and the shortened name of the Rose::DB::Object-derived class:

package My::Product;
use Moose;

with 'Prixing::DB::Role' => { table => 'Product'};
1;

With this little setup, I have working code:

use Test::More;

use_ok('My::Product');

my $product = My::Product->new;

$product->id(1);
$product->load;

note $product->created_at;

done_testing;

This outputs:

ok 1 – use My::Product;
# 2011-04-09T09:03:20
1..1

This is not thoroughly tested; I just did this tonight. But this looks like the way to go.

Further reading:

  • Kate Yoak posts a comment about her solution at Rohan Almeida’s blog (now listed as an attack site by Google, which I find odd). Link to very fierce attack site; you have been warned.
  • Inheritance from Rose::DB::Object has been possible since Moose 1.15, which introduced the -meta_name to use Moose. Renaming Moose’s meta neatly sidesteps the Rose::DB::Object method of the same name.

UTF8 follies

April 8, 2011

Character encoding issues are shortening my life expectancy. It’s been a few years since I dealt with them regularly, so they bite me from time to time.

Recently I puzzled over a set of strings that were showing up double-encoded in my Postgres database. These strings were encoded from incoming Latin 1 to UTF8, travelled around the program with their utf8 flags set, went through JSON->decode and encode multiple times without apparent harm, but once in the database, they had the telltale double-encoding gibberish characters. E.g.:


use Encode;
my $utf8_string = "Télévision extrême à domicile";
print encode('utf8', $utf8_string);
# becomes Télévision extrême à domicile

I spent an absurdly long time capturing strings and dumping during execution:

say qx{echo $str | od -c }

od being a handy Unix utility I became very familiar with in my days of converting bibliographic data.

Turns out I was focusing on the wrong leads. These strings became values in a hash which was run through JSON->encode before saving to db. What prompted the re-encoding was not the values of the hash, but the keys. These were string literals in my program which were not marked as UTF8. Perl looked at my keys, looked at my values, saw a mixed bag, and decided to run the whole thing through the shredder again, just to be on the safe side.

The solution was simple:
use utf8

Because my keys were source-code string literals, I want my source code to be UTF8. use utf8 assures that.


Started reading Perl Moderne

April 5, 2011

I picked up a copy of Perl Moderne the new book by France’s Perl Gang of Four, Damien Krotkine, Sébastien Aperghis-Tramoni, Jérôme Quelin, and Philippe ‘BooK’ Bruhat, and have just started reading it.

Perl doesn’t seem to have the presence in France that it does in the English-speaking world. I hope this book helps change that, because it’s clearly-written, commute-friendly book which covers a lot of ground, from installation to Moose. Non-French Perl hackers can pick up their professional vocabulary here too. (Make your admirers swoon with desire by murmuring table de hachage like Morticia Addams did Gomez: “Tish! You speak French!”)

I am puzzled about a seeming omission in their first-chapter discussion of editors and ready-to-install binaries: there is no mention of Active State’s Komodo IDE or ActivePerl. Perhaps because Komodo is payware? I’ll ask next time I see one of them.


Figuring out map coordinates

April 5, 2011

Many sites use vendors other than Google for their mapping needs. These may use projections that dish up non-GPS coordinates. Here’s a rough way to figure out what these coordinates are and how to convert them, without returning to school for a graduate degree in geoinformatics.

  • Make a note of the unfamiliar coordinates and the street address.
  • Search by street address at Google Maps. Get the coordinates by right-clicking at the very tip of the red indicator and choosing “What’s here?”
  • Hop over to the World Coordinate Converter web site. Choose ‘*GPS (WGS84) (deg)’ from the drop-down in the upper box (if it’s not already selected) followed by the Google Maps coordinates.
  • Fool around with target systems in the lower box. Choose some likely candidates and click Convert. Keep this up until you get results close to the mystery coordinates (don’t count on identical).
  • Click on the ? next to the coordinate system name you chose. Put on your reading glasses and find the link in the popup to spatialreference.org. Click on it. This will give you the WKID (Well Known ID) of the projection, in the form of EPSG:\d+.
  • The WKID for the Google Maps projection is EPSG:4326 (http://spatialreference.org/ref/epsg/4326/).
  • Obtain the program gdaltransform by installing the GDAL utilities on your friendly *nix box.
    On Fedora, it’s apt-get install gdal-bin

  • Now the magic incantation:

    echo $x $y | /usr/bin/gdaltransform -s_srs [/source] -t_srs [target WKID]

    You will get your desired coordinates. Gingerly carry these over to Google Maps and verify that you’re in desired vicinity. The coordinates may be longitude-first, so you may need to reverse their order.

Further reading: