For me, the subroutine is the unit of abstraction. Give me subroutines (or methods or functions) and I can change the world.
Fixing Hashes
If you try and retrieve a non-existent key from a perl hash, it returns an undefined value. Often, that isn’t what I want.
No worries. With a simple subroutine, I can fix it.
sub get_hash_value (\%$)
{
my ($hash_ref, $key) = @_;
if (! exists $hash_ref->{$key}) {
die "KeyNotExists: $key\n";
}
return $hash_ref->{$key};
}
my %hash;
print $hash{'hardtospellkey'};
print get_hash_value(%hash, 'hardtospeelkey');
With warnings turned on, this is easily caught. Plus with emacs dabbrev, it is never a problem for me anyway – my mispellings are consistent.
But with a less enlightened language than perl, if you have this problem then as long as you also have subroutines, you can fix it.
Use of uninitialized value $hash{"hardtospellkey"} in print at t.pl line 14.
KeyNotExists: hardtospeelkey
Fixing Weakly Typed Numbers
use Scalar::Util 'looks_like_number'; sub ensure_number { my $val = shift; if (! looks_like_number($val)) { die "NotNumber: $val\n"; } return $val; } my $x = '1'; my $y = 'rhubarb'; print ensure_number($x) + ensure_number(2), "\n"; print ensure_number($x) + ensure_number($y), "\n";
In production code I’m likely to call that subroutine something more like _n.
3 NotNumber: rhubarb
Subroutine Call Speed
This is why I care about perl subroutine call speed – I have so many little routines stating exactly what I expect from my code. And it seems like it is quick enough.
It would be nice though to have something like emacs’ defsubst. Say a new keyword like inline_sub { ... }. So I can invent the syntax I want, secure in the knowledge that, code bloating aside, I’m not paying for it.