in reply to Questions about context

You are correct about what the @{ [ ] } syntax does in your first question. The reason it's written like that is twofold: first, you're trying to call a function within a string interpolation, which simple interpolation of scalar variables and the like doesn't allow. However, you can interpolate an array constructed on the fly just like you have. Second, the code (localtime)[5] means: evaluate the function localtime in list context, and then take the sixth element of the list that it returns. This also explains what is going on in your second example. This is known as a list slice and is explained in more detail in the "Slices" section of perldata.

Update: Thought I'd add some examples. As you've mentioned,

my $x = (localtime)[0];
works by taking a list slice, thus forcing localtime to be called in list context. The behavior of a list slice in scalar context, however, is to return the last element of the list, so
my $x = (localtime)[2,3,4,0];
would have the same result as the above. Another way to do it is
my ($x) = localtime;
This is different. There's no slice here. Instead, the parentheses around the left-hand side of the assignment force the right side to be evaluated in list context, and then the first element returned is assigned to the first scalar lvalue on the left side. BUT, parentheses do not always mean list context. In particular,
my $x = (localtime)
will not do the same thing. Instead it will call localtime in scalar context and assign the result to $x.

Replies are listed 'Best First'.
Re^2: Questions about context
by Anonymous Monk on Jan 30, 2005 at 01:48 UTC
    Ah, I see, so it's kind of a trick: you create an anony array reference and then you dereference it, so it's like it never existed! The only point was to interpolate what was inside.

    Would it work if I used an anony hash reference, instead of an array reference? For example:

    %{ { (localtime)[5] } }

      Hashes don't interpolate in double-quoted strings. That's the first reason it doesn't work. The second reason is that hashes need an even number of elements, and you're generating an odd number of elements.

      To illustrate both of those points, try the following:

      my %hash = ( one => 1, two => 2 ); print "%hash\n"; # See, it doesn't interpolate. %hash = ( localtime )[5]; # Now you get a warning about uneven number +of elements.

      Far more than you ever wanted to know about string interpolation is described in perlop.


      Dave

        Far more than you ever wanted to know about string interpolation is described in perlop.

        And yet more in MJD's Identity.

      No, that does not work.
      But you can write  print "@{[ %x ]}" if you want.
      Boris
      No, hashes don't interpolate into double-quoted strings in perl5. But you can use a scalar de-ref/ref:
      print "year is ${\((localtime)[5]+1900)}!\n";
        ... you can use a scalar de-ref/ref:
        print "year is ${\((localtime)[5]+1900)}!\n";

        True, but I've finally managed to get this mechanism excised from the FAQ because it is messy-looking and confusing.

        Many people looking at the that code (including the authors of early versions of the FAQ) would expect the expression to be evaluated in a scalar context. It is not. The expression in \(EXPR) is evaluated in a list context. Not, of course, that this makes any difference for the + operator.