I have the following hypothetical class which uses blessed anonymous subs as objects. For now I realize that it does nothing I couldn't do with
grep, but please bear with me as this is only a slimmed-down example for the sake of this node.
package BlessedSub;
use base 'Exporter';
@EXPORT = qw/blessed_sub/;
## prototyped for convenience
sub blessed_sub(&) {
my $anonymous_sub = shift;
bless $anonymous_sub, __PACKAGE__;
}
sub filter {
my ($self, @items) = @_;
## check if all the items return succesfully
for (@items) {
return 0 unless $self->($_);
}
return 1;
}
The
blessed_sub sub is prototyped so I can remove the
sub keyword on the arguments, like this:
my $obj = blessed_sub { $_[0] =~ /foo/ };
die unless $obj->filter(qw/foobar foobaz bazfoo barbaz barfoo/);
But I soon after writing many lines like these, I decided that if I were already using prototypes to make
blessed_sub behave more like a builtin, why not make it even
more like a builtin? Our neighborhood friendly builtins like
map and
grep use the
$_ variable to grab their argument, not
@_ and
$_[0]. I noticed that my anonymous subs were being called from within a
for loop, so I changed the calling code to this:
my $obj = blessed_sub { /foo/ }; ## now uses $_, not @_
die unless $obj->filter(qw/foobar foobaz bazfoo barbaz barfoo/);
..and it worked in exactly the same way. Now
blessed_sub really looks and feels just like a builtin.
I enjoy being able to shorten builtins that default to
$_ when possible, and I think the readability increases anyway from replacing
$_[0] with
$_. But am I missing some dangerous consequences of using
$_ here? I think it's pretty safe from within a
for loop, but I want to make sure no bad things can happen.
Thanks for your comments,
blokhead