DEV Community

Nicholas Hubbard
Nicholas Hubbard

Posted on • Edited on

4 More Unrelated Perl Tidbits

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
Enter fullscreen mode Exit fullscreen mode

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) }
    }
)
Enter fullscreen mode Exit fullscreen mode

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
...
Enter fullscreen mode Exit fullscreen mode

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)/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
matthewpersico profile image
Matthew O. Persico

One use case:

$ cat tmp.pl
use 5.18.0;
my sub print {
    CORE::print(scalar(localtime()), ":", @_)
}

print "Hello, World!\n";

$ perl tmp.pl
Tue Apr 11 12:37:09 2023:Hello, World!
Enter fullscreen mode Exit fullscreen mode