The documentation for the open function shows the syntax of open() as:
- open FILEHANDLE,EXPR
- open FILEHANDLE,MODE,EXPR
- open FILEHANDLE,MODE,EXPR,LIST
- open FILEHANDLE,MODE,REFERENCE
- open FILEHANDLE
Down in the examples they have places where a normal $-prefixed variable is used for the file handle:
open(my $fh, "<", "input.txt")
and also examples where a bareword is used:
open(FOO, "|tr '[a-z]' '[A-Z]'");
One question is what is the name of each style as in "I am using __ for a filehandle" in each case? The other is, why did they start using bare words for open() in the documentation? It appears to be the later uses all don't involve normal filename open()s. Is the $-prefixed form not acceptable in those instances?
The bareword form is, essentially, just historical legacy for backward compatibility. Using a lexical variable is pretty much always The Right Thing To Do in new code.
→ incidentally,
$xis a lexical scalar variable, whereFOOis, as you said, called a barewordDetails/Digression
Just for completeness, as @Joe_Z pointed out in the comments, the lexical filehandle objects are “relatively new,” as a part of the rather major rewrite between Perl 5.005 and 5.6 (they even gained whole orders of magnitude in that version number…).
However, technically, the bareword
FOO(or, e.g.STDIN) is interpreted in a separate namespace just for filehandles. Since there isn't a sigil (like$ @ % &) for the filehandle namespace, there are only two ways to reference a filehandle in that namespace:print, who will (behind the scenes) infer that a bareword must refer to a filehandle, for historical reasons;*FOO, which refers to “anything in any namespace which happens to be bound to the symbolFOO.Note that in some languages, like C or Scheme, a single symbol has no type sigils, and so all symbols can be bound only in one way (e.g. one cannot have a variable named
printfand a function namedprintfin C … generally), whereas in Perl or (e.g.) Common Lisp, the same symbolfoocan be bound to many different things; the distinction is that Perl actually requires you to use sigils to disambiguate “whichfooyou mean” in most contexts.$foo,@foo=@foo[ $x .. $y],$foo[ $n ],%foo=@foo{ $k1, $k2 }=$foo{ $k },&fooand the like.By using barewords as filehandles, though, you lose some abilities:
Significantly, in order to bind them locally or lexically (instead of globally), you need to bind every symbol in every namespace, because there is no sigil available. Thus,
my $fooandmy @foocan live in two different scratchpads (scopes), where perhaps one outlives the other; butmy *foowould include both of these, as well as the filehandlefoo(and potentially other obscure corner-cases, likeformatspecifiers, although I wouldn't swear to it).It's also immensely difficult to pass a bareword-style filehandle into a function, and the like.
Basically, barewords inherit all of the downsides of global scope and have none of the advantages of lexical variables.
perldoc perldatahas a nice section on Typeglobs and Filehandles which probably explains these things a bit more clearly, as well. I don't have my copy handy, but I believe the Camel goes into more detail on the subject, as well.