|
Recent Entries...
Re: Vibram FiveFingers FTW
Hats off to whoever wrote this up and potesd it....
Re: A little more detail on using a new model
百度
[url=http://www.sina.com]sina[/url]
...
Re: Catching up through week 7
Re: Porting a non-Moose object to Moose
Wow, look what I found,
greedy genius ...
Re: Porting a non-Moose object to Moose
Kevin,
You're right, that does seem a little confusing. ...
Re: Porting a non-Moose object to Moose
Wait. I'm confused. Moose isn't the tool to reach for. So...
Re: Porting a non-Moose object to Moose
You should switch to MooseX::Types to declare your Typed and...
Porting a non-Moose object to Moose
I'm currently working with a lot of legacy code in an envi...
Testing strategy for mocking code
I keep finding myself using the following idiom for writing ...
Re: Library Woes on OSX
Have you considered changing your hosts file so it connects ...
|
|
weblog | `web·lôg -läg |
noun
Another term for BLOG
ORIGIN 1990s: from web in the sense [World Wide Web] and log in the sense [regular record of incidents.]
blog | bläg |
noun
A web site on which an individual or group of users produces an ongoing narrative.
ORIGIN a shortening of WEBLOG.
Porting a non-Moose object to Moose
 Posted by
on Tuesday, September 15 2009, 2:27pm
I'm currently working with a lot of legacy code in an environment where the other developers haven't been brought up to speed on things like Moose just yet. I've been tasked with writing some modules in support of this legacy code on a legacy platform - so Moose probably isn't the first choice of tools to reach for.
The module I created is a lightweight wrapper around PDF::API2 that handles a very specific case - adding an image to an existing PDF file. Naturally, Moose is installed on my laptop, so after creating a recent module in older style perl with a hash based object I decided to re-implement it in Moose.
The first comparison I'll look at is object instantiation.
use constant ARGS => qw/pdf_template image new_filename/;
sub new {
my( $class, $arg_ref ) = @_;
my( $pdf_template, $image_file, $new_filename )
= ref $arg_ref eq 'HASH'
? @{ $arg_ref }{ ( ARGS ) }
: ( $arg_ref );
my $self = {};
bless $self, $class;
$self->_clear_saved;
die "Can't read PDF template - $!" unless $pdf_template && -r $pdf_template;
$self->_set_pdf( PDF::API2->open( $pdf_template ) );
$self->add_image( $image_file ) if $image_file;
$self->save( $new_filename ) if $image_file && $new_filename;
return $self;
}
sub _set_pdf {
my( $self, $pdf ) = @_;
die "Invalid PDF object" unless $pdf && ( ref $pdf ) =~ /^PDF::API2/;
$self->{pdf} = $pdf;
$self->_set_page( $self->_load_page );
$self->_set_gfx( $self->_load_gfx );
$self->_set_dimensions( $self->_load_dimensions );
return;
}
There's really just a few things to point out here.
I've designed the object so that it will either accept a single string as an argument, or a hashref containing key => value pairs of the pieces of data used to setup the object; in this case a PDF template filename, an image filename, and a new filename to save a resultant file as. To make this module as easy as possible to use, I have it setup so that if all arguments are passed in the constructor, the object knows enough about what's needed from it and does everything - even saves the new file.
I've included the _set_pdf() method because that one is always called for my definition of a successful object instantiation. As you can see, once it sets the private object member {pdf} to the new PDF::API2 object passed in, it also sets a few other object member data based on the PDF::API2 object.
After setting these in _set_pdf(), the code checks to see if there's an image file and a new filename. We'll get to that part later.
One way to create the analog to the above code using Moose :
use Moose;
use Moose::Util::TypeConstraints;
has 'pdf_template' => (
is => 'rw',
isa => 'Str',
required => 1
);
has 'image_file' => (
is => 'rw',
isa => 'Str'
);
has 'new_filename' => (
is => 'rw',
isa => 'Str'
);
has 'image' => (
is => 'rw',
isa => 'PDF::API2::Resource::XObject::Image::JPEG'
);
subtype 'MyPDF'
=> as 'PDF::API2';
coerce 'MyPDF'
=> from 'Str'
=> via { PDF::API2->open( $_ ) };
has 'pdf' => (
is => 'ro',
isa => 'MyPDF',
coerce => 1,
lazy_build => 1,
);
sub _build_pdf { shift->pdf_template }
sub BUILD {
my $self = shift;
if( my $image = $self->image_file ){
$self->image( $image );
if( my $filename = $self->new_filename ){
$self->save( $filename );
}
}
}
The first item of interest is that I'm letting Moose::Util::TypeConstriants handle the coercion of a string (the PDf filename) to a PDF::API2 object. I'm also setting the pdf attribute to lazy_build. A little more on that later.
Additionally - for the rest of the attributes, most of the work is done for me by Moose - I only need to tell it what attributes my class is going to have, and Moose does all the setting and type checking for me.
Notice there's no new() subroutine - that's because Moose takes care of creating a default constructor, which will take care of parsing the argument(s) to the constructor for us.
Because I am creating a literal translation of the previous object in Moose , I decided to give it the exact same behavior. I originally started adding the extra functionality to the constructor by creating an after() modifier, but that had a couple of problems - the first of which was the fact that I could no longer follow the Moose best practice of making the class immutable .
I also ran into an issue using after() with deep recursion - notice how after setting the pdf attribute I use it (the pdf attribute) again to set the page attribute. This had the fun effect of calling after() again, after accessing the pdf attribute. Oops :)
I then tried around() but that had also didn't let me set the class to be immutable. So I settled on using a BUILD() method.
I originally had a few more calls to other attributes' setup inside my BUILD() subroutine, but Chris Prather suggested I move those pieces to lazy_build attributes , in which advice (and the accompanying documentation) I found great wisdom. The thinking is that the value for these attributes depend on another attribute - so these attributes /must/ be lazy. I've left out those definitions, but I'll get to those in a later post.
Testing strategy for mocking code
 Posted by
on Wednesday, September 09 2009, 1:12pm
I keep finding myself using the following idiom for writing unit tests in perl for modules that have to interact with other modules.
use strict;
use warnings;
use Test::More tests => 4;
{
no warnings qw/redefine once/;
local *ModuleToMock::MethodToMock = sub {
ok( 1, 'got a call to the method' );
is( ref $_[1], 'HASH', 'got an hashref as an arg' );
is( $_[1]->{param}, 'value', 'got a reasonable value as a param' );
return 'sensible return value';
};
my $obj = ModuleThatsBeingTested->new();
my $return = $obj->OtherMethodThatCallsMockedModule(
param_passed_along => { param => 'value' }
);
like( $return, qr/sensible return/, 'got a reasonable return' );
}
Yes, I know about Test::MockObject but for some reason I never reach for it these days. For comparison purposes, using Test::MockObject in the above example might look like:
use strict;
use warnings;
use Test::More tests => 4;
use Test::MockObject;
my $mock = Test::MockObject->new();
$mock->fake_module(
'ModuleToMock',
MethodToMock => sub {
ok( 1, 'got a call to the method' );
is( ref $_[1], 'HASH', 'got an hashref as an arg' );
is( $_[1]->{param}, 'value', 'got a reasonable value as a param' );
return 'sensible return value';
},
);
my $obj = ModuleThatsBeingTested->new();
my $return = $obj->OtherMethodThatCallsMockedModule(
param_passed_along => { param => 'value' }
);
like( $return, qr/sensible return/, 'got a reasonable return' );
I'm not sure what caused me to stop using it, though. I've heard recently (in fact, as I was writing this post and pondering its use):
NOOOOOOOO! it loads UNIVERSAL::isa and ::can. If I want to mock something I make a mock class.
But I'm sure that never entered my thought process.
Maybe I just thought it was too much setup, even though it's really only a couple of lines of code more.
Maybe it's because I can never remember the exact syntax for setting something up with it, without consulting either previous test code I've written or the documentation. I had to check both before posting this.
Library Woes on OSX
 Posted by
on Tuesday, September 01 2009, 1:00am
I've been trying off and on to get Device::USB up and running on my mac in order to be able to talk to some USB devices via perl. But that depends on having libusb installed (properly, mind you) - which I have just had no luck getting to work.
I did find some precompiled binaries for my OS version, but Device::USB doesn't seem to like it.
Maybe I'll grab the source for libusb and compile it myself and see how that goes. I have high hopes.
Related Photos:
code
mac
perl
Tired eyes
 Posted by
on Thursday, August 20 2009, 8:00pm
It's so easy to miss things if you're just casually trying to familiarize yourself with some perl code that's brand new to you.
It wasn't until I was creating a comprehensive set of unit tests and calculating code coverage metrics that I saw this not once, but three times in a row...
if( condition ){
die "some appropriate error message";
return;
}
Of course, even when writing the tests, I didn't spot it until I was writing a test for the last if.
Thankfully Devel::Cover quickly highlighted that no matter what I tried, I couldn't write test code to exercise that return; statement.
Same thing with this one:
sub method {
my( $self, $args ) = @_;
return unless $args->{ key };
if( $args ){
}
}
I couldn't understand why I couldn't manage to manipulate the inputs of method to cover all branches of that if.
And then I realized it would never get that far with the early short-circuit return. Duh.
Related Photos:
code
perl
Vibram FiveFingers FTW
 Posted by
on Tuesday, April 28 2009, 12:53am
I picked up a pair of Vibram FiveFingers shoes today, and they felt great.
Tonight I went on my semi-regular "run with the dog at the park" with the Vibrams and it was awesome.
You pretty much have no choice but to run "right", i.e. as if you were running barefoot. What this means is that you don't have the "heel-to-toe" stride that sends jarring impact up through your heel into the rest of your body. I just had a light springy bounce on the balls of my feet - which felt like a dream and brought back memories from childhood of running through the yard without a care in the world.
It was a little chilly and rainy out tonight, so before I got moving (and every time I had to stop for the dog's benefit) my soles got a little cold.
I'm also going to have to re-think wearing socks under them - something was a little off and the fabric of my feelmax socks got a little bunched up around a few of my toes, adding a little compression which became uncomfortable.
I can also tell the change in the stride/footstrike pattern is going to challenge my calves a bit more. Good thing I'm still in the gentle re-introduction to running where I'm already taking things pretty light for maximal injury avoidance.
Related Photos:
None
It's Clobbering Time!
 Posted by
on Tuesday, April 21 2009, 12:52pm
I'm putting my time off to good use.
Last week I pulled down a bunch of jury-rigged shelves and the drywall behind them, and hauled most of the rubble out. I still need to break down the shelves.
Today I hauled out three large (and heavy) contractor bags primarily full of "previous owner detritus" as well as two boxes - one of which was new(?) or at least unused subfloor adhesive tubes (which maybe someone cruising the alley might find a use for) and a box full of (wrong-sized!) discarded air filters.
I also found a replacement piece of glass for the glassblok window in the basement that's been missing a piece of glass - so I screwed that into place. That'll help keep the basement warmer in the winter if we don't get around to finishing it off this year.
I think I'll cut down the makeshift shelves and remove the crappy cabinets throughout the basement next.
Updates on their way
 Posted by
on Tuesday, April 14 2009, 2:38pm
It hasn't been too many posts since I've had to apologize for not posting in a while. And as it's been over three months since my last post, I suppose an apology is not only in order, but long overdue.
So having said that, I'm sorry :)
Recently, I've had to take some time off my routine for illness, and then I had to extend that time off for injury - i.e. my gradually worsening back pain. Well, mostly sort of kind of partly recently. I've been easing my way back into a workout routine the last month or so.
Of course I can't forget that Matthew, my son, turned one just a few short weeks ago, so there was the whole getting ready for the party, and the party, and the clean up/organization involved with that.
And then there's my sudden excess of spare time due to my recent bout of unemployment. Which is a good thing - I get to spend a little more time with Matthew, as well as take care of some thing around the house that I haven't found time to take care of in the last year.
So I'll add an update here once I get a little more time ;-)
Merry P90X-mas!
 Posted by
on Tuesday, December 30 2008, 11:33pm
So much to write, so little time.
Having trouble remembering what I did and when (again) - so I'll work backwards. Again.
So because of all of that, I decided to re-start week 11 this week and I did the Chest and Back routine on Tuesday. I think I did pretty well, 264 pushups (a personal best), 65 pull ups and 35 chin ups. I'm totally blowing off Ab Ripper. And I knocked the scab off my knuckle from Shoulders and Arms. At least I got to use my pull up bar again. Last week seems like it counted for something, because I got more pull ups and chin ups than I did last time I did this routine with a pull up bar. I'm really anxious to see how well I'd do on the old 100 pushups program.
And over the weekend I did Yoga X, again all of it, and came back to Chicago. Believe me, with a 20 pound child and a 12 pound dog, plus a 15 pound car seat, a 50 pound suitcase, and a ... well, I don't know exactly how hevy it is, but I'd have to say my shoulder bag fully loaded is about 15 pounds - toting all that around is plenty workout enough. Not really, but it wore me out anyhow.
Later on Christmas Day I did Shoulders and Arms. Kind of. I had to use the bands again. While I'm glad I had them, I didn't take the time before the trip to fully learn how to use them for the various exercises. I ended up abrading one of my knuckles on Congdon Curls (curl up, hammer down).
Thursday, I had some catch-up to do so I did Plyometrics in the morning, tucked away in about 5 square feet of spare room in the, uh ... spare room :) I couldn't quite get a lot of forward/backward distance with moves like Monster Truck Tires or Leapfrog Squats, so I did the best I could with the room I had. And Lisa was out spreading holiday cheer with Matthew, so I had a few minutes to run through it. She got back near the end though, I had a great time playing peek-a-boo with Matthew as he was on one side of his carseat and I was peeking around the sides as I did lateral leapfrog squats.
I'm pretty sure I skipped everything on Wednesday. I just couldn't find the time with all the errands, visitors, carseat shuffling, and Matthew toting that happened.
Tuesday evening I got out my trusty bands, mounted them in a doorway, and did the Chest and Back routine. On the one hand, I couldn't do too many more of the band pull ups than regular pull ups, which tells me that it's a fair approximation of the real deal pull ups and chin ups. On the other hand, it just didn't feel like an honest-to-goodness pull up and chin up routine. But I managed to pump out 235 push ups.
Tuesday morning, December 23rd, was spent traveling with Lisa, Matthew, Spike, and the luggage.
Monday the 22nd I was busy tying up loose ends and packing.
I'm pretty sure I did Kenpo around the 21st.
I probably did Legs and Back on the 20th, or thereabouts.
It's very likely that I did Yoga X on the 19th, give or take. Of special note, I think I finally did the entire Yoga X routine.
There's a good chance I did Back and Biceps on the 18th.
I very possibly did Plyometrics on or around the 17th.
I find it likely that I did Chest, Shoulders, and Triceps on or around the 15th.
Signs point to that I maybe did a catch up Legs and Back on the 14th.
I have a fair degree of confidence that I did Shoulders and Arms on the 11th.
The odds are pretty good that I did Chest and Back on the 9th.
The week of December 1st was supposed to be a recovery week, and it was. I was sick. Not terribly sick, but enough to make me not want to keep up with everything. I have recollection of doing Core Synergistics, Yoga, and possibly Kenpo, but I'm not so clear on that one.
And that takes me back to where I left off.
Related Photos:
None
Still here, still working
 Posted by
on Friday, December 19 2008, 1:36pm
Yes, I'm still here.
No, I haven't fallen off the face of the Earth.
Yes, I'm still moving along with P90X.
No, I haven't been fully healthy, so I've missed some workouts.
Yes, I plan to update my progress Real Soon Now™.
Related Photos:
None
Catching up through week 7
 Posted by
on Saturday, November 29 2008, 2:29pm
So it seems that nearly every time I write about what I plan to do or what I'd like to do in the near future, I do just about everything in my subconscious power to not do exactly that. And if I just shut up about it, I tend to do what I intend to do.
I actually did Plyometrics Tuesday night like I intended to do, but I think I got a fairly late start on it. Now I know I have indeed been squatting deeper ad jumping higher - my quads and glutes were sore for days.
Wednesday turned into a surprise rest day. It probably had to do with the rest of my family coming into town for Thanksgiving.
Thursday morning I did back and biceps - luckily I was able to do this because we weren't cooking for Thanksgiving, so we didn't have everyone crammed in our tiny little kitchen and making me too self-conscious to work out. Instead, I snuck in my workout before everyone came over from the hotel.
And of course, we had Thanksgiving dinner Thursday evening. Because we weren't cooking, there wasn't any taste-testing the food during preparation all day, and there wasn't any real ability to eat way too much.
I did eat a lot - hey, it's Thanksgiving after all! - but I was still able to come home and later on and do the Ab Ripper X workout. And I improved a bit from the time before, instead of just 332 moves, I did 342. Still not at the top of my game, but still up there.
Friday I did 43 minutes of Yoga again - stopping just before Warrior 3 since there's no way I can do those.
Saturday morning I mixed it up a little. Since I could still feel some residual soreness from Plyometrics, I decided to completely skip the legs part of legs and back. Instead I did all the pull ups and chin ups interspersed with bits of Ab Ripper X. All tolled, I did 76 pull ups and 51 chin ups. That's no typo, that is one hundred and twenty seven chin to the bar moves in a single workout.
For Ab Ripper X I've finally got it to the point where I do every rep of every exercise as on the Ab Ripper video. Even the cross leg wide side ups - I did 50 of those, with a few rests thrown in. And when I say 50, I mean 50 the way I started counting them, which is in reality 25 the way the video counts them. And I'm also counting the V-up roll-up combos differently - I did 13 in my way of counting where the video calls that 25. So I'm finally at the magical 349 that the video counts, which in my way of counting the moves is 362. Whew.
I'm not going to talk about what I want or plan to do tonight. Because I want to do it, and I don't want another self unfulfilling prophecy.
Related Photos:
thanksgiving
|
|