The fundamental key IMHO is this. As long as you are doing a lot of thinking involving positional logic, you are not being very Perlish. What this means is that you use implicit looping operations (foreach over a list rather than a C-style for, map, grep) and use hashes to do things by name. To get a good sense I can suggest nothing better than getting the Cookbook and looking through the examples in there.

Short of that I highly recommend the section in Camel II (possibly in Camel III as well?) in chapter 1 on how Perl data structures map to linguistic operations. The linguistic version of a hashlookup is the word "of". This informs us how we name a hash. If the hash gives us the address of the person, we should say $address{$person}. If it is possible to get an address in several ways we might be more verbose and say $address_by_person{$person}. In either case "talk your way" through the problem in English and wherever you say "of" or an equivalent, that is a good sign that you want a hash.

That said, here are some standard uses that I have for them:

  1. The obvious lookup. $address{$person};
  2. Keep track of existing things I have dealt with. Where I might say, "If I haven't seen this one yet (BTW mark it seen) then..." I might write in code: if (not $is_seen{$case}++) { # etc
  3. Named function arguments. Rather than having to remember a set of 6 arguments in order, and what the defaults are if you need to set the 6'th but not touch the 3'rd, 4'th, or 5'th, just use a hash:
    sub my_function { my %opts = @_; # etc
    and it is easier to remember how to call the function, and easier to add more useful options later.
  4. Structs. Anywhere you would have used a pointer to a struct in C, you can use a reference to a hash in Perl. The notation is even similar since the arrow is used in Perl for dereferencing. This is why you see a lot of OO code in Perl with things like: my $name = $self->{name};
  5. List special cases. You can easily enumerate special cases in a hash. If you are willing to create anonymous functions for them (with sub) then you can easily create a nice catch-all special case:
    if (exists $handler{$case}) { $handler{$case}->(); # Handle the special case }
    The actual definitions of the special cases are placed elsewhere. Lest this idea just sound weird, you may want to read Why I like functional programming. (It helps to read the *last* function first - scrub_input - and understand what it does. It may also help to check out what pos does.) OK, perhaps you don't want to try that. Yet.
And so it goes. Whenever it makes sense to refer to things by name, it makes sense to use hashes.

UPDATE
Forgot a ++ on $is_seen{$case}. I thought it, and verbalized it in English, but when I went to write the Perl at last I apparently forgot it at the last moment...


In reply to Re (tilly) 1: Hash Tutorial by tilly
in thread Hash Tutorial by dhammaBum

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.