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

Hi,

I'm trying to reduce the amount of name lookups I'm performing... However, I'm coding this for within a class so I'm not quite certain. I'm new to perl classes...

My code

sub syb_gethostbyaddr { my $self = shift; my $class = ref($self); my ($my_ipaddr) = @_; return (gethostbyaddr(inet_aton($my_ipaddr), AF_INET)) }

In the Programming Perl, it is a little confusing how to implement. "sub numtoname" is the subroutine and $numtoname{} is an unrelated global hash? I don't understand the desire for "local ($_) = @_;"

in essence, can someone explain the example to me? the second and third lines I mean.

from Programming Perl
Cache entries from files (like passwd and group files) that are apt to be reused. It's particularly important to cache entries from the network. For example, to cache the return value from gethostbyaddr when you are converting numeric addresses (like 204.148.40.9) to names (like "www.oreilly.com"), you can use something like:

sub numtoname { local ($_) = @_; unless (defined $numtoname{$_}) { my (@a) = gethostbyaddr(pack('C4', split(/\./)),2); $numtoname{$_} = @a > 0 ? $a[0] : $_; } return $numtoname{$_}; }

I can create a local variable using something like local SybaseInterfaces::{$my_test_var}; but without understanding the simple example...

UPDATE

Here is the new code:

package SybaseInterfaces; .... my %lookup_iptoname = (); sub syb_gethostbyaddr { my $self = shift; my $class = ref($self); my ($my_ipaddr) = @_; # We cache the name lookups to increase performance and reduce ne +twork i/o unless (defined $SybaseInterfaces::lookup_iptoname{$my_ipaddr}) { $SybaseInterfaces::lookup_iptoname{$my_ipaddr} = gethostbyaddr +(inet_aton($my_ipaddr), AF_INET); } return ( $SybaseInterfaces::lookup_iptoname{$my_ipaddr} ); }
Man I feel like an idiot for not seeing it right off the bat... grrr... must be lack of caffeine - that's it

Replies are listed 'Best First'.
Re: local variables and classes
by Fletch (Bishop) on Mar 11, 2004 at 19:47 UTC

    Sounds like you need to read Coping with scoping; at least I think that's what you're asking. More to your actual question you'd want to check out Memoize.

Re: local variables and classes
by Ovid (Cardinal) on Mar 11, 2004 at 20:04 UTC
    1: sub numtoname { 2: local ($_) = @_; 3: unless (defined $numtoname{$_}) { 4: my (@a) = gethostbyaddr(pack('C4', split(/\./)),2); 5: $numtoname{$_} = @a > 0 ? $a[0] : $_; 6: } 7: return $numtoname{$_}; 8: }

    Line two "localizes" the variable $_. Because $_ is a global variable, it's necessary to use local with this global variable to ensure that whatever value you currently assign the variable does not overwrite the previous value. For example:

    foreach (1 .. 3) { foo($_ + 1); print "$_\n"; } + sub foo { $_ = shift; $_ += 7; }

    That code prints 9, 10, and 11 (on successive lines) instead of the 1, 2, and 3 that some would expect. Changing the first line of &foo to local $_ = shift will prevent $_ from being overridden.

    Line 3 says "unless we've already looked up this host, let's look it up and store it in our cache. Line 7 returns the host from the cache.

    Incidentally, use of $_ is a shorthand. If it's confusing, you could write that function like this:

    sub numtoname { my $address = shift; unless (defined $numtoname{$address}) { my (@a) = gethostbyaddr(pack('C4', split(/\./, $address)),2); $numtoname{$address} = @a > 0 ? $a[0] : $address; } return $numtoname{$address}; }

    Cheers,
    Ovid

    New address of my CGI Course.

Re: local variables and classes
by TomDLux (Vicar) on Mar 11, 2004 at 20:31 UTC

    The script is caching values which have been looked up, on the theory that the number of sites looked up is much less than the number of lookups. Memoize is a general solution to apply this to any subroutine.

    As for your confusion, sub numtoname, aka numtoname(), is a routine which is the only place the hash %numtoname, aka $numtoname{..}, is referenced. Since they all have different sigils, and can be distinguished, you are allso allowed to have a scalar value, $numtoname, and an array @numtoname, aka $nuumtoname.., but they wouldn't do anything useful, in this case.

    The local protects the existing value of $_, so that at the end of the routine, that value is restored. Just within the routine, $_ takes on the value of the first argument. local is an old construct which is only useful for protecting previous values assigned to global variables. If you want an actual local variable, use my.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

      As for your confusion, sub numtoname, aka numtoname(), is a routine which is the only place the hash %numtoname, aka $numtoname{..}, is referenced. Since they all have different sigils, and can be distinguished, you are allso allowed to have a scalar value, $numtoname, and an array @numtoname, aka $nuumtoname.., but they wouldn't do anything useful, in this case.

      So what you are saying is that the $numtoname{$_} is just a variable that just happens to have the same name as the subroutine? I could use $my_var{$_} instead?

      forgive me for being slow on this

        nevermind! got it :-)