While trying to do this:
my $obj = new JavaScript::Minifier;
$obj->minify(*STDIN, *STDOUT);
// modified above line to
$obj->minify(*IP_HANDLE,*OP_HANDLE)
The above works if IP_HANDLE and OP_HANDLE are filehandles but still I am not able to figure out what actually the * does when applied to a filehandle or any other datatype.
Thanks,
In the bad old days before perl v5.6, which introduced lexical filehandles — more than a decade ago now — passing file- and directory handles was awkward. The code from your question is written using this old-fashioned style.
The technical name for
*STDIN, for example, is a typeglob, explained in the “Typeglobs and Filehandles” section of perldata. You may encounter manipulation of typeglobs for various purposes in legacy code. Note that you may grab typeglobs of global variables only, never lexicals.Passing handles was a common purpose for dealing directly with typeglobs, but there were other uses as well. See below for details.
*foo{THING}syntaxPassing filehandles to subs
The perldata documentation explains:
The referenced section of perlsub is below.
Note that a typeglob can be taken on global variables only, not lexicals. Heed the warning above. Prefer to avoid this obscure technique.
Syntactic ambiguity: string or filehandle?
Without the
*sigil, a bareword is just a string.Simple strings sometimes suffice, hower. For example, the
printoperator allowsThese fail with
strict 'refs'enabled. The manual explains:In your example, consider the syntactic ambiguity. Without the
*sigil, you could mean stringsor maybe a sub call
or, of course, a filehandle. Note in the examples above how the bareword
JavaScript::Minifieralso compiles as a simple string.Enable the
strictpragma and it all goes out the window anyway:Aliases via typeglob assignment
One trick with typeglobs that’s handy for Stack Overflow posts is
(I could be more precise with
*ARGV = *DATA{IO}, but that’s a little fussy.)This allows the diamond operator
<>to read from theDATAfilehandle, as inThis way, the program and its input can be in a single file, and the code is a closer match to how it will look in production: just delete the typeglob assignment.
Localizing handles by localizing typeglobs
As noted in perlsub
you can use typeglobs to localize filehandles:
“When to Still Use
local()” in perlsub has another example.To emphasize, this style is old-fashioned. Prefer to avoid global filehandles in new code, but being able to understand the technique in existing code is useful.
Peeking under the hood:
*foo{THING}syntaxYou can get at the different parts of a typeglob, as perlref explains:
Tying it all together: DWIM!
Context is key with Perl. In your example, although the syntax may be ambiguous, the intent is not: even if the parameters are strings, those strings are clearly intended to name filehandles.
So consider all the cases
minifymay need to handle:For example:
As a library author, being accomodative can be useful. To illustrate, the following stub of JavaScript::Minifier understands both old-fashioned and modern ways of passing filehandles.
Output: