Reading Raymond’s post about bulk file renaming reminded me of Larry Wall’s filename fixer. This is a great thing to have in your toolbox. Here’s a minor tweak that allows it to work in Windows CMD.exe.
I call this renamer.cmd to avoid conflict with CMD’s much-less-useful built-in rename.
@rem = '
@echo off
perl -w %~f0 %*
exit /B %ERRORLEVEL%
';
# rename - Larry's filename fixer
$op = shift or die "Usage: renamer expr [files]\n”;
chomp(@ARGV = <STDIN>) unless @ARGV;
# cmd.exe doesn’t do glob expansion
@ARGV = map glob, @ARGV;
for (@ARGV) {
$was = $_;
eval $op;
die $@ if $@;
rename($was,$_) unless $was eq $_;
}
Update:
Oops! Who woulda thunk that the first Google hit for “Larry’s filename fixer” would be a book warez site? Link changed to point at Google’s Usenet archive.
Larry Wall gave a keynote entitled Present Continuous, Future Perfect at OSDC 2006. It was back in February, but I didn’t discover the audio and slides until tonight.
The deck is 150+ slides, and covers the upcoming features in Perl 6. There’s a Wiki page for the talk here, which includes a full text transcript.
I just realized that one of the reasons I choose Perl for “quick hacks” is because the syntax is so ugly and inconsistent.
It’s a psychological thing. If I were to select Ruby, for example, I’d feel a tremendous obligation to write a beautiful well-designed program. I’d probably create a subversion repository, create unit tests, automate, etc. These are all important things, but I want to amortize their up front cost over the term of a long project.
I choose Perl because it takes the pressure off.
Wow, Perl’s Memoize.pm is cool. Try this:
use Memoize;
sub fib {
my $n = shift;
print "called fib($n)\\n";
return $n if $n < 2;
fib($n-1) + fib($n-2);
}
print fib(5) . "\\n\\n";
memoize( 'fib' );
print fib(5) . "\\n\\n";
It does two different things:
- It wraps the function with a caching version.
- It replaces all calls to the function with calls to the memoized version. This includes the recursive calls inside the function itself.
It does all of this without requiring any source-level changes to the memoized function. This makes it easy to accelerate any referrentially-transparent function. Just don’t do something dumb like memoize print() or time().
With C++ I can mimic #1, but not #2. It’s a shame, because #2 is the cool part. With my C++ implementation, I only speed up identical repeated calls:
fib(5); // slow: makes 14, mostly-redundant, recursive calls
fib(5); // fast: purely a look up
fib(4); // slow
fib(6); // slow
Perl does much better:
fib(5); # fast: makes 5 recursive calls
fib(5); # fast: purely a look up
fib(4); # fast: purely a look up
fib(6); # fast: picks up where fib(5) left off
I’m somewhat bugged that I couldn’t duplicate this behavior with C++. Perl needn’t reach into it’s “dynamic language” bag of tricks to achieve this. It just provides access to the symbol table:
sub a() { print "a\\n"; }
sub b() { print "b\\n"; }
*a = \\&b;
a(); # prints b
Latest Comments
RSS