http://www.fmi.uni-passau.de/archive/doc/unix/perl/faq/2.1.html (Einblicke ins Internet, 10/1995)
What are all these $@*%<> signs and how do I know when to use them?
What are all these $@*%<> signs and how do I know when to use them?
Those are type specifiers: $ for scalar values, @ for indexed arrays,
and % for hashed arrays. The * means all types of that symbol name
and are sometimes used like pointers; the <> are used for inputting
a record from a filehandle. See the question on arrays of arrays
for more about Perl pointers.
Always make sure to use a $ for single values and @ for multiple ones.
Thus element 2 of the @foo array is accessed as $foo[2], not @foo[2],
which is a list of length one (not a scalar), and is a fairly common
novice mistake. Sometimes you can get by with @foo[2], but it's
not really doing what you think it's doing for the reason you think
it's doing it, which means one of these days, you'll shoot yourself
in the foot; ponder for a moment what these will really do:
@foo[0] = `cmd args`;
@foo[2] = <FILE>;
Just always say $foo[2] and you'll be happier.
This may seem confusing, but try to think of it this way: you use the
character of the type which you *want back*. You could use @foo[1..3] for
a slice of three elements of @foo, or even @foo{A,B,C} for a slice of
of %foo. This is the same as using ($foo[1], $foo[2], $foo[3]) and
($foo{A}, $foo{B}, $foo{C}) respectively. In fact, you can even use
lists to subscript arrays and pull out more lists, like @foo[@bar] or
@foo{@bar}, where @bar is in both cases presumably a list of subscripts.
While there are a few places where you don't actually need these type
specifiers, except for files, you should always use them. Note that
<FILE> is NOT the type specifier for files; it's the equivalent of awk's
getline function, that is, it reads a line from the handle FILE. When
doing open, close, and other operations besides the getline function on
files, do NOT use the brackets.
Beware of saying:
$foo = BAR;
Which wil be interpreted as
$foo = 'BAR';
and not as
$foo = <BAR>;
If you always quote your strings, you'll avoid this trap.
Normally, files are manipulated something like this (with appropriate
error checking added if it were production code):
open (FILE, ">/tmp/foo.$$");
print FILE "string\n";
close FILE;
If instead of a filehandle, you use a normal scalar variable with file
manipulation functions, this is considered an indirect reference to a
filehandle. For example,
$foo = "TEST01";
open($foo, "file");
After the open, these two while loops are equivalent:
while (<$foo>) {}
while (<TEST01>) {}
as are these two statements:
close $foo;
close TEST01;
but NOT to this:
while (<$TEST01>) {} # error
^
^ note spurious dollar sign
This is another common novice mistake; often it's assumed that
open($foo, "output.$$");
will fill in the value of $foo, which was previously undefined.
This just isn't so -- you must set $foo to be the name of a valid
filehandle before you attempt to open it.