Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Mashing with Hashing

by hacker (Priest)
on Feb 24, 2005 at 15:28 UTC ( [id://434094]=perlmeditation: print w/replies, xml ) Need Help??

As many who hang out in Chatterbox already know, I've been fighting with learning hashes for quite some time. Its the only data structure in Perl that gives me fits. I'm also trying to ramp up on some templating in Perl, for a big project I'm going to be working on very soon. I've decided that HTML::Template fits the bill for my needs in the short term.

To that end, I've been trying to find little reasons to give me more challenges to force me to learn how to build and use hashes better. I'm starting to "get it". tye's help and this hash howto helped quite a bit, as did the help of many seasoned monks in the CB (you know who you are).

I've been frustratred with some of the boring logging on my server, and I found something called BirdTrap, which basically logs and sends an email for every ErrorDocument Apache serves up. If you look at the code, its pretty monolithic and flat. It looks like perl4'ish code. Its dying for a hash infusion.

To that end, I decided to take that concept and write a replacement that uses hashes, HTML::Template, and MIME::Lite to do its dirty work. I've linted it for cross-site scripting attacks (xSS). I think I've covered all of the possibililities (did I miss any?). Its also 30% of the size of the original.

The only thing left to do, is create a hash on a per-domain basis, so I can email these errors to the owner of the domain, instead of to one solid address (see? More hash training!)

Does this look like a good transition from nothing to something? I'm looking for some other practical ways I can learn more about hashes, and use them in an every day capacity.

Where else can I look for some hash "puzzles" that I can use?

Replies are listed 'Best First'.
Re: Mashing with Hashing
by revdiablo (Prior) on Feb 24, 2005 at 18:48 UTC

    One neat thing you can play with is a hash-based dispatch table. The idea is you store code references as the hash values, and look up the code by key, as necessary.

    Here's a simplistic example that hopefully gives you some idea of the power behind these constructs. Say you have a string of text, and you want to read it word-by-word, reacting to certain words in different ways. A traditional way to do that would be:

    my $text = "I am going to walk to the park."; for ($text =~ /(\w+)/g) { if (lc $_ eq "walk") { print "Walking is good for you\n"; } elsif (lc $_ eq "park") { print "Parks are fun\n"; } }

    That's good and well, but not very flexible, or scalable. Each new entry would require a new branch in the if/elsif chain, which can really start to add up. A hash-based approach might look something like this:

    my %react_to = ( walk => sub { print "Walking is good for you\n" }, park => sub { print "Parks are fun\n" }, ); my $text = "I am going to walk to the park."; for ($text =~ /(\w+)/g) { if (my $reaction = $react_to{lc $_}) { $reaction->(); } }

    This one may seem more complicated, but it's moving the logic out of a nested chain of if/elsif statements and into a data structure. All sorts of neat things can then be done with that data structure, including modifying it at runtime. Here's a dispatch table that modifies itself at runtime:

    my %react_to = ( a => sub { shift->{b} = sub { print "A before B\n" } }, b => sub { shift->{a} = sub { print "B before A\n" } }, ); my $text = "b is the first word, but a is not the last."; for ($text =~ /(\w+)/g) { print "Read word: $_\n"; if (my $reaction = $react_to{$_}) { $reaction->(\%react_to); } }

    This may be a contrived example, and it relies on the calling code passing the dispatch table in as an argument, but the idea is there.

Re: Mashing with Hashing
by kvale (Monsignor) on Feb 24, 2005 at 15:36 UTC
    I think a most excellent way to learn is to work problems and then check out the solutions. To that end, you could search for hash/dictionary/associative array on the Perlmonks site. Read the question and try to solve it on your own. Then check the answers to see how you did.

    Further 'exercises' can be found in the perl FAQ and in the Perl Cookbook. Have fun!

    -Mark

Re: Mashing with Hashing
by pelagic (Priest) on Feb 24, 2005 at 15:47 UTC
    hacker
    I'd suggest you to look into some OO programming. Very often in common modules you will find the objects stored as hash or even as HoH (Hash of Hash) or HoA (Hash of Array).
    Enjoy!

    pelagic
Re: Mashing with Hashing
by mkirank (Chaplain) on Feb 25, 2005 at 11:07 UTC
Re: Mashing with Hashing
by bageler (Hermit) on Feb 24, 2005 at 18:42 UTC
    any problem where you need multidimensional descriptive (non-integer dimensions) data. for example a web log, and you want to view results per webpage per hour. Or problems where you want to group results by unique identifiers.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://434094]
Approved by herveus
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-25 17:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found