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

I have working code for trimming off some of the names we get returned from DNS to leave just the computer name. I have to drop it through two variables and I have a gut feeling I could be doing this in one step instaed of two. This code works but are there any suggestions to simplify this code:

if ($pingObj->ping($IpAddress, 1)){ my $MachineName = uc(gethostbyaddr (inet_aton($IpAddress), + AF_INET)) or "[FAILED]"; my $Host = ($MachineName =~ /^(.*?)(-UDP\w*\.|\.)(.*)/i)[0 +]; $Host = "$IpAddress" . "[NULL]" if ($MachineName eq ""); print "$IpAddress\t$Host" if $VERBOSE; } else { print "$IpAddress\tNo Response\n" if $VERBOSE; } }

My goal is to get rid of the variable $Host and just perform all of the functions on $MachineName . To me this means I have to change the regex or my usage of it. But even outside of this would it help the program to have one less variable in this loop in terms of efficiency. Note this section of the code is in an thread and working.

To simplify my query what are the other ways the monks would write the above code?

Update:
Corrected typo perfomr to perform
Changed "Note this section of the code is most likely going to be in an thread." updated version above. I feel this more accurately reflects the state of the code example.

"No matter where you go, there you are." BB

Replies are listed 'Best First'.
Re: Can I condense the variable usage here?
by dragonchild (Archbishop) on Dec 23, 2003 at 13:02 UTC
    A few thoughts other than variables.
    1. Generally, I like to deal with my error conditions before dealing with my success conditions. Something like:
      sub getHostname { my ($IpAddress) = @_; unless ($pingObj->ping($IpAddress, 1)) { print "No response from $IpAddress\n" if $VERBOSE; return; } # Do the rest of the stuff here }
    2. As for your variables, maybe something like:
      # This is the rest of the stuff. # Note the use of single quotes. It's not a performance thing - it +'s a # readability thing. Double-quotes are for interpolation. Single-q +uotes # tell the reader there's no interpolation here. my $Host = uc(gethostbyaddr (inet_aton($IpAddress), AF_INET)) or '[FAILED]'; # Get rid of everything starting with -UDP. # In your version, you captured everything before -UDP. Same diffe +rence. $Host =~ s/-UDP.*//; $Host = "${IpAddress}[NULL]" if $Host eq ''; print "$IpAddress\t$Host\n" if $VERBOSE; return $Host; }
    3. As for threading issues, I'm definitely not the one to ask about that. You'll probably have to add lock() somewheres.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      It works fine in threads I am just trying to have less variables, so that overall I am carrying less baggage in the threads.

      Though I must agree I like unless more than if, but after so many years using if exlusively I don't intially think of using unless. This is a thought process I must try to change.

      The regex change is much better thank you. It goes to show when you put code together to get it to work, that bits can grow and you should learn to trust the gut instinct that you need to revisit a section again. This bit of code intially just got the host name but over the time of looking at the output we added more to it. And I kept feeling it needed a revisit. But when I would look at it I saw how it worked and why we did it that way and couldn't think out of the box we built.

      Thank you again.

      Update:
      I modified the regex in my code for to look like this:

      $Host =~ s/(-UDP.*|\..*)//;

      Which seems to be testing fine but still need to throw it some weird machine names to be sure.

      "No matter where you go, there you are." BB
Re: Can I condense the variable usage here?
by jeffa (Bishop) on Dec 23, 2003 at 14:33 UTC
    Um, how about just using Net::DNS instead? From the EXAMPLES section:
    use Net::DNS; my $res = Net::DNS::Resolver->new; my $query = $res->search("host.example.com"); if ($query) { foreach my $rr ($query->answer) { next unless $rr->type eq "A"; print $rr->address, "\n"; } } else { warn "query failed: ", $res->errorstring, "\n"; }

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      I am on a Win32 machine for now. And Net::DNS is a bit buggy on Win32 from the link you sent. But to explain it more clearly. I have a range of IP addresses that are pinged to see what live machines are on the network. I then look up from a live ip the host name. I need to get the computer name from computer_name.company.com but sometimes our dns/dhcp systems resolves to a name of computer_name-udp12345678.company.com

      "No matter where you go, there you are." BB
Re: Can I condense the variable usage here?
by Roy Johnson (Monsignor) on Dec 23, 2003 at 18:20 UTC
    The test: ($MachineName eq "") is never going to be true, because of the or in the initialization of it. That means that you are only using $MachineName once, and can probably just inline it. This ought to be equivalent to your code:
    if ($pingObj->ping($IpAddress, 1)){ my $MachineName = uc(gethostbyaddr (inet_aton($IpAddress), AF_INET) +) or "[FAILED]"; $MachineName = ($MachineName =~ /^(.*?)(-UDP\w*)?\./i)[0]; print "$IpAddress\t$MachineName" if $VERBOSE; } else { print "$IpAddress\tNo Response\n" if $VERBOSE; }
    But you probably meant ($Host eq ''), didn't you? That would be a good thing to check, if the match, er, didn't. Easy enough:
    # Assuming you won't have a machine named "0" $MachineName = ($MachineName =~ /^(.*?)(-UDP\w*)?\./i)[0] || ($IpAd +dress . '[NULL]');

    The PerlMonk tr/// Advocate

      Oddly enough the code supplies catches .company.com look ups we found. I was getting blank input and caught it with that. I am sure I meant $Host eq '' but the code I cut and paste worked. Though it may have been off the edit version I was working on to change the regex. When I get back to work I will look at the in production code versus the new version I was working on. I believe we tried a regex like you supplied but the problem is their is a value in the string with a value of .company.com but after the regex that is reduced to '' and it was a catch at the bottom.

      Besides catching this in the script I need to know than how to fix these machines that have a null computer name, but that is another query for another place.

      "No matter where you go, there you are." BB