Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: What are typeglobs (useful for)?

by tlm (Prior)
on Jun 26, 2005 at 02:42 UTC ( #469987=note: print w/replies, xml ) Need Help??

in reply to What are typeglobs (useful for)?

I have never found the documentation for typeglobs particularly clear myself, even when typeglobs were more important to routine Perl programming than they are now (references are a better way of doing many of things that typeglobs were used for before).

My favorite introduction to typeglobs is ch. 3 of the venerable Advanced Perl Programming (1st edition, 1997), by Sriram Srinivasan. (The much awaited 2nd edition of this book, by Simon Cozens, is a complete re-write, and will not cover this topic.)

Other sources worth consulting are the Symbol Tables section of perlmod and the Typeglobs and Filehandles section of perldata. These sources have a better treatment (than APP's) of the remaining uses for typeglobs in Perl 5.

I doubt that I can do justice to the subject without writing a very long node, so I will just try to get you started, but I'm going to have to make a bit of a detour into package variables and symbol tables before I can describe typeglobs.

First you should know that Perl has two entirely distinct classes of variables: package variables and lexical (aka "my") variables. Typeglobs concern the former exclusively, so for the remainder of this post I will completely disregard lexicals.

Next, Perl keeps information about package variables in a data structure known as a symbol table. Each package (e.g. main, LWP::Simple, Benchmark) has its own symbol table. The symbol table is actually a hash whose keys are the names of the symbols. The following script will print out all the symbols in the symbol table for the default package, main; these will include the symbol foobarbaz, defined (by assigning to the scalar $main::foobarbaz) just before the loop, along with several other symbols that, because main is the default package, are there more or less by default:

use strict; $main::foobarbaz = 3; print "$_\n", for sort keys %main::; __END__ ^R ^X " $ + - / 0 <none>:: @ ARGV BEGIN CORE:: Carp:: DATA . . . foobarbaz . . .
For example, the seventh symbol above is the one associated with the special variable $/, which holds the input record separator (and with the variables @/, %/, etc., but I'm getting ahead of myself).

NB: for the special package main there is an abbreviation that is commonly used: one can drop the main part, leaving only the ::. Hence, I could have written $::foo instead of $main::foo above, for example. I'll stick with the fully qualified names, because I think they make it easier to follow what's going on.

The important thing to notice here is this funny item %main::. That's the hash corresponding to the symbol table for package main. If you wanted to examine the symbol table for, say, package Foo::Bar::Baz you would examine the hash %Foo::Bar::Baz:: (though you may need to load the package first, e.g. via require).

OK, you may have noticed that, in referring to the keys of the symbol table, I have been careful to call them "symbols," not variables. That's because, under each symbol name, perl stores the information associated with all the package "entities" associated with that symbol, including a scalar variable, an array variable, a hash variable, a subroutine, a filehandle, a dirhandle, a socket, and a format. In other words, under the symbol table entry foo, perl stores the information (if any) associated with $foo, @foo, %foo, &foo, filehandle foo, dirhandle foo, socket foo, and format foo.

This bundle of information associated with a single symbol (such as foo) is a typeglob! One refers to the typeglob for the symbol foo of package main with the expression *main::foo. More precisely, *main::foo is the value corresponding to the key foo in the symbol table %main::.

A typical way to describe a typeglob is as an aggregate data structure consisting of several independent slots, labeled "scalar", "array", "hash", "code" (or subroutine), "filehandle", "dirhandle", "socket", and "format". These slots hold the info for the scalar, array, hash, etc. associated with the corresponding symbol. In most cases, all the slots but one are empty. (Actually, typeglobs have one more slot: a typeglob slot! That's right, typeglobs are self-referential. In the typeglob *foo, for example, there is a slot referring to *foo.)

To look at this in more detail, run the following script:

use strict; $main::foo = 'hello'; @main::foo = 1..7; print "${ *main::foo }\n"; print "${ $main::{ foo } }\n"; print "@{ *main::foo }\n"; print "@{ $main::{ foo } }\n"; __END__ hello hello 1 2 3 4 5 6 7 1 2 3 4 5 6 7
This illustrates a couple of things. First, it shows that $main::{ foo } and *main::foo refer to the same thing, a typeglob. It also shows that this typeglob holds information about both the scalar $main::foo and the array @main::foo, and that we can access this information by enclosing the typeglob in {} and prepending the appropriate sigil (in this case $ or @) to the whole thing. (Of course, there is a simpler way to get to the same information: $main::foo and @main::foo.)

NB: $main::{ foo } and $main::foo are very different things! The former is equal to the typeglob *main::foo while the latter refers to the contents of this typeglob's scalar slot. It is essential to understand this distinction.

Well, even though there is still a lot more to say about typeglobs, this node is already way too long, so I'll stop here. But see the references cited above for more on this topic.

Update: In my original version of this post I neglected to mention the dirhandle, socket, and typeglob slots of typeglobs. I've corrected this omission.

the lowliest monk

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://469987]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (9)
As of 2019-10-22 17:45 GMT
Find Nodes?
    Voting Booth?