http://qs321.pair.com?node_id=311626

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

Greeting all,
I have this code so far but I am trying to figure out how to sort on the hashes I have built in my sub routine, where I am getting a bit confused is the returned value from my nslookup will not always be in the same order so ip for ns1.t might not be the first, but the second or last. With that said will my sort still work or should I build my hashes as a hash of an array?? This is really confusing to me and I really have no idea where to start. Any help you might offer would be great.

SUNADMN
USE PERL
#!/usr/bin/perl use strict; use Net::Nslookup; my $input = '/var/tmp/clean'; my $ours = '/var/tmp/ours'; my $theirs = '/var/tmp/theirs'; my $unknown = '/var/tmp/unknown'; open(IN, "$input") || die "Can't open $input\nReason: $!\n"; open(OUT, ">$ours") || die "Can't create $ours\nReason: $!\n"; open(OUT1, ">$theirs") || die "Can't create $theirs\nReason: $!\n"; open(OUT2, ">$unknown") || die "Can't create $unknown\nReason: $!\n"; my @ns; while(<IN>) { my $domain = $_; chomp $domain; @ns = nslookup(domain => "$domain", type => "NS"); &ours; # for(@ns) { # print "@ns\n"; # } } sub ours { my %ours ( '24.56.102.10' => ns1.t, '24.56.100.10' => ns2.t, '24.56.100.11' => ns3.t ) my %theirs ( '68.168.192.17' => ns1.a, '24.50.78.2' => ns2.a, '68.168.224.177' => ns3.a ( if($ours{ns1.t}) { print OUT "$_\n"; } elseif($theirs{ns1.a}) { print OUT1 "$_\n"; } } close(IN); close(OUT); close(OUT1); close(OUT2); exit;

Replies are listed 'Best First'.
Re: To Hash or Not to Hash??
by l2kashe (Deacon) on Dec 02, 2003 at 15:38 UTC

    There is an issue here. In your test structure you are testing for $our{'ns1.t'}, but ns1.t is a value not a key. What you would need to test for would be a key.. ala

    my $ip = '24.56.102.10'; my %ours = ( 24.56.102.10 => 'ns1.t', ); if ( $ours{$ip} ) { print "Its there\n"; } else { print "Its not there\n"; }

    If I am reading deep enough into what you are trying to do, I think you want to also reverse your %our and %theirs hashes. ala

    $ours{$v} = $k while ( my($k, $v) = each %ours);

    This way you can test for the existance of either the name of the host, or the IP address of the host.

    On a side note in regards to style, it is better to pass the data you are going to be working on to your sub.

    #... yada yada ... my %ips = ( ours => { 24.56.102.10 => 'ns1.t', }, theirs => { 68.168.192.17 => 'ns1.a', }, ); my @recs = nslookup( type => "NS", domain => $domain, ); ours(\%ips, \@recs); # .. yada yada .. sub ours { my($ip, $recs) = @_; for ( @$recs ) { if ( $ip->{ours}{$_} ) { print OUT "$_\n"; } elsif ( $ip->{theirs}{$_} ) { print OUT1 "$_\n"; } else { # do we care about this case? } } }

    This way its clear exactly what is going where, and what data is being worked on. As opposed to digging into the sub, figuring out what variables are used, determine their scope, etc..

    use perl;

      As a quick side note, an idiom for inverting a hash like that is

      %ours = reverse %ours;

      This may not be the right choice if the hash is very large because of the extra memory used by the temporary list. But in this case, it looks like it would be okay.

      See recipe 5.8 in the Perl Cookbook.

      Obviously, both of our solutions will have problems if the values are not unique.

      G. Wade
Re: To Hash or Not to Hash??
by Roy Johnson (Monsignor) on Dec 02, 2003 at 19:28 UTC
    First of all, this is not real code. Your hash assignments lack an equals sign, the closing parenthesis on %theirs is an open parenthesis, and you're quoting the side of the hash assignment arrows that doesn't need quotes.
    68.168.192.17 => 'ns1.a'
    not
    '68.168.192.17' => ns1.a
    Your if block is not sensible. It seems that $_ should figure in the conditional somehow; isn't that what you want to test? Maybe something like:
    if ($ours{$_} eq 'ns1.t') { print OUT "$_\n"; } elsif ($theirs{$_} eq 'ns1.a') { print OUT1 "$_\n"; }
    You mention a sort in your question, but not in your code. Could you give us a little clearer description of what you want your code to do?

    The PerlMonk tr/// Advocate