Приглашаем посетить
Мережковский (merezhkovskiy.lit-info.ru)

Section 5.6.  Creating an Anonymous Hash

Previous
Table of Contents
Next

5.6. Creating an Anonymous Hash

Similar to creating an anonymous array, you can also create an anonymous hash. Consider the crew roster from Chapter 4:

my %gilligan_info = (
  name     => 'Gilligan',
  hat      => 'White',
  shirt    => 'Red',
  position => 'First Mate',
);

my %skipper_info = (
  name     => 'Skipper',
  hat      => 'Black',
  shirt    => 'Blue',
  position => 'Captain',
);

my @crew = (\%gilligan_info, \%skipper_info);

The variables %gilligan_info and %skipper_info are just temporaries we needed to create the hashes for the final data structure. We can construct the reference directly with the anonymous hash constructor, which is yet another meaning for curly braces, as we'll see. We can replace this:

my $ref_to_gilligan_info;

{
  my %gilligan_info = (
    name     => 'Gilligan',
    hat      => 'White',
    shirt    => 'Red',
    position => 'First Mate',
  );
  $ref_to_gilligan_info = \%gilligan_info;
}

with the anonymous hash constructor:

my $ref_to_gilligan_info = {
  name     => 'Gilligan',
  hat      => 'White',
  shirt    => 'Red',
  position => 'First Mate',
};

The value between the open and closing curly braces is an eight-element list. The eight-element list becomes a four-element anonymous hash (four key/value pairs). Perl takes a reference to this hash and returns as a single scalar value, which we assign to the scalar variable. Thus, we can rewrite the roster creation as:

my $ref_to_gilligan_info = {
  name     => 'Gilligan',
  hat      => 'White',
  shirt    => 'Red',
  position => 'First Mate',
};

my $ref_to_skipper_info = {
  name     => 'Skipper',
  hat      => 'Black',
  shirt    => 'Blue',
  position => 'Captain',
};

my @crew = ($ref_to_gilligan_info, $ref_to_skipper_info);

As before, we can now avoid the temporary variables and insert the values directly into the top-level list:

my @crew = (
  {
    name     => 'Gilligan',
    hat      => 'White',
    shirt    => 'Red',
    position => 'First Mate',
  },

  {
    name     => 'Skipper',
    hat      => 'Black',
    shirt    => 'Blue',
    position => 'Captain',
  },
);

Note we use trailing commas on the lists when the element is not immediately next to the closing brace, bracket, or parenthesis. This is a nice style element to adopt because it allows for easy maintenance. We can add or rearrange lines quickly, or comment out lines without destroying the integrity of our list.

Now @crew is identical to the value it had before, but we no longer need to invent names for the intermediate data structures. As before, the @crew variable contains two elements, each of which is a reference to a hash containing keyword-based information about a particular crew member.

The anonymous hash constructor always evaluates its contents in a list context and then constructs a hash from key/value pairs, just as if we had assigned that list to a named hash. Perl returns a reference to that hash as a single value that fits wherever a scalar fits.

Now, a word from our parser: because blocks and anonymous hash constructors both use curly braces in roughly the same places in the syntax tree, the compiler has to make ad hoc determinations about which of the two you mean. If the compiler ever decides incorrectly, you might need to provide a hint to get what you want. To show the compiler that you want an anonymous hash constructor, put a plus sign before the opening curly brace: +{ ... }. To be sure to get a block of code, just put a semicolon (representing an empty statement) at the beginning of the block: {; ... }.


Previous
Table of Contents
Next