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.
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:
sub some_field : lvalue { state $value = 'some_default' }
(We know, of course, that “class data” is OOPese for “global variable”.)
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.
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.