[Edinburgh-pm] A little perl help please

Aaron Crane perl at aaroncrane.co.uk
Sat Feb 18 03:30:56 PST 2006


asmith9983 at gmail.com writes:
> I want this little perl one-liner to run without assigning the return
> of gmtime to an array.  Is this possible?  Soomething like this but as
> this doesn't work, not this
> perl -e -w 'use strict "vars";print "Today is Friday" if (gmtime[6] == 5);'

The slightly-confusing thing here is that there are multiple things that
use square-bracket syntax.  You're looking for array subscripting, as in
this code:

  my @x = gmtime;
  print "..." if $x[6] == 5;

However, Perl only lets you do that directly if you have an actual array
variable (something that could take an '@' sigil).  In this case, you've
got

  print "..." if gmtime[6] == 5;

which Perl treats as if it were

  print "..." if gmtime([6]) == 5;

That is, you're calling gmtime() with a single argument: a reference to
an anonymous array containing the value 6.

Since array subscripting isn't available when you don't have an actual
array variable, the alternative is to use a list slice.  List slices
look very much like array subscripts, but since there's no sigil, they
need an extra set of parentheses round the list being sliced:

  print "..." if (gmtime)[6] == 5;

A handy tip for helping to debug things like this: the B::Deparse module
can deparse the internal compiled form of your code back to source.  For
various reasons, you don't invoke B::Deparse directly, but through the
O.pm module instead.  Using it normally looks like this:

  perl -MO=Deparse -e '...'

or

  perl -MO=Deparse file.pl

B::Deparse also has a -p option, which adds excess parentheses to reveal
the precedence in your code.  Running your original code and the fixed
version using Deparse -p looks like this:

  $ perl -MO=Deparse,-p -e 'print "Today is Friday" if gmtime[6] == 5'
  ((gmtime([6]) == 6) and print('Today is Friday'));
  -e syntax OK
  $ perl -MO=Deparse,-p -e 'print "Today is Friday" if (gmtime)[6] == 5'
  (((gmtime)[6] == 6) and print('Today is Friday'));
  -e syntax OK

The first of those makes it clear that gmtime is being called with an
argument.

-- 
Aaron Crane


More information about the Edinburgh-pm mailing list