Terry
Terry

Reputation: 1232

Function name inside parentheses in Perl one liner

I'm working on a Perl one liner tutorial and there are one liners like this:

ls -lAF | perl -e 'while (<>) {next if /^[dt]/; print +(split)[8] . " size: " . +(split)[4] . "\n"}'

You see the function name split has been inside parentheses. Documentation about this use of functions is hard to find on Google so I couldn't find any information on it. Could somebody explain it? Thank you.

Upvotes: 1

Views: 122

Answers (3)

Chris Turner
Chris Turner

Reputation: 8142

It probably doesn't help that the use of split is defaulting everything - it's splitting $_ by spaces and returning a list of values.

The (...)[8] is called a list slice, and it filters out all but the 9th value returned by split. The preceding plus is there to prevent Perl from misparsing the brackets as being part of a function call. Which also means you don't need it on the second instance.

So print +(split)[8]; is basically a very succinct way of writing

my @results=split(/ /,$_);
print $results[8]; 

The example you've included is performing the split twice so it might be more efficient to do the more verbose version as you can get $results[4] from the above without any extra effort.

Or because you can put a list of indexes inside the [], you could do the split once and use printf to format the output like this

printf "%s size: %s\n", (split)[8,4];

Upvotes: 5

Borodin
Borodin

Reputation: 126722

Most installations of Perl include a full set of documentation, accessible using the perldoc command.

You need to read the Slices section of perldoc perldata which makes very clear this use of slicing.

Upvotes: 1

Borodin
Borodin

Reputation: 126722

In my opinion you should be avoiding this author's advice, both for the reasons laid out in my comments on your question, and because they don't appear to know their topic at all well.

The original "one-liner" was this

ls -lAF | perl -e 'while (<>) {next if /^[dt]/; print +(split)[8] . " size: " . +(split)[4] . "\n"}'

This could be written much more succinctly by using the -n and -a options, giving this

ls -lAF | perl -wane 'print $F[8] size: $F[4]\n" unless /^[dt]/'

Even without the "luxury" of these options you could write

ls -lAF | perl -e '/^[dt]/ or printf "%s size: %s\n", (split)[8,4]  while <>'

I recommend that you go and read the Camel Book several times over the next few years. That is the best way to learn the language that I have found.

Upvotes: 2

Related Questions