Last year I wrote an article titled 4 Unrelated Perl Tidbits, where I talked about some random Perl facts I learned about from reading Programming Perl. In this article I will talk about 4 more random and interesting Perl features I have learned about since.
Built-Ins Can Be Overridden with Lexical Subroutines
Perl version 5.18 introduced lexical subroutines, which are often sometimes referred to as "my subs". An interesting characteristic of lexical subs is that unlike regular subroutines, they can override built-ins.
use v5.18;
my sub print {
die "printing is banned\n";
}
print "Hello, World!\n";
__END__
$ perl tmp.pl
printing is banned
If anybody has seen a use of this feature then please comment below.
Recursive Anonymous Subroutines With __SUB__
Perl version 5.16 introduced the __SUB__ special token that holds a reference to the current subroutine. You can use __SUB__
to make a recursive call in an anonymous subroutine.
use v5.16;
higher_order_subroutine(
sub {
my $n = shift;
if ($n <= 1) { return 1 }
else { return $n * __SUB__->($n-1) }
}
)
Goto Searches For Labels In The Dynamic Scope
The following example shows that goto searches for its label argument from within the current dynamic scope. Note that this program just goes on forever printing hello from after LABEL
:
sub foo {
bar();
}
sub bar {
goto LABEL;
}
sub baz {
LABEL:
print "hello from after LABEL\n";
foo();
}
baz();
__END__
$ perl tmp.pl
hello from after LABEL
hello from after LABEL
hello from after LABEL
...
This is another feature that you should leave a comment about if you have seen a usage of it.
Regex Modifier For Only Portions Of The Regex
You can use the (?M:)
pattern in a regex to turn on the modifier specified by M
, only inside the parentheses. For example, the following two regexs are the same:
/foo/i
/(?i:foo)/
You can also turn a modifier off with (?-M:)
, which is shown in this example:
if ('FOO' =~ /(?-i:foo)/i) {
print "matches\n"
} else {
print "does not match\n"
}
__END__
$ perl tmp.pl
does not match
This feature is useful if you want to turn a modifier on/off for only a portion of the regex:
if ('fooBAR' =~ /(?-i:foo)bar/i) {
print "matches\n"
} else {
print "does not match\n"
}
__END__
$ perl tmp.pl
matches
Top comments (1)
One use case: