Today I evangelized my Sony reader, and ebook devices in general, to two separate people. So I figure I ought to do it with a bit wider audience.
I had about four devices to choose from. The iRex Iliad, the Bookean Cybook, the Amazon Kindle, and the Sony PRS505.
For a number of reasons, I went with the sony - chief among them being price and availability. Least expensive, and I could go to either a local Best Buy or Borders to pick one up, play with it, buy it, and start using it the same day.
It's just amazing. Small, slim, lightweight, and easy to read.
Works with my Mac.
Tons of ebooks available online - no late night trips to the bookstore to make sure I have reading material for the next days' commute.
No more need for additional storage space in my basement.
Life changing? Maybe a little melodramatic.
But it has made the time I spend getting to and from work a lot more enjoyable. And most importantly, more efficient.
Major props to Lisa for this awesome Christmas gift.
If you've already downloaded a copy of the slides from my first talk (Testing Code and Assuring Quality) then this update is for you.
By popular demand, I've added the lolcats back into the presentation in the appropriate places.
But more importantly, I'm no longer at the company for which I created this testing infrastructure. As such, I've updated the company name and technology name(s) to anonymize them a bit.
Just in case.
The biggest thing this means is that I need to re-record the screencasts before I can release those as well, being sure to remove any non-anonymous and non-proprietary information that may or may not already be in the recordings.
Which will take some time. :(
The good news is that the other talk I've prepared (and presented) on "Simple Photo Processing and Web Display" has never had any such information in it, so once I've got it in its final polished state, the publishing of the slides will be that much quicker.
My mom sent us a nice christmas gift, including a dog toy for Spike, and two catnip scented toys for Shadow and Butterscotch. Turns out that shipping catnip toys in a box with another plush toy will pretty much make it smell like catnip, too.
We were wondering why the cats were so interested in the dog toy, but then we noticed that Spike was a little more interested in the toy than normal. Turns out Spike enjoys the scent of catnip too.
So, I finally decided to stop putting it off and upload the slides from my testing talk onto slideshare.net. Click here to view these slides, as well as any future slides I make public.
Unfortunately, this presentation/slide set was heavy with screencasts, which don't survive the transition to PDFs very well. I'm considering hosting the screencasts elsewhere.
After Lisa and I got back from Thanksgiving dinner, we decided to take a few pictures of how well Spike was balancing in order to earn some tasty morsels of smoked turkey.
So I'm working on a new presentation for my local Perl Mongers group, and (indirectly) thanks to Ricardo Signes, I've got a cool way to get properly syntax colored code into my slides.
Ricardo has been working on an easy way to get syntax colored code into Keynote presentations. I wondered why he was bothering to convert the syntax colored code to RTF - then I realized why - I think because TextEdit.app on Mac OSX is a cocoa application, the font coloring is preserved through copying and pasting the code into Keynote, another cocoa application.
A little later on, I was creating some other presentation, and was copying some code out of my blog and happened to notice that the code I copied and pasted from Safari, my web browser, also retained its coloring information.
Problem solved, right? Anything I want to put into a Keynote slide, I should blog about first. Right?
Wrong.
That's too much blogging.
Instead, I wrote a teeny tiny little CGI to post up the syntax colored source of anything sitting around on my server, using the same Text::VimColor module on the backend.
... and then a little HTML to display it in the right font, font size, and using my standard code stylesheet - which is left as an exercise for the reader.
I'm really not understanding something. I've run into a module for which I had a lot of difficulty writing the first few tests. This usually happens when the module under scrutiny does something a little weird, so I'm used to it by now.
But this one is a lot weird.
The code for the module I'm looking at is structured exactly like this:
package foo;use strict;
use warnings;
sub firstSub {
my$string_orig = shift;
# in the production code, this# somehow works and doesn't diemy$string = secondSub $string_orig;
return ( foo => $string, bar => $string_orig );
}
sub secondSub {
my$string = shift;
my$ret = join'', reversesplit //, $string;
return$ret;
}
1;
What's strange is that when I use the module and try to call "firstSub", I get a Can't locate method object secondSub via package VALUE_PASSED at line blah, of course substituting VALUE_PASSED for whatever value I actually pass :) But the module - as is - works on the development server, and has worked on the production server for years with this exact structure and syntax.
So for this example, this code (reduced to the smallest example that still exhibits the behavior, but essentially the same structure) tries to call the modules' subroutine via:
use foo;
my%q = foo::firstSub( 'MTFNPY' );
print"$_: $q{$_}"forkeys%q;
And the output I get is:
Can't locate object method "secondSub" via package "MTFNPY" (perhaps you forgot to load "MTFNPY"?) at foo.pm line 13.
A little boggling. I tried a few things, including this ugliness:
{
no warnings'once';
*MTFNPY::secondSub = \&foo::secondSub;
}
... but of course that will only work as long as I'm passing the value of "MTFNPY".
Running the code through B::Deparse confirms that line is interpreted as my $string = $string_orig->secondSub.
I see I've got a couple of options:
Fix the code minimally - re-order the subroutines inside the module so the second subroutine is defined first, so it will be correctly interpreted as a function call.
Fix the code a little less minimally - add parens around the argument to secondSub.
Fix* my tests and don't touch the original code until my tests are complete so I am 100% certain I don't break anything else. (I'm fairly sure either of these changes won't, but "fairly" isn't 100%).
* By which I mean 'just make it work'
So, I add this near the top of my test file:
BEGIN {
package foo;use subs'secondSub';
}
use_ok( 'foo' );
... which basically tells the interpreter that package foo will be defining a subroutine called secondSub, which is to say predeclaring them - before the foo module has a chance to load, by taking place inside a BEGIN block.
And lo, testing successful.
But what I still don't understand is how exactly the code in the original module works at all! I'm testing on the same box where the code lives - where the code runs day in and day out without bringing the test server down to a screeching halt. I know - I added trace debugging statements all around, thinking that perhaps the code has always been silently failing and the failure was just dealt with. But no, the code was making it through that step and doing exactly what my predecessor(s) expected it to do. It's just doing it wrong.