March 2016 Archives

Perl curio: For loops and statement modifiers

Perl has a "statement modifier" form of most control structures:

EXPR if EXPR;
EXPR unless EXPR;
EXPR while EXPR;
EXPR until EXPR;
EXPR for EXPR;

Perl also has a C-style for loop:

for (INIT; COND; STEP) {
    ...
}

The curious part: COND is a normal expression, but STEP allows statement modifiers. That is, you can write:

for (my $i = 0; $i < 10; $i++ if rand() < 0.5) {
    print "$i\n";
}

Perl curio: Dereferencing blocks

We're all familiar with references and Use Rule 1:

You can always use an array reference, in curly braces, in place of the name of an array.

This leads to code like ${$foo} (dereference a scalar reference) or @{$bar{baz}} (dereference an array reference stored in a hash).

The curious part: The curly braces actually form a block, i.e. you can put multiple statements in there (just like do BLOCK), as long as the last one returns a reference:

% perl -E 'use strict; use warnings; ${say "hi"; \$_} = 42; say $_'
hi
42

This block also gets its own scope:

% perl -E 'use strict; use warnings; ${my $x = "hi"; say $x; \$x} = 42; say $x'
Global symbol "$x" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.

$x isn't visible outside the ${ ... } block it was declared in.

% perl -E 'use strict; use warnings; ${my $x = "hi"; say $x; \$x} = 42;'
hi

About mauke

user-pic I blog about Perl.