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

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

Just using warnings, I get this Undefined subroutine &main::inet_aton called at dnscheck.pl line 15. When I add in use strict; I get
Global symbol "%dns_check" requires explicit package name at dnscheck. +pl line 7. Global symbol "$key" requires explicit package name at dnscheck.pl lin +e 13. Global symbol "$value" requires explicit package name at dnscheck.pl l +ine 13. Global symbol "%dns_check" requires explicit package name at dnscheck. +pl line 13. Global symbol "$key" requires explicit package name at dnscheck.pl lin +e 14. Global symbol "$key" requires explicit package name at dnscheck.pl lin +e 15.
This is the code so far:
%dns_check = ("address" => "ip"); while ( ($key, $value) = each %dns_check) { $found_addr = gethostbyname($key) or die "Error $!\n"; $found_addr = inet_ntoa(inet_aton($key)); print "IP found is: $found_addr ", "\n"; }
- Confused

Replies are listed 'Best First'.
Re: Undefined Subroutine & Global symbol requires explicit package name
by Corion (Patriarch) on Jan 24, 2012 at 15:29 UTC

    Where did you find inet_aton documented? Consider taking a look at Socket and use.

    The code you showed is not the code you run. Please post the complete code that corresponds to your error message. The snippet you show does not tell us anything about your code.

    strict.pm is there to force you to predeclare all variables you use. This helps preventing typos in variable names. If you have use strict; in your program, you will need to predeclare all variable names you use. You don't do that, at least if we are to believe the error message you get. Maybe you want to predeclare the variables?

Re: Undefined Subroutine & Global symbol requires explicit package name
by rovf (Priest) on Jan 24, 2012 at 15:31 UTC
    From your question, I assume that you are a beginner in Perl. In this case, I recommend that you add use diagnostics; in addition to strict and warnings. It will give you more information about the messages.

    %dns_check = ("address" => "ip");
    You should always "declare" your variables, to tell Perl whether you want to have a lexically scoped or a globally scoped variables. For the time being (until you get more experience), I suggest you use only lexically scoped variables. You declare it using my:
    my %dns_check = ("address" => "ip");
    See my.

    -- 
    Ronald Fischer <ynnor@mm.st>
Re: Undefined Subroutine & Global symbol requires explicit package name
by rovf (Priest) on Jan 24, 2012 at 15:35 UTC
    Undefined subroutine &main::inet_aton called at dnscheck.pl line 15.
    Hmmmm..... What exactly is unclear in this error message? It is pretty much plain English.

    In case you wonder about the &main:: part: Subroutine names in Perl always belong to some package. If you don't write your own package definition, Perl assumes that you are in package main. Hence, Perl looks for the subroutine inet_aton in Package main.

    -- 
    Ronald Fischer <ynnor@mm.st>
      Yikes, yeah I didn't realize that "Global Symbol...." error was due a declaring issue, I've always declared them with 'my' but forgot and should have thought that through more, yaddayadda.. With the undefined subroutine problem, my issue was resolved by adding use Socket; duhhh! So from my understanding, that type of error will come up if you try to call some type of function incorrectly, say I write INET_ATON instead of inet_aton, because perl is case sensitive, right? Orrr, in this case, not 'using' the Socket or a module perhaps? Thanks as always

        Perl is mostly case-sensitive. There is some ambiguity over case with regard to module names on case-insensitive file systems. For example, given the following module:

        # this code is in Foo/Bar.pm package Foo::Bar; use parent qw/Exporter/; our @EXPORT = qw/baz/; sub baz { "Hello world"; } 1;

        On a Windows system (Windows a uses case-insensitive but case-preserving file system) you could do this:

        use 5.010; use strict; use foo::bar; say Foo::Bar::baz(); # says "Hello world"

        And you could do this:

        use 5.010; use strict; use Foo::Bar; say baz(); # says "Hello world"

        But you couldn't do this:

        use 5.010; use strict; use foo::bar; say baz(); # dies - undefined subroutine main::baz

        And you couldn't do this:

        use 5.010; use strict; use foo::bar; say foo::bar::baz(); # dies - undefined subroutine again
        You didn't really understand the first answer you got on the issue: "where did you find inet_aton documented?".

        When you call a subroutine, it must be defined somewhere, unless it is a builtin Perl function, like "each" and "print" in your example. In your code, you want to use functions from the module "Socket.pm" - so you have to "use Socket" to make these functions available.

        You can tell that inet_aton is not a Perl function simply by checking with man perlfunc or by trying

        perldoc -f inet_aton

        Of course, if you misspell a function you'll get the same error, but this is not the issue here.

        further documentation

Re: Undefined Subroutine & Global symbol requires explicit package name
by Anonymous Monk on Jan 24, 2012 at 15:32 UTC
    I do not know what you used to learn Perl, but clearly it's a bad resource/teacher if you already confused by this very basic problem. See http://learn.perl.org/ and http://perl-tutorial.org/ to find good ones.

    You need to declare variables you use with the my function.

    use strict; use warnings FATAL => 'all'; my %dns_check = (address => 'ip'); while (my ($key, $value) = each %dns_check) { my $found_addr = gethostbyname($key) or die "Error $!\n"; $found_addr = inet_ntoa(inet_aton($key)); print "IP found is: $found_addr\n"; }