SPUG: PERL technical interview

Yitzchak Scott-Thoennes sthoenna at efn.org
Wed Jan 25 14:03:20 PST 2006


On Tue, Jan 24, 2006 at 12:09:23PM -0800, Yitzchak Scott-Thoennes wrote:
> $ perl -wl
> use POSIX "/EXIT_*/";
> print "EXIT_SUCCESS is @{[EXIT_SUCCESS]}, EXIT_FAILURE is @{[EXIT_FAILURE]}";
> __END__
> EXIT_SUCCESS is 0, EXIT_FAILURE is 1

I had a response from someone whom this syntax gave momentary pause,
so I thought I'd try to explain it.

@{[ expr ]} is an idiomatic way of embedding an arbitrary expression
in a double-quoted string.  It executes expr in list context (which
makes no difference for these constants) and interpolates the result
into the string.  (If there are multiple items in the result, they are
separated by $" aka $LIST_SEPARATOR, which defaults to a space.)

Taking it apart, first there's the @ which introduces an array
to be interpolated into the string.  This has three basic forms:
@identifier, @{identifier}, and @{arrayref}.  The second form
uses the {} just to delimit the identifier name, as when there
is a word character immediately following:

   @foo="foo"; $foobar="@{foo}bar";

The third form is just like @ followed by a BLOCK outside of
double quoted string; the code in the BLOCK is executed and
the result is treated as an array reference to dereference.

In this case, the code in the BLOCK is just an anonymous
array constructor: [ expr ].

Putting it all together, EXIT_SUCCESS calls the function of that
name, which returns 0.  [ ] creates an anonymous arrayref [ 0 ].
@{ } dereferences that and puts the contents ( 0 ) into the string.

When would you use this idiom?  Rarely.  Just saying e.g.

   print "EXIT_SUCCESS is ", EXIT_SUCCESS, ", EXIT_FAILURE is ", EXIT_FAILURE"

is just about as clear.  Even if you need the whole thing in one scalar, not
in a list, either of these is also just about as clear:

   join "", "EXIT_SUCCESS is ", EXIT_SUCCESS, ", EXIT_FAILURE is ", EXIT_FAILURE"

or

   sprintf "EXIT_SUCCESS is %d, EXIT_FAILURE is %d", EXIT_SUCCESS, EXIT_FAILURE

(Just replacing the ,'s with .'s works too, but I don't find that visually
distinctive enough; I try to avoid use of multiple .'s.)

I occasionally use it to interpolate a "constant", especially where a
join or sprintf would otherwise be needed, but avoid it other times.
But I sometimes like to put things into posts just in the hope that at
least one person is nudged to do some Fine Manual reading.


More information about the spug-list mailing list