perlfan99 has asked for the wisdom of the Perl Monks concerning the following question:
what does \*FH means? a pointer to a file handle( a pointer to an integer)?open(FH, "> $log"); function(\*FH);
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: what is filehandle's data type
by GrandFather (Saint) on Aug 20, 2008 at 04:04 UTC | |
It's a GLOB:
Prints:
\*FH passes a reference to a GLOB to function. Perl reduces RSI - it saves typing | [reply] [d/l] [select] |
|
Re: what is filehandle's data type
by jwkrahn (Abbot) on Aug 20, 2008 at 04:11 UTC | |
In Perl a file handle is a filehandle type, see Typeglobs and Filehandles \*FH is a reference to a typeglob, see perlref | [reply] [d/l] |
|
Re: what is filehandle's data type
by Anonymous Monk on Aug 20, 2008 at 04:09 UTC | |
Wouldn't you know it, docs :) Typeglobs and Filehandles | [reply] |
|
Re: what is filehandle's data type
by gone2015 (Deacon) on Aug 20, 2008 at 20:16 UTC | |
It's a good question. You can get to the underlying integer using fileno(), but that doesn't answer the question of what a file handle is in Perl -- which turns out to be trickier than it looks... We all know that an identifier in Perl can refer to a SCALAR, an ARRAY, a HASH or a subroutine (CODE) -- and the prefixes $, @, % and & specify which. An identifier can also refer to a file handle (IO) or a FORMAT. An identifier without a prefix generally refers to a subroutine, but in some special contexts it refers to a file handle or a FORMAT. The unfortunate consequence is that you cannot pass a file handle identifier to a subroutine or store it, because in those contexts an identifier with no prefix is treated as a subroutine.
Now, the collection of all possible values that a name can refer to is known as a GLOB, and the prefix * is used to specify that. You can pass a GLOB and you can store one -- so my $a = *SUE ; makes $a an implicit reference to the GLOB named SUE. You can also pass a reference to a GLOB and store one -- thus my $b = \*SUE ; stores an explicit reference to the GLOB named SUE in $b. The construct *SUE{SCALAR} returns a reference to the SCALAR part of the GLOB named SUE. (The significance of all this may become clear later.) So that:
prints:
so... although $a and $b are not the same as far as ref is concerned, they can both be used as references to the GLOB (just in case we'd forgotten this is Perl). So a file handle is the IO part of a GLOB. However, where Perl expects a file handle, it will accept a number of things:
prints:
This shows:
This also shows:
So... what was the question, again ? A thing which acts as a FILEHANDLE can have a number of apparently different data types. I would recommend using $FH "indirect" file handles or IO:Handle objects, which can be passed around or stored in data structures as straightforward scalars. This can be achieved by:
or:
depending on whether you want the IO:Handle collection of methods to be applicable. "But what about the special file handles like STDERR and DATA ?", I hear you cry... The trick here is:
or, if you want the IO::Handle methods:
Noting that the names STDIN, STDOUT and STDERR are special, and refer to main:: variables wherever they are used and are implicitly declared (so no our or my required.) From deep in Perl's past it is possible to use a scalar string value as a reference to a file handle. Consider:
Which looks as though it works by passing the file handle STDERR to the subroutine announce. In fact, what is happening is that (a) the bareword STDERR is passed as a string, and (b) the print treats the contents of $FH as the name of the FILEHANDLE to use (ie as a symbolic reference). One assumes that in the dim and distant past, this looked like a particularly cunning plan to deal with the problem of passing file handles. Of course, in modern times use strict ; will whinge like mad about both the bareword and the sybolic reference. | [reply] [d/l] [select] |