55

What is the difference between $this, @that, and %those in Perl?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Mare
  • 567
  • 4
  • 3
  • 3
    I was about to complain about this being a dupe many times over, but while I can find questions about why Perl uses sigils that explain what the sigils mean, there isn't a question specifically asking "What do these mean?" So +1 – Chris Lutz Apr 28 '10 at 17:14
  • You may find this related question helpful too: http://stackoverflow.com/questions/1235837/whats-a-simple-ref – dreeves Apr 28 '10 at 19:55
  • 7
    You may find the documentation useful. Do we really have to repeat the most basic contents of the user manual here? – Svante Apr 28 '10 at 21:41
  • 2
    I guess there's a fine line between 20+ up-votes and RTFM. WTH? – FMc Apr 30 '10 at 01:41
  • Note the `%` can now preface arrays or hashes for Perl v5.20's new [key-value slices](http://www.effectiveperlprogramming.com/2014/07/perl-5-20-introduces-keyvalue-slices/). – brian d foy May 14 '15 at 20:24

5 Answers5

43

A useful mnemonic for Perl sigils are:

  • $calar
  • @rray
  • %ash

Matt Trout wrote a great comment on blog.fogus.me about Perl sigils which I think is useful so have pasted below:

Actually, perl sigils don’t denote variable type – they denote conjugation – $ is ‘the’, @ is ‘these’, % is ‘map of’ or so – variable type is denoted via [] or {}. You can see this with:

my $foo = 'foo';
my @foo = ('zero', 'one', 'two');
my $second_foo = $foo[1];
my @first_and_third_foos = @foo[0,2];
my %foo = (key1 => 'value1', key2 => 'value2', key3 => 'value3');
my $key2_foo = $foo{key2};
my ($key1_foo, $key3_foo) = @foo{'key1','key3'};

so looking at the sigil when skimming perl code tells you what you’re going to -get- rather than what you’re operating on, pretty much.

This is, admittedly, really confusing until you get used to it, but once you -are- used to it it can be an extremely useful tool for absorbing information while skimming code.

You’re still perfectly entitled to hate it, of course, but it’s an interesting concept and I figure you might prefer to hate what’s -actually- going on rather than what you thought was going on :)

Hosam Aly
  • 41,555
  • 36
  • 141
  • 182
draegtun
  • 22,441
  • 5
  • 48
  • 71
  • It's wrong to so strongly associate sigils with variable types. It's the reason so many people have problems with them. It would be much better for you to remove everything before "Matt". – brian d foy Apr 28 '10 at 19:40
  • 1
    @brian d foy: I don't see anything wrong with the cited post-- it makes perfect sense to me, but then again I picked up Perl really easily somehow. So what about it makes it a bad quotation for you, if you don't mind my asking? – Platinum Azure Apr 28 '10 at 21:19
  • I think you missed the word "before" in my comment. Matt's stuff is "after". :) – brian d foy Apr 28 '10 at 22:29
  • 2
    I always say that sigils are not part of the variable name, but illustrate *context*. – Axeman Apr 29 '10 at 00:32
  • @brian d foy: I didn't think my prelude did _strongly associate sigils with variable type_. However I got two downvotes following your comment so have amended it to hopefully avoid any conflict with Matt's comments. – draegtun Apr 29 '10 at 08:45
  • Well, you used the sigil to spell the variable (or data) types. That's pretty strong. – brian d foy Apr 29 '10 at 16:41
  • @brian d foy: I believe those mnemonics come straight from the horses mouth (ie. Larry's!). So I think there worth keeping in for reference. But feel free to amend/remove as u see fit. – draegtun May 13 '10 at 09:09
  • 2
    Larry isn't always right though. Consider local and wantarray: two very poor names that we now have to live with. – brian d foy May 13 '10 at 14:57
24

$this is a scalar value, it holds 1 item like apple

@that is an array of values, it holds several like ("apple", "orange", "pear")

%those is a hash of values, it holds key value pairs like ("apple" => "red", "orange" => "orange", "pear" => "yellow")

See perlintro for more on Perl variable types.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
CaffGeek
  • 21,856
  • 17
  • 100
  • 184
  • 4
    perldoc is really quite good: http://perldoc.perl.org/perldata.html (or run `perldoc perldata`, if you have documentation installed). – Cascabel Apr 28 '10 at 17:01
  • 10
    Side note: $scalar values are often used to point at (reference) arrays and hashes (and sometimes even other scalars). – Frank Krueger Apr 28 '10 at 17:02
  • 2
    @Frank - Yes, that and arrays can be used as hashes. My favorite is in subs with named parameters: `my ($foo, $bar) = @{@_}{qw/ foo bar /};` – amphetamachine Apr 28 '10 at 17:15
  • 2
    Careful - the code `@that = ["apple", "orange", "pear"]` creates an anonymous array reference and tries to assign it to `@that`, which leads to confusing results. `@that = ("apple", "orange", "pear")` does what you want, and `@that = qw(apple orange pear)` does it prettier. – Chris Lutz Apr 28 '10 at 17:16
  • 1
    @Frank Krueger: And file handles, and code references, and... :-) – Platinum Azure Apr 28 '10 at 17:16
  • @Chris, been a long time since I used perl, changed my answer to use () instead of [] – CaffGeek Apr 28 '10 at 17:22
  • 1
    This is too much of an oversimplification. Hash slices are accessed with @. – frankc Apr 28 '10 at 17:47
10

Perl's inventor was a linguist, and he sought to make Perl like a "natural language".

From this post:

Disambiguation by number, case and word order

Part of the reason a language can get away with certain local ambiguities is that other ambiguities are suppressed by various mechanisms. English uses number and word order, with vestiges of a case system in the pronouns: "The man looked at the men, and they looked back at him." It's perfectly clear in that sentence who is doing what to whom. Similarly, Perl has number markers on its nouns; that is, $dog is one pooch, and @dog is (potentially) many. So $ and @ are a little like "this" and "these" in English. [emphasis added]

mob
  • 117,087
  • 18
  • 149
  • 283
9

People often try to tie sigils to variable types, but they are only loosely related. It's a topic we hit very hard in Learning Perl and Effective Perl Programming because it's much easier to understand Perl when you understand sigils.

Many people forget that variables and data are actually separate things. Variables can store data, but you don't need variables to use data.

The $ denotes a single scalar value (not necessarily a scalar variable):

$scalar_var
$array[1]
$hash{key}

The @ denotes multiple values. That could be the array as a whole, a slice, or a dereference:

@array;
@array[1,2]
@hash{qw(key1 key2)}
@{ func_returning_array_ref };

The % denotes pairs (keys and values), which might be a hash variable or a dereference:

%hash
%$hash_ref

Under Perl v5.20, the % can now denote a key/value slice or either a hash or array:

%array[ @indices ];  # returns pairs of indices and elements
%hash{ @keys };      # returns pairs of key-values for those keys
brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • Side note: You can also have scalar references-- what the point would be, I don't know, but you can. Dereferencing those is done with something like `$$scalar_ref`. – Platinum Azure Apr 28 '10 at 21:22
  • 3
    Scalar references are nice to pass around large data without copying them. – brian d foy Apr 28 '10 at 22:29
4

You might want to look at the perlintro and perlsyn documents in order to really get started with understanding Perl (i.e., Read The Flipping Manual). :-)

That said:

  • $this is a scalar, which can store a number (int or float), a string, or a reference (see below);
  • @that is an array, which can store an ordered list of scalars (see above). You can add a scalar to an array with the push or unshift functions (see perlfunc), and you can use a parentheses-bounded comma-separated list of scalar literals or variables to create an array literal (i.e., my @array = ($a, $b, 6, "seven");)
  • %those is a hash, which is an associative array. Hashes have key-value pairs of entries, such that you can access the value of a hash by supplying its key. Hash literals can also be specified much like lists, except that every odd entry is a key and every even one is a value. You can also use a => character instead of a comma to separate a key and a value. (i.e., my %ordinals = ("one" => "first", "two" => "second");)

Normally, when you pass arrays or hashes to subroutine calls, the individual lists are flattened into one long list. This is sometimes desirable, sometimes not. In the latter case, you can use references to pass a reference to an entire list as a single scalar argument. The syntax and semantics of references are tricky, though, and fall beyond the scope of this answer. If you want to check it out, though, see perlref.

Platinum Azure
  • 45,269
  • 12
  • 110
  • 134
  • Side note: In Perl (pre Perl 6), when you access an array or hash to retrieve a single element, at that point the `$` sigil is used for that access; this is because while you're digging into an array or hash, what you're actually GETTING is a scalar, and Larry Wall (the creator of Perl) believed it made more sense to use the scalar sigil to denote that the value you're getting can be used anywhere a normal scalar variable can be used. – Platinum Azure Apr 28 '10 at 17:15
  • in Perl v5.20, you can apply a `%` to either an array or a hash to get a [key-value slice](http://www.effectiveperlprogramming.com/2014/07/perl-5-20-introduces-keyvalue-slices/) – brian d foy May 14 '15 at 20:21