ajefferies has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks,

I am trying to create a script to track and store domain information. I'm hoping to store the information in a hash by domain level. Kind of like:

.com->domain1->subdomain ->domain2->subdomain ->subdomain2 .net->domain1->subdomain ->subsubdomain1->subsubsubdomain1 ->subsubsubdomain2

I have the URI elements broken out into an array (rootdomain,domain,subdomain,...) and I want to insert them into a hash.

How can I check each element to tell whether it should create a new domain or go into an appropriate existing one and keep checking if it already exists.

Is there some funky statement I can use to check each level of domain to see if it's level exists. The answer is obvious to me if it is a fixed number of sub-domains but I can't figure out how to do it with different numbers of domains. (ie. www.perlmonks.com or seek.wisdom.here.perlmonks.com)

Thoughts?

Thanks in advance for your assistance.

Replies are listed 'Best First'.
Re: storing domain info in hashes of hashes
by Aristotle (Chancellor) on Nov 18, 2002 at 16:39 UTC
    Something like this should work (untested):
    sub insert_domain { my $cursor = shift; $cursor = $cursor->{$_} ||= {} for @_; $cursor = {}; } insert_domain(\%domain, qw(org perlmonks www));

    The only "trick" here is using ||=, which only assigns to a variable if it's false. Since we only add hash references in this hash structure and references are always true, it means we only assign an empty anonymous hash {} to nonexistant values; otherwise, we move the cursor down one level to the already existing subhash.

    Update: pg's post compelled me to test mine, and it does work:

    Makeshifts last the longest.

      That is one fine solution. Completely different than I had been attempting. Thanks so much.
Re: storing domain info in hashes of hashes
by pg (Canon) on Nov 18, 2002 at 16:35 UTC
    Try this:
    use Data::Dumper; use strict; sub insert { my $domain_hash = shift; my @domain_chain = @_; my $parent = $domain_hash; my $cur_node; while ($cur_node = shift @domain_chain) { if (exists($parent->{$cur_node})) { $parent = $parent->{$cur_node}; } else { do { $parent->{$cur_node} = {}; $parent = $parent->{$cur_node}; } until (!($cur_node = shift @domain_chain)); } } } my $domain_hash = {}; insert($domain_hash, "www", "perlmonks", "com"); insert($domain_hash, "www", "perlmonks", "org"); insert($domain_hash, "www", "google", "com"); print Dumper($domain_hash);