While reading about the pragma overload of Perl5, I noticed the operator *{}
.
I'd like to know what kind of sigil *
is, if any, or what's the meaning of *
in a ref context.
*foo
is a "typeglob", or "glob" for short. A glob is a structure (as in C struct
) with fields named ARRAY
, HASH
, IO
, etc. These fields either contain nothing or a reference. From the perspective of Perl code, they look like very special hashes.
The primary purpose of globs is to server as entries for Perl's symbol table. The symbol table holds all symbols that belong to a package and all "truly global" variables (e.g. STDOUT
, $1
, etc). Without the symbol, there would be no named subroutines, @ISA
and @EXPORT
wouldn't exist, and neither would @_
, $$
, etc. [Obviously, globs are most definitely not legacy.]
$ perl -E'
our @foo = qw( a b c );
our %foo = ( d=>4, e=>5 );
say @{ *foo{ARRAY} };
say %{ *foo{HASH} };
'
abc
d4e5
Globs are also used as wrappers around IO objects (file handles). Even open(my $fh, ...)
populates $fh
with a glob.
Globs are very rarely used explicitly in Perl. The one exception is old-style file handles. For example, FILE
and STDOUT
actually means *FILE
and *STDOUT
(when used as file handles), which in term are used to get *FILE{IO}
and *STDOUT{IO}
.
$ perl -e'open(FILE, "echo foo|") or die; print readline(FILE);'
foo
$ perl -e'open(*FILE, "echo foo|") or die; print readline(*FILE);'
foo
$ perl -e'open(*FILE{IO}, "echo foo|") or die; print readline(*FILE{IO});'
foo
So why would you want to override *{}
?
You would want to override *{}
if you wanted to create an object that looks like a file handle without actually being a file handle. For example, you could use this override to make IO::Socket object hash-based objects instead of glob-based objects.