views:

137

answers:

3

I don't think the following should work, but it does:

$ perl -e '@a = qw/1222 2 3/; while (<@a>) { print $_ ."\n";}'
1222
2
3
$

As far as I know, Perl's <> operator shoud work on filehandle, globs and so on, with the exception of the literal <> (instead of <FILEHANDLE>), which magically iterates over @ARGV.

Does anyone know if it's supposed to work also as it did in my test?

A: 

<FH> is not the name of a filehandle, but an angle operator that does a line-input operation on the handle. This confusion usually manifests itself when people try to print to the angle operator" - Programming Perl

So in your case the array is a handle, which makes sense, and thus the operator iterates over it. So in answer to your question, yes, I think this is standard (but obscure) Perl. It is obscure because the language has more obvious ways to iterate over an array.

P.S. However, thanks for this, this will be great for code golf competitions.

Robert Massaioli
Don't post links to unauthorized copies of books.
Sinan Ünür
Whoops, I didn't even realise. Sorry for that one.
Robert Massaioli
foreach(@a) is just as short and easy as while(<@a>), so it doesn't help much in code golf.
Jeff B
...and `for(@a)` is exactly equivalent to `foreach(@a)`, but 4 characters shorter, which does help when golfing.
Dave Sherohman
+9  A: 

Magic at work!

From 'perldoc perlop':

If what's within the angle brackets is neither a filehandle nor a simple scalar variable containing a filehandle name, typeglob, or typeglob reference, it is interpreted as a filename pattern to be globbed, and either a list of filenames or the next filename in the list is returned, depending on context.

This is the rule you're triggering with this code. Here's what's happening:

  1. <@a> is (syntactically, at compile-time) determined to be a glob expansion
  2. thus <> turns @a into the string "1222 2 3" (string interpolation of an array)
  3. glob("1222 2 3") in list context returns ('1222', '2', '3')
dlowe
OK, so I just got up, but I simply don't get #3.
innaM
The behavior is: unless there are pattern matching metacharacters in its argument, glob doesn't bother going to the filesystem.This can be surprising. It helps me to think of it in terms of the shell glob functionality, which perl's glob aims to emulate: if you say 'cat foo', the shell invokes 'cat' with an argument of 'foo', regardless of whether 'foo' exists. If you say 'cat foo.*', the shell will call 'cat' with variable arguments, depending on what (if anything) matches the pattern.
dlowe
Thank you! Now I get it.
innaM
+1  A: 

This is invoking glob.

Sinan Ünür