newbie01 perl wrote:
Hi all especially Perl teachers if anyone is ... :-)

I just want to know if someone can provide some explanation on how does the
argument iterator sub-routine below work. The Perl script is called from a
UNIX Korn script as below:

mail_smtp.pl -r ${MAILFROM} -s "$subject_line TEST EMAIL"
supportm...@test.com<  /tmp/test_email.txt

The Perl script is working and SMTP mail is working. Am just trying to
understand how the getval sub-routine is parsing the command line arguments.
the getval subroutine is as below.

=================================================================

sub getval {
         my $refVal = '';
         foreach $var(@ARGV) {
                 if ($refVal ne '') {
                         $$refVal = $var;
                         $refVal = '';
                 }
                 else {
                         $_ = $var;
                         if (/-r/ ) {
                                 $refVal=\$fromUser;
                         }
                         elsif (/-f/) {
                                 $refVal=\$dataFile;
                         }
                         elsif (/-s/) {
                                 $refVal=\$subject;
                         }
                         else {
                                 @toUser = split(/[\;,]/,$var);
                         }

                 }
         }
}

=================================================================

The portion that am confused at is at the following lines:

$$refVal = $var;

and

$_ = $var;
if (/-r/ ) {
         $refVal=\$fromUser;
}

When @ARGV is at the '-r' element the $refVal=\$fromUser assigns a reference from $fromUser to the variable $refVal and then the next time through the loop when @ARGV is the element just past '-r' $fromUser is dereferenced through $$refVal and is assigned the current element of @ARGV.

You are probably better off just using Getopt::Std


Does "if (/-r/ )" means "ignore" all command line that begins with a hyphen
but reference by value the next command line argument after them?

In this case "if (/-r/ )" is just short for "if ($var =~ /-r/ )" but for some "cute" reason the programmer decided to use $_ instead of $var.

Also, /-r/ matches the string '-r' *anywhere* in $_, not just at the beginning. It would more properly be written as "if (/\A-r\z/ )" or even "if ( $_ eq '-r' )".


Does $_ contains the following values on each iteration?

mail_smtp.pl
-r
${MAILFROM}
-s
"$subject_line TEST EMAIL"
supportm...@test.com
<
/tmp/test_email.txt

Any "explanation" on this will be very much appreciated. Am going nuts
trying to understand how the iteration functions although am glad it is
functioning.

Thanks in advance.


===============================
mail_smtp.pl source code below:
===============================

#!/usr/bin/perl -w

use warnings;
use strict;

use Net::SMTP;
use FileHandle;


# global variables
my $fromUser = $ENV{USER};
my @toUser = {};

This is assigning a hash reference to the first element of @toUser which makes little sense.


my $smtpSvr = '192.168.3.11';
my $subject = '';
my $dataFile = '';
#$mailBody = '';
sub getval {
         my $refVal = '';
         foreach $var(@ARGV) {
                 if ($refVal ne '') {
                         $$refVal = $var;
                         $refVal = '';
                 }
                 else {
                         $_ = $var;
                         if (/-r/ ) {
                                 $refVal=\$fromUser;
                         }
                         elsif (/-f/) {
                                 $refVal=\$dataFile;
                         }
                         elsif (/-s/) {
                                 $refVal=\$subject;
                         }
                         else {
                                 @toUser = split(/[\;,]/,$var);
                         }

                 }
         }
}

# main
getval(@ARGV);

This is passing the array @ARGV to the @_ array inside the subroutine but you don't use the @_ array inside the subroutine so why do it?


if (@toUser ne {}) {

That statement is useless and doesn't do what the programmer seems to think it is doing. An array in scalar context will return the number of elements in the array, which at this point is 1. So '1' will be compared to the textual representation of an anonymous hash which is something like 'HASH(0x9ec8818)' and the two will *never* be equal.

Even if the programmer just compared the first element of @toUser to an anonymous hash they would *never* be equal.

What the programmer should have done is define the array without any elements:

my @toUser;

And then test the array is scalar context to see if getval() populated the array:

if ( @toUser ) {


         if ($dataFile eq '') {
                 $dataFile = '-';
         }
         open(my $inFile, "<  $dataFile");

You should *always* verify that the file was opened correctly before using its filehandle.


         $smtp = Net::SMTP->new($smtpSvr);
         $smtp->mail($fromUser);
         $smtp->to(@toUser);
         $smtp->data();
         $smtp->datasend("From:$fromUser\n");
         $smtp->datasend("To:".join(';',@toUser)."\n");
         if ($subject ne '') {
                 $smtp->datasend("Subject:$subject\n");
         }
         while (<$inFile>) {
                 if (/^\.$/) {
                         last;
                 }
                 else {
                     $smtp->datasend($_);
                 }

         }
         close($inFile);
         $smtp->dataend();
         $smtp->quit;
}



John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction.                   -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to