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

I have this error: Undefined subroutine &main::savemail called at skrypt.pl line 36, <FD> line 2.

Can anyone help me? What i do wrong?

My code:

use strict; my $mails = @ARGV[0]; my $username; my $password; my $domena; my $i=0; my $p_wp = "wp.txt"; my $p_interia = "interia.txt"; my $p_onet = "onet.txt"; my $p_gmail = "gmail.txt"; my $p_inne = "inne.txt"; open(FD, $mails) or die "Nie moge otworzyc pierwszego pliku"; while(<FD>) { $_ =~ m/([^:]*):(\S*)/; $username = $1; $password = $2; &checkdomain($username); } sub checkdomain { my $login = shift(@_); if($login =~ m/^([^@]+)@(wp\.pl|WP\.PL)/i) { $domena = "wp.txt"; &savemail($domena,$username,$password); } elsif($login =~ m/^([^@]+)@(onet\.pl|ONET\.PL|onet\.eu|ONET\.EU +|vp\.pl|VP\.PL|OP\.PL|op\.pl|spoko\.pl|poczta\.onet\.pl|vip\.onet\.pl +|autograf\.pl|onet\.com\.pl|opoczta\.pl|buziaczek\.pl|amorki\.pl|buzi +aczki.onet.pl|poczta.onet.eu)/i) { $domena = "onet.txt"; &savemail($domena,$username,$password); } elsif($login =~ m/^([^@]+)@(interia\.pl|poczta\.fm|interia\.eu| +INTERIA\.EU|INTERIA\.PL|POCZTA\.FM)/i) { $domena = "interia.txt"; &savemail($domena,$username,$password); } elsif($login =~ m/^([^@]+)@(o2\.pl|O2\.PL|tlen\.pl|TLEN\.PL|pro +konto\.pl)/i) { $domena = "o2.txt"; &savemail($domena,$username,$password); } elsif($login =~ m/^([^@]+)@(poczta\.pl)/i) { $domena = "poczta.txt"; &savemail($domena,$username,$password); } elsif($login =~ m/^([^@]+)@(1gb\.pl|2gb\.pl|serwus\.pl|vip\.int +eria\.pl|akcja\.pl|czateria\.pl)/i) { $domena = "interia.txt"; &savemail($domena,$username,$password); } elsif($login =~ m/^([^@]+)@(gmail\.com)/i) { $domena = "gmail.txt"; &savemail($domena,$username,$password); }}

Replies are listed 'Best First'.
Re: Undefined subroutine &main::savemail called at skrypt.pl line 36, <FD> line 2.
by 1nickt (Canon) on Apr 16, 2017 at 16:56 UTC

    As the Anonymous One pointed out, the code you showed lacks a subroutine called savemail. Is that code you wrote, or are you trying to use a function from some library? In that case you'll have to load the other library with require or use and import the function(s) you want to use. For a hypothetical example:

    use strict; use warnings; use Other::Library qw/ savemail /; ...

    On a side note:

    { $_ =~ m/([^:]*):(\S*)/; $username = $1; $password = $2; &checkdomain($username); }
    This would be better written with split:
    open my $FH, '<', $mails or die "Nie moge otworzyc pierwszego pliku"; while ( <$FH> ) { chomp; my ($username, $password) = split /:\s*/; checkdomain($username); }
    • No point in launching the regular expression engine if you don't need to. split() is way faster (although it does add the need to chomp the newline characters from the end of each line, as you can see).
    • Also note the use of the three-argument form of open for opening a filehandle, which is safer.
    • Finally, note that subroutines can and should be called without the &, unless there exists one of a small set of specific reasons to use it.

    You might also want to see about getting rid of that tree of conditional elsifs, using a small library in your script to look up the values for $domena. There are many ways to do this; one solution would be to compile the regular expressions and use them as the keys of a look-up table in a hash.

    Hope this helps!


    The way forward always starts with a minimal test.
Re: Undefined subroutine &main::savemail called at skrypt.pl line 36, <FD> line 2.
by Anonymous Monk on Apr 16, 2017 at 16:02 UTC

    Hello wz34az,

    The script is missing the savemail function.

    sub savemail { ... }