Scoping out an even conciser fork idiom

Years ago I wrote about a concise fork idiom. It turns out that it’s possible to do better than everything I discussed in that entry as well as the proposals in the comments.

I didn’t at the time appreciate a clever aspect of variable scoping in Perl:

use strict;
sub get_answer { 0 }
if ( my $answer = get_answer ) {
    ...;
} else {
    print $answer;
}

This compiles and works as intended. In other words, a variable declared within an if or elsif conditional is in scope not just in that branch, but in all following branches (and elsif conditionals) as well. Which means it is possible to write the following:

if ( my $kid = fork ) {
    print "parent of $kid\n";
} elsif ( defined $kid ) {
    print "child of ", getppid, "\n";
} else {
    die "Couldn't fork: $!\n";
}

It doesn’t get more low-key than this.

I am sure there are many similar applications of the same idea in other scenarios that I missed over the years, for which instead I awkwardly declared a variable in a separate statement up front because I thought that that was necessary in order to refer to it from several branches of an if/else chain. Not so.

Once more unto the Wide character (U+XXXX) in substitution (s///)

I wrote very elliptically about this warning and received some helpful comments with the standard advice about how to proceed when encountering it. Except unfortunately that advice will be of no use when you encounter this warning.

Namely I should have been less cute about it and made it clear that I was specifically talking about a warning about a wide character “in substitution”. How can a s/// even possibly trigger a wide character warning, you ask? Beats me, to be entirely honest, even now, but: if you have a use locale somewhere, it turns out that it can. Because defeating that is what fixed the warning I was getting:

Class data for cheapskates

sub some_field : lvalue { state $value = 'some_default' }

(We know, of course, that “class data” is OOPese for “global variable”.)

Wide character (U+XXXX) in substitution (s///)

There is a “use locale” somewhere in the code you are running.

Update: This is specifically in reference to warning about wide characters “in substitution”. See also the follow-up entry.

Never matching: everybody is doing it wrong

Well, not actually wrong, just slow. But the exaggeration makes a punchier headline, you’ll admit.

This comes up when an interface takes a pattern to match things against. Sometimes you have some reason to want this match to always fail, so you want to pass a pattern which will never match. The customary way of doing this is to pass qr/(?!)/. There is a problem with that, though.

I’m not talking here about the fact that if possible, you really don’t want to pass an actual qr object. We’ve already covered that. It was a surprising enough discovery that I’ll take this opportunity to signal-boost that while we’re here, but this article is not about that.