New module: SQL::Functional

If you have an application with simple database needs, writing the SQL strings directly in the program works fine. If it’s bigger, an Object-Relational Mapper like DBIx::Class starts to make sense. I find the additional boilerplate of an ORM isn’t worth the effort for simple needs, but it doesn’t take much more for the overhead to be worthwhile.

Then there’s another point beyond that where the ORM doesn’t know how to effectively and efficiently run a request. When you get there, it’s time to write raw SQL again, perhaps giving the result set back to your ORM so you can continue on as if nothing happened.

How do you write that SQL? Probably with strings again, or a helper library like SQL::Abstract.

The problem with raw strings is brought up in Epigrams in Programming:

  • It’s difficult to extract sense from strings, but they’re the only communication coin we can count on.
  • The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information.

The nature of our database problem is that we’ve hit on a very complicated case, and now we’re stuck using the most ad-hoc way of structuring data. Not a good combination!

SQL::Abstract tries to address this by providing a structured way of building a string. We still have to output a string (” . . . they’re the only communication coin we can count on”), but at least we don’t have to deal with it directly. The problem is that, again, we’re getting to the most complicated cases of SQL, and SQL::Abstract abuses syntax tricks for these cases. Consider this case I pulled out of its docs:

my %where = {
  start0 => { -between => [ 1, 2 ] },
  start1 => { -between => \["? AND ?", 1, 2] },
  start2 => { -between => \"lower(x) AND upper(y)" },
  start3 => { -between => [
    \["upper(?)", 'stuff' ],
  ] },

Why are we taking references to scalars? And references to arrayrefs, for that matter? Could you copy-and-paste this to a DBA and explain what’s going on?

When you drill down a bit, the reason for these issues is that SQL::Abstract uses an Object Oriented interface to build this string, and OO is just not a good fit for this problem.

On the other hand, the problem can be solved more cleanly by combining functions that look vaguely like SQL:

my ($sql, @sql_params) = SELECT [qw{ bar baz }],
    FROM( 'foo' ),
        match( 'bar', '=', 1 ),
            match( 'baz', '=', 2 ),
            match( 'qux', '=', 3 ),

This is exactly what SQL::Functional does. Version 0.1 is now up on CPAN.

Programming Quadcopters, Part I

Video of my presentation for the Madison Perl Mongers about programming quadcopters. Part II will be given for the Millwaukee Perl Mongers on March 16th.

The quality isn’t up to snuff. I grabbed an action cam with a fisheye lens and a microphone that isn’t meant for this sort of thing. The brightness of the projector washes out the image of most of the slides. I’m putting it up for posterity, but I think I’ll redo it at home so people who weren’t there can tell what the hell is going on.

Quoting in Documentation

I just ran across a small niggle in the DateTime::Format::Strptime docs:

%N Nanoseconds. For other sub-second values use %[number]N.

I needed a 3-decimal sub-second value, so I went off and dutifully wrote:

my $formatter = DateTime::Format::Strptime->new(
    pattern => q{'%FT%T.%[3]N%z'}, 

Note my simple-stupid copy of the square brackets. This creates dates like:


Which is not at all what I had in mind. Then I smacked my forehead, remembering printf() conventions, and wrote:

my $formatter = DateTime::Format::Strptime->new(
    pattern => q{'%FT%T.%3N%z'}, 

No square brackets, and everything works fine.

This issue of direct quoting conventions reminds me of an entry on writing style from the Jargon File:

Consider, for example, a sentence in a vi tutorial that looks like this:

Then delete a line from the file by typing “dd”.

Standard usage would make this

Then delete a line from the file by typing “dd.”

but that would be very bad — because the reader would be prone to type the string d-d-dot, and it happens that in vi(1), dot repeats the last command accepted. The net result would be to delete two lines!

This isn’t quite a “standard usage” issue. It’s an American usage issue. British style for quotes sensibly puts the period on the outside, in agreement with the Jargon File above.

The problem with the Strptime method above is that the convention is ad-hoc, hoping that the reader will catch on to the author’s intent. This tends to cause problems for newer programmers, and even more experienced programmers may take a few iterations to catch on. In some cases, it could also confuse programmers with a different social background.

One solution is to lay out a style guideline at the beginning of the documentation. Programming books will often do this. It’s also similar to the way RFC2119 lays out the definitions of “MUST”, “SHOULD”, etc. in a way that’s intended to be used by other RFCs.

The problem here is that you’re expecting your readers to know that much more before getting into the nuts and bolts of your library. Language and protocol definitions need to be specified very precisely, but library documentation doesn’t necessarily require that–clarity of understanding and succinctness can be better than rigor. Plus, there’s bound to be competing systems of style guidelines, and readers will have to know all of them, or at least the more popular ones.

Instead, it’s enough to give a quick example. Consider if the Strptime docs had said something like:

%N Nanoseconds. For other sub-second values use %[number]N. Example: ‘%T.%3N’

And now there is no question on the square brackets being included in the string or not. Everything the reader needs to know is encapsulated in a single location of the docs–no referencing back to other sections or documents.

Don’t use is() in Test::More

use v5.14;
use warnings;
use Test::More tests => 2;

my $val = "2.123450";

is( $val, 2.123450 );
cmp_ok( $val, '==', 2.123450 );

This results in:

not ok 1
#   Failed test at tmp/ line 9.
#          got: '2.123450'
#     expected: '2.12345'
ok 2
# Looks like you failed 1 test of 2.

The issue is fairly obvious when it’s laid out like this: is() does a string comparison, which means that trailing zero matters. One day, though, I promise you, you’ll hit a problem like this and will spend hours debugging it, only to smack your forehead when you finally see it. You can prevent that by explicitly giving a comparison operator to cmp_ok() instead.

This is somewhat similar to the issues seen in the ‘==’ operator in JavaScript and PHP, where the language makes a guess about how to coerce the types and gets it wrong (or at least, produces unexpected behavior). Those languages invented ‘===’ to solve that, which is madness.

Got stuff that needs to be attached to other stuff? Use Attach::Stuff

I’m in the middle of a project that’s going to be continaing a Raspberry Pi, the Rpi
camera module, a GPS breakout board, an accelerometer breakout board, and a microphone breakout board. All that needs to be screwed into a lasercut case.

Now, the lasercutter at The Bodgery takes its own special format (naturally), but can also import DXF and PLT files, among others. Both of these can be exported by Inkscape, and I’ve generally found the PLT export works a little better. In any case, Inkscape can take an SVG file, which I can create programmatically in Perl easily enough.

So I worked out how to do all that with the SVG module. Thing is, the majority of boards are covered by these steps:

  1. Draw a box x mm by y mm
  2. Place a list of screw holes at designated coordinates, which all have the same radius

Which is really easy to wrap up into a single class, which gives back an SVG object with the bits above already done. If there’s something slightly more complicated to do (like making a box for the Rpi camera’s lens), then you can draw that in yourself with the SVG object you have in hand.

Here’s an example for Adafruit’s Ultimate GPS module:

use v5.14;
use warnings;
use Attach::Stuff;

my $attach = Attach::Stuff->new({
    width                => 26,
    height               => 34,
    screw_default_radius => 1.25,
    screw_holes          => [
        [ 3,       3 ],
        [ 26 - 3,  3 ],
my $svg = $attach->draw;
print $svg->xmlify;

All the stuff from the Raspberry Pi Foundation has schematics out there already, so that was easy. Adafruit’s breakout boards, however, don’t seem to have any published schematics (Sparkfun isn’t any better, as far as I can tell), so I got out the callipers and started measuring. Had to do some guess work with the screw hole location and size. After a few iterations of prototypes being etched into cardboard, I got a design that looks like it will work.

Attach::Stuff v0.652389025389315 should be out to the CPAN mirrors shortly.

“use strict” makes us forget that Perl used to be worse

What does “int a, b, c” do in Perl? Lots of people want to say that this won’t even compile. There’s even a comment on the StackOverflow post accusing OP of posting uncompilable code.

It is compilable. Without use strict, perl will accept damn near anything. What’s interesting here is that the immediate response by many people is that it’s invalid code. That was my initial reaction, and it took me a second to remind myself.

It’s interesting that we’re all so conditioned to use strict that we forgot how Perl looks without it. This is probably a good thing.

Device::PCDuino — Perl Module for Accessing I/O on the pcDuino

The Bodgery (my makerspace) was donated a few pcDuinos. These are great little devices, more powerful than the Raspberry Pi, and with a built-in WiFi adapter and Arduino-like pin headers.

One thing it lacked was a Perl interface to the I/O pins. I quickly fixed this oversight with Device::PCDuino.

Currently, GPIO and ADC pins are implemented. PWM should be easy to work out. SPI and I2C look like they’ll be a little more involved (see the Sparkfun examples in C).

Usage is about as simple as can be. Use set_output() and set_input() to set the type you want for a given pin, then call output() and input() to set or receive values, respectively. See the POD docs and the “examples/” directory in the distribution for more details.