Fixing bugs instead of explaining them

David Golden, one of the reviewers for Intermediate Perl, gave me extensive comments about one of the test program examples in the book. I made a simple example using Test::Output, a module I sometimes use but didn’t write. It solved my needs at the time, but it has some issues. Perl’s output is complicated, and the simple tie in Test::Output::Tie doesn’t cover all the cases.

I’m the current maintainer of the module, and rather than explain the edge cases in my example (or fix the module), I merely mentioned to David that we should reimplement Test::Output with Capture:Tiny, his module that handles almost all cases. I meant “we” in the universal sense, and I didn’t say much because I was busy writing the book. A couple of hours later, David sends me a pull request.

That often happens as part of the writing process. If something is too hard to explain, it’s probably too hard to use. The time explaining it is better spent making it clear, unbuggy, or whatever it takes to avoid the explanation. In this case, it’s even better when someone else did it.

The Alpaca is on its way

O’Reilly now has Intermediate Perl, Second Edition. Just this morning, in time for the open of business on the East Coast, I finished fixing the final reviewer comments. I went through over 300 pages of extensive comments:

320 pages of this, from three different reviewers

This doesn’t mean that the book is done. The publisher does their bit with indexers, proofreaders, and the authors checking the book again. There’s usually a few things to fix after that, and, once, fixed, the books go to the printers. The printers send it to the distributors, who send it to the sellers. After all of this, we should have the actual bound paper version around July, but probably not in time for you to walk away from OSCON holding one.

The book isn’t available for pre-order yet, but O’Reilly should add it to their Rough Cuts early editions program so you can see it sooner than the printers. It’s available for pre-order from the O’Reilly site, but I haven’t seen it available anywhere else yet. We’re working on that.

Multiple package VERSION declarations

I’m re-reading the parts of Intermediate Perl where we introduce packages. Perl v5.12 introduced an expanded package syntax to include a version and a block:

package Foo { ... }
package Foo 1.23;
package Foo 1.23 { ... }

That almost seems to imply that you’d have to completely define the package inside the block if you use a block, but as you know from everything else you’ve experienced in the language, Perl is happy to let you muck with other things. You can add to the package later: » Read more…

Moose in the Alpaca

We’re putting Moose, the “postmodern object system for Perl 5”, in Intermediate Perl, but only as a short introduction. If you want more coverage, you should still look at Moose by Dave Rolsky and Stevan Little.

We started with Randal’s columns from Linux Magazine way back in 2007: “The Moose is Flying (Part 1)” and “The Moose is Flying (Part 2)”. We’ve updated it and showed a couple more topics.

If you’re a Moose user and would like to see what we’ve put together before it goes into the book, especially to ensure that we’re doing all the right things with the latest practices.

We’re also looking for a limited number of people to review larger sections of the book. You’ll get a sneak peek at the book, and we’ll do something nice for you once the book comes out.

Writing with text-to-speech feedback

As I’m working on the next edition of Intermediate Perl, I’m letting the computer read it back to me. I use Mac::Speech, part of the old Perl Carbon interface.

I use this script as a BBEdit Text Filter (although it’s not really filtering anything). I put this in my ~/Library/Application Support/BBEdit/Text Filters/speak_it. When I select text and choose this (or any) filter, BBEdit supplies the selected text to my filter on standard input. Anything I send to standard output replaces the selection, but I don’t want to replace the text. If I output nothing, the text disappears so I just print the unmodified text.

I call SpeakText and give it the current line. This fires off a separate process and my program continues, so I sleep while the interface tells me that it is speaking.

#!/usr/bin/perl

=pod

To use Mac::Speech, you need to use the 32-bit perl. The Mac comes
with both 32- and 64-bit versions and automatically selects the one. 
However, the Carbon API, which Mac::Speech uses, needs the 32-bit
version.

You can set the default perl to the 32-bit version:
 
	% defaults write com.apple.versioner.perl Prefer-32-Bit -bool yes

You can also choose it for just this session:

	% export VERSIONER_PERL_PREFER_32_BIT=yes

You don't really have to do anything because the program will set this
for you and re-exec itself if necessary.

=cut

BEGIN {
	unless( $ENV{VERSIONER_PERL_PREFER_32_BIT} eq 'yes' ) {
		$ENV{VERSIONER_PERL_PREFER_32_BIT} = 'yes';
		exec qq($^X "$0");
		}
	}

use v5.12;
use Mac::Speech;

my $voice   = $Mac::Speech::Voice{Victoria};
my $channel = NewSpeechChannel( $voice );

while( <> ) {
	SpeakText( $channel, $_ );
	print; 
	sleep 1 while SpeechBusy();
	}

DisposeSpeechChannel($channel);

Visualizing Perl data structures

Joseph Hall invented Perl Graphical Structures, which he used in Effective Perl Programming and we used in Intermediate Perl. To make the images for the first and second editions, I wrote PeGS::PDF (on Github).

I used this to create all of the PeGS structures in the book. Here are a couple of examples, which you can also find in the distribution. I can make the basic structures from Learning Perl as well as the references and structures from this book. I can’t make arbitrarily deep structures because I didn’t do the work to recursively place everything in non-overlapping spaces.

#!/usr/local/bin/perl

use PeGS::PDF;

my $W    = 1.50 * 72;
my $H    = 2.25 * 72;

my $pdf = PeGS::PDF->new(
	{
	file => "/Users/brian/Desktop/array.pdf",
	'x'  => $W,
	'y'  => $H,
	}
	);
die "Could not create object!" unless ref $pdf;

$pdf->make_array( '@cats', [ qw(Buster Mimi Ginger Ella) ], 10, 120 );

$pdf->close;

I can also make a hash.

#!/usr/local/bin/perl

use PeGS::PDF;

my $W    = 2.5 * 72;
my $H    = 2.25  * 72;

my $pdf = PeGS::PDF->new(
        {
        file => "/Users/brian/Desktop/hash.pdf",
        'x'  => $W,
        'y'  => $H,
        }
        );
die "Could not create object!" unless ref $pdf;

my %microchips = qw(
        Buster  1435
        Mimi    9874
        Ella    3004
        Ginger  5207
        );

$pdf->make_hash( '%microchips', \%microchips, 10, 120 );

$pdf->close;