Andy Lester: February 2008 Archives

How not to do a Changes file

| | Comments (5)

Here's how to not do a Changes file:

That tells me nothing about whether I want to upgrade my SpamAssassin install. :-(

Oh, look, I wrote about this before, and how great Tim Bunce's Changes files are.

Marcel GrĂ¼nauer posted to his Twitter account that he freed up 3 GB by removing non-English localization resource files (*.lproj) with the following command:

find / \
    \! -name 'English.lproj' \
    \! -name 'en.lproj' \
    -name '*.lproj' -type d \
    -exec rm -rf -- {} \; -prune

If you want to make sure you're deleting the right files before you delete them, see the list of the .ljprojf files first:

find / \
    \! -name 'English.lproj' \
    \! -name 'en.lproj' \
    -name '*.lproj' -type d -print -prune

From David Fetter's page at

  1. The first rule of Optimization Club is, you do not Optimize.
  2. The second rule of Optimization Club is, you do not Optimize without measuring.
  3. If your app is running faster than the underlying transport protocol, the optimization is over.
  4. One factor at a time.
  5. No marketroids, no marketroid schedules.
  6. Testing will go on as long as it has to.
  7. If this is your first night at Optimization Club, you have to write a test case.

Of course it's company policy never to imply ownership of a performance problem. Always use the indefinite article: "a performance problem", never "your performance problem."

Leopard cheat sheet

| | Comments (0)

Here's a handy little cheat sheet for Mac OS X Leopard from O'Reilly. I didn't realize there were so many Finder shortcuts! Command-T puts something in the sidebar! Command-Shift-G lets you type in a folder name! Cool!

Perl lets you call object methods in two different ways:

  • $obj->method()
  • method $obj
The latter form is usually called only for things like clone $obj, which is pretty ugly. For more about indirect object syntax and some of the pain it causes, see When Is Backwards-Compatibility Not Worth It?.

It's funny that Max posted that blog entry the other day, because I just was shown a problem that was caused indirectly by it. Mike O'Regan showed me some code that he was surprised even compiled, because it certainly wasn't working.

sub custom_sort {
        $a->{foo} cmp $b->{foo}
        a$->{bar} cmp b$->{bar}

See the a$ instead of $a? Yuck. But it compiles just fine. Why? Well, let's see what B::Deparse decompiles it out as:

$ perl -MO=Deparse
sub custom_sort {
    return $$a{'foo'} cmp $$b{'foo'} || $-->a > {'bar'} cmp $-->b > {'bar'};
} syntax OK

Turns out that it's calling method a on the object $- and then seeing if that is greater than {'bar'}. Double-ugh.

Perl 6 still has indirect object syntax, but you must follow it with a colon, as in method $obj: @args. Larry says in Perl 6 it's completely unambiguous.

On the perl-qa list tonight, we were discussing how best to find all the modules used in a source tree. To do the job right, you'd have to run the code and then look at the %INC:: hash, which shows the paths of all modules loaded. The low-tech and usually-good-enough solutions we came up with use ack:

$ ack -h '^use\s+(\w+(?:::\w+)*).*' --output=\$1 | sort -u

Thanks to Andy Armstrong for coming up with a better regex than mine, which assumed that the use statement would necessarily end with a semicolon.

About this Archive

This page is a archive of recent entries written by Andy Lester in February 2008.

Andy Lester: January 2008 is the previous archive.

Andy Lester: March 2008 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Other Perl Sites

Other Swell Blogs

  • geek2geek: An ongoing analysis of how geeks communicate, how we fail and how to fix it.