19
$hash = { 'Man' => 'Bill',
          'Woman' => 'Mary,
          'Dog' => 'Ben'
        };

What exactly do Perl's “anonymous hashes” do?

G. Cito
  • 6,210
  • 3
  • 29
  • 42
user1363308
  • 938
  • 4
  • 14
  • 33
  • That hash reference isn't anonymous, since it's stored in the variable `$hash`. –  Jan 05 '13 at 23:00
  • 8
    Philosophically speaking, it *is* a reference to an anonymous hash. `%hash` is a named hash, `$hash` is not, its just a reference. The reference could point to a named hash, though. – TLP Jan 05 '13 at 23:43
  • @TLP - `%hash` names a hash, but it itself isn't a named hash. – Kenosis Jan 06 '13 at 00:36
  • @JackManey - But the OP's hash is anonymous. – Kenosis Jan 06 '13 at 00:42
  • 1
    @Kenosis: I think that's being overly picky. The 5-character string `%hash` is a name, not a hash, but it's perfectly reasonable to refer to the hash that it names as `%hash`, which is a named hash. Just as `"Kenosis"` is a name, not a person, but Kenosis is a person. (Assuming you're not a bot, of course.) – Keith Thompson Jan 06 '13 at 03:34
  • The "anonymous" nature of the hashreference is that it doesn't point to a hash that previously was created and named. – Joel Berger Jan 06 '13 at 04:26
  • 3
    @JoelBerger: There is so much unclear thinking here. A hash reference *cannot* be anonymous, only the hash itself. The reference may refer to a hash that has a name, or to one that doesn't: if you are using references then the namedness of the hash is irrelevant. – Borodin Jan 06 '13 at 04:42
  • 1
    @Borodin, sorry, this is the standard terminology, I'm sorry you find it unclear. http://perldoc.perl.org/perlreftut.html#Making-References – Joel Berger Jan 06 '13 at 04:46
  • @KeithThompson - That was my point. – Kenosis Jan 06 '13 at 05:26
  • 2
    @Borodin: "A hash reference *cannot* be anonymous" -- Oh? `my $hash_ref_ref = \{'foo' => 'bar'};` – Keith Thompson Jan 06 '13 at 05:41
  • @KeithThompson: That is a reference to a reference to an anonymous hash. Saying a reference *itself* is anonymous is meaningless. – Borodin Jan 06 '13 at 18:12
  • @JoelBerger: Nowhere does that document talk about an *anonymous reference*. A reference can be to a named hash or to an anonymous hash. Theoretically Jack Maney is correct to say that that the *reference* in the question is named because it is accessible through a named variable, but that is unusual terminology and very different from the hash itself being unnamed. – Borodin Jan 06 '13 at 18:15
  • "The "anonymous" nature of the hashreference is that it doesn't point to a hash that previously was created and named." Read what I said. I never said that the hash reference was anonymous. An anonymous hash with no references ceases to exist. Therefore the anonymous nature of the hash reference is that it points to one that was never stored as a named hash. I'm not disagreeing with you. – Joel Berger Jan 06 '13 at 19:57
  • @Borodin: `$hash_ref_ref` is a named scalar object, which happens to be a reference, so it's a named reference. The thing it refers to is itself a reference (specifically a hash reference), and that reference has no name of its own, so it's an *anonymous hash reference*, the thing you said doesn't exist. It also happens to be a reference to an anonymous hash. So we have a named reference, referring to an anonymous reference, referring to an anonymous hash. Or am I missing something? – Keith Thompson Jan 06 '13 at 23:54
  • @JoelBerger: It may not be what you meant to say, but *"The "anonymous" nature of the hashreference"* tells me that you think the hash reference is anonymous. – Borodin Jan 07 '13 at 00:15
  • @KeithThompson: As I said regarding Jack Maney's comment, theoretically references can be called *named* or *anonymous*, but that is unusual terminology. What I was trying to say is that the distinction is never made and is of little use. For instance in `sqrt(4)` or `print "line\n"` we don't have an *anonymous number* or an *anonymous string*. – Borodin Jan 07 '13 at 00:23
  • @Borodin: Ok. If you had said that it doesn't matter whether references are anonymous or not, I would have had nothing to say. But you specifically said that "a hash reference cannot be anonymous", which is a very different statement, and that's what I was responding to. In any case, I don't think it's particularly relevant to the OP's question. – Keith Thompson Jan 07 '13 at 00:35
  • @Borodin, of course you are specifically correct, but as you cannot have an anonymous hash without having a reference to it, WHO CARES! – Joel Berger Jan 07 '13 at 02:46

4 Answers4

23

It is a reference to a hash that can be stored in a scalar variable. It is exactly like a regular hash, except that the curly brackets {...} creates a reference to a hash.

Note the usage of different parentheses in these examples:

%hash = ( foo => "bar" );   # regular hash
$hash = { foo => "bar" };   # reference to anonymous (unnamed) hash
$href = \%hash;             # reference to named hash %hash

This is useful to be able to do, if you for example want to pass a hash as an argument to a subroutine:

foo(\%hash, $arg1, $arg2);

sub foo {
    my ($hash, @args) = @_;
    ...
}

And it is a way to create a multilevel hash:

my %hash = ( foo => { bar => "baz" } );  # $hash{foo}{bar} is now "baz"
TLP
  • 66,756
  • 10
  • 92
  • 149
  • 1
    I think this is more confusing thatn it needs to be. There is no way that an anonymous hash "a reference to a hash data structure". An anonymous hash is simply a hash without a name. Both named and anonymous hashes have references, and `\%hash` is no more a *direct* reference than `{ foo => "bar" }`. You imply that the latter is an indirect reference. – Borodin Jan 05 '13 at 20:08
  • 1
    It's not a hash without a name. A "hash" is the variable prefaced with a percent sign. `{ ... }` creates a reference to a hash. As data containers, they are the same, but practically, they are different. – TLP Jan 05 '13 at 22:53
  • I understand the confusion now. I meant the practice of using `{}` creates a reference, not that an anonymous hash is something different. Which, by the way, you might have picked up on when I said "It is exactly like a regular hash". – TLP Jan 05 '13 at 22:58
15

You use an anonymous hash when you need reference to a hash and a named hash is inconvenient or unnecessary. For instance, if you wanted to pass a hash to a subroutine, you could write

my %hash = (a => 1, b => 2);
mysub(\%hash);

but if there is no need to access the hash through its name %hash you could equivalently write

mysub( {a => 1, b => 2} );

This comes in handy wherever you need a reference to a hash, and particularly when you are building nested data structures. Instead of

my %person1 = ( age => 34, position => 'captain' );
my %person2 = ( age => 28, position => 'boatswain' );
my %person3 = ( age => 18, position => 'cabin boy' );

my %crew = (
  bill => \%person1,
  ben  => \%person2,
  weed => \%person3,
);

you can write just

my %crew = (
  bill => { age => 34, position => 'captain' },
  ben  => { age => 28, position => 'boatswain' },
  weed => { age => 18, position => 'cabin boy' },
);

and to add a member,

$crew{jess} = { age => 4, position => "ship's cat" };

is a lot neater than

my %newperson = ( age => 4, position => "ship's cat" );
$crew{jess} = \%newperson;

and of course, even if a hash is created with a name, if its reference is passed elsewhere then there may be no way of using that original name, so it must be treated as anonymous. For instance in

my $crew_member = $crew{bill}

$crew_member is now effectively a reference to an anonymous hash, regardless of how the data was originally constructed. Even if the data is (in some scope) still accessible as %person1 there is no general way of knowing that, and the data can be accessed only by its reference.

Borodin
  • 126,100
  • 9
  • 70
  • 144
5

It's quite simple. They allow you to write

push @hashes, { ... };

f(config => { ... });

instead of

my %hash = ( ... );
push @hashes, \%hash;

my %config = ( ... );
f(config => \%config);

(If you want to know the purpose of references, that's another story entirely.)

ikegami
  • 367,544
  • 15
  • 269
  • 518
4

Anything "anonymous" is a data structure that used in a way where it does not get a name.

Your question has confused everyone else on this page, because your example shows you giving a name to the hash you created, thus it is no longer anonymous.

For example - if you have a subroutine and you want to return a hash, you could write this code:-

return {'hello'=>123};

since it has no name there - it is anonymous. Read on to unwind the extra confusion other people have added on this page by introducing references, which are not the same thing.

This is another anonymous hash (an empty one):

{}

This is an anonymous hash with something in it:

{'foo'=>123}

This is an anonymous (empty) array:

[]

This is an anonymous array with something in it:

['foo',123]

Most of the time when people use these things, they are really trying to magically put them inside of other data structures, without the bother of giving them a waste-of-time temporary name when they do this.

For example - you might want to have a hash in the middle of an array!

@array=(1,2,{foo=>3});

that array has 3 elements - the last element is a hash! ($array[2]->{foo} is 3)

perl -e '@array=(1,2,{foo=>1});use Data::Dumper;print Data::Dumper->Dump([\@array],["\@array"]);'
$@array = [
            1,
            2,
            {
              'foo' => 1
            }
          ];

Sometimes you want to don't want to pass around an entire data structure, instead, you just want to use a pointer or reference to the data structure. In perl, you can do this by adding a "\" in front of a variable;

%hashcopy=%myhash;     # this duplicates the hash
$myhash{test}=2;       # does not affect %hashcopy
$hashpointer=\%myhash; # this gives us a different way to access the same hash
$hashpointer->{test}=2;# changes %myhash
$$hashpointer{test}=2; # identical to above (notice double $$)

If you're crazy, you can even have references to anonymous hashes:

perl -e 'print [],\[],{},\{}'
ARRAY(0x10eed48)REF(0x110b7a8)HASH(0x10eee38)REF(0x110b808)

and sometimes perl is clever enough to know you really meant reference, even when you didn't specifically say so, like my first "return" example:

perl -e 'sub tst{ return {foo=>bar}; }; $var=&tst();use Data::Dumper;print Data::Dumper->Dump([\$var],["\$var"]);'     
$var = \{
       'foo' => 'bar'
     };

or:-

perl -e 'sub tst{ return {foo=>bar}; }; $var=&tst(); print "$$var{foo}\n$var->{foo}\n"'
bar
bar
cnd
  • 1,689
  • 16
  • 14