Here's the relevant excerpt from the documentation of the ref
function:
The value returned depends on the type of thing the reference is a reference to. Builtin types include:
SCALAR ARRAY HASH CODE REF GLOB LVALUE FORMAT IO VSTRING Regexp
Based on this, I imagined that calling ref
on a filehandle would return 'IO'
. Surprisingly, it doesn't:
use strict;
use warnings;
open my $fileHandle, '<', 'aValidFile';
close $fileHandle;
print ref $fileHandle; # prints 'GLOB', not 'IO'
perlref
tries to explain why:
It isn't possible to create a true reference to an IO handle (filehandle or dirhandle) using the backslash operator. The most you can get is a reference to a typeglob, which is actually a complete symbol table entry [...] However, you can still use type globs and globrefs as though they were IO handles.
In what circumstances would ref
return 'IO'
then?
The only way to get an IO reference is to use the *FOO{THING} syntax:
$ioref = *glob{IO};
where glob is a named glob like STDIN or a reference like $fh. But once you have such a reference, it can be passed around or stored in arbitrary data structures just like any other scalar, so things like marshalling modules need to be savvy of it.
Since a glob or globref can be used as a filehandle and implicitly get the contained IO thingy, there isn't a lot of need for IO refs. The main exception is this:
use Symbol;
# replace *FOO{IO} handle but not $FOO, %FOO, etc.
*FOO = geniosym;
(geniosym returns a new semi-anonymous IO reference, and any non-glob reference-to-glob assignment only assigns to that particular reference's part of the glob)
As Konerak says, the answer is in this question:
How can I get Perl's ref() function to return REF, IO, and LVALUE?
The relevant snippet is:
use Acme::Damn;
say 'IO: ', ref damn *STDIN{IO}; # really prints IO
and this should not really be used in production code since damn removes the bless from the reference...
来源:https://stackoverflow.com/questions/2955428/when-does-refvariable-return-io