March 2017 Archives

Using the Perl debugger with DBIx::Class

I wrote about using the Perl debugger with Moose. In that post, I showed how to use DB::Skip to make it easier to use the Perl debugger with Moose and other modules whose guts you don't want to wade through.

Today's debugger hack will make using the debugger with DBIx::Class much easier.

Saving your test suite history

If you saw my FOSDEM talk about Building a Universe in Perl, I show some examples of the code we use to model behaviors in our universe. I start talking about out test suite at one point and that's probably the most exciting part. You see, we've been fixing our leaderboard system in part because I can do this:

That's a truncated version of our test failure report for tests failing on master. Leaderboard tests show up twice in there.

Ever have an failing test and trying to remember if it failed before? Is it fragile code? Is it fragile tests? Has it ever failed on your master branch? What percentage of your tests fail? Well, now you can find out.

Metric Time in Tau Station

If you've been following our progress with Tau Station, you know we're creating a science fiction universe in Perl for people to enjoy. As of this writing, the time in Tau Station is 194.10/51:647 GCT.

"GCT" stands for "Galactic Coordinated Time" and that's a variant of metric time. As a software developer, I wish we had that in the real world, but alas, we don't.

The GCT time listed above is roughly 194 years and 10 days after the "Catastrophe" (an apocalyptic event that effectively serves as our "epoch"). There are 100 days in a year, 100 "segments" in a day (14.4 minutes each) and 1000 units in a segment (.864 seconds each).

I love the fact that figuring out the display time for GCT is this simple:

my $days = sprintf "%9.5f" => $seconds_since_catastrophe / $second_in_a_day;
$days =~ m{^(?<year>\d+)(?<day>\d\d)\.(?<segment>\d\d)(?<unit>\d\d\d)}a;
my $gct = "$+{year}.$+{day}/$+{segment}:$+{unit} GCT";

Due to imprecision in normal dates, we don't get an exact round-trip conversion between regular DateTime objects and GCT, but so far we've not found them more than a second off.

Figuring out durations (D0.00/12.500) is similarly simple:

my $days = sprintf "%9.5f" => $duration_in_seconds / 86400;
$days =~ m{^(?<years>\d+)(?<days>\d\d)\.(?<segments>\d\d)(?<units>\d\d\d)}a;
my $duration => "D$+{years}.$+{days}/$+{segments}:$+{units}";

Of course, since that means we often need to know the total number of seconds, we have this nasty bit of code to figure that out:

sub period (%args) {
    my $seconds = delete $args{seconds} // 0;
    $seconds += ( delete $args{minutes}  // 0 ) * 60;
    $seconds += ( delete $args{hours}    // 0 ) * 3600;
    $seconds += ( delete $args{days}     // 0 ) * 86400;

    # solar year
    $seconds += ( delete $args{years}    // 0 ) * 31_556_925.97474;
    $seconds += ( delete $args{units}    // 0 ) * .864;
    $seconds += ( delete $args{segments} // 0 ) * 864;
    if ( keys %args ) {
        my $unknown = join ', ' => sort keys %args;
        croak("Unknown keys to Veure::Util::Time::period: $unknown");
    }
    return round($seconds);
}

Metric time is lovely and easy. Regular time sucks.

I really wanted to write a DBIx::Class inflator to use GCT objects instead of DateTime objects, but found too many assumptions about the use of DateTime in the DBIx::Class code, so we scrapped that bit. Darn shame.

About Ovid

user-pic Freelance Perl/Testing/Agile consultant and trainer. See http://www.allaroundtheworld.fr/ for our services. If you have a problem with Perl, we will solve it for you. And don't forget to buy my book! http://www.amazon.com/Beginning-Perl-Curtis-Poe/dp/1118013840/