Stupid Tricks Archives

What they say in Java is just as true in Perl

use Benchmark::Dumb 'cmpthese';

( $bar, $quux ) = qw( bar quux );

cmpthese( 0.0002, {
  conc => q{
    my $str = "xxx ";
    (((( $str .= "foo" ).= $::bar ).= "baz" ).= $::quux ).= "qux";
  },
  intp => q{
    my $str = "xxx ";
    $str .= "foo${::bar}baz${::quux}qux";
  },
} );

I don’t recall ever seeing anyone mention this.

(It is, of course, obvious, and it is, of course, irrelevant in most contexts, especially as it is, of course, not a huge difference. Perl structurally tends to make it less likely to make this mistake in an accidentally quadratic way compared to how Java tends to be written, anyway. And anyhow, instead of micro-optimising Perl code this way, we all rewrite it – of course – in C… right?)

Narrowly destricted refs

*{; no strict 'refs'; \*{ "${pkg}::type" } } = sub () { $type };
push @{; no strict 'refs'; \@{ "${pkg}::ISA" } }, __PACKAGE__;
# ... and so on

I really don’t feel like I have anything to add but I suppose it may not be obvious that the point of this exercise is to surgically limit the lifting of the refs stricture to just the desired symbolic dereference (without leaking it even as far as any other part of the expression) – in the most compact form possible.

I also suppose I ought to expand on it by way of explanation for the less travelled in the dustier corners of Perl 5 syntax:

A very stupid, over-clever scoping-based importing trick

In some code I’m working on, I use a module which exposes a whole bunch of package variables as part of its public interface. It does not export them, however. I could refer to them directly by prefixing them all with Some::Module::, but that would be ugly and verbose. It’s also unsafe – the vars stricture will not help you catch typos if you use fully qualified names.

The obvious solution would be to emulate what exporting does:

Running plenv 𝘢𝘯𝘥 perlbrew

So I just went to investigate switching from perlbrew to plenv.

This has failed before, because I run an old and grungy installation of Perl where I didn’t set up a local lib and just installed whatever without keeping records of which installed modules I need and which are just junk I tried for a few minutes. Unless I carry forward all that junk, I can’t switch perls without breaking all my local scripts – and I have better things to do.

Eventually I want to fix this situation, but no today on which it comes up has been the day for it so far.

Still, I do want to upgrade to 5.22 now that it’s out, and I’ve been wanting to switch to plenv for a while. What to do?

Uhm… *looks around*
ln -s ~/perl5/perlbrew/perls/perl-5.16.1 .plenv/versions/5.16.1
La la la… *walks away*

Yup, plenv global 5.16.1 is fine with that and a plenv rehash later, it works.

I threw out the rest of perlbrew, just kept the directory tree for the linked perl installation, and now I happily run this bastard/cuckoo setup. Teehee.

Now for installing 5.22 and making all my stuff work with it…

Today’s bit of black perl

use 5.010;
{
    package F;
    sub new { bless {}, shift }
    sub me { $_[0] = 'surprise!' }
}
my $f = F->new;
say $f;
$f->me;
say $f;

Output:

F=HASH(0x7f9daa025c80)
surprise!

Teehee…

Tonight’s folly

I just realised that since the addition of /r, you can now write s!!!regex. Or s!!!regexp if you prefer.

Today's curiosity

use strict;
push my @weight, 'around';

Today's lyrical excursion Perl perversion

perl -e 'my (my (my (my (my (my $puerto_rico)))))'

About Aristotle

user-pic Waxing philosophical