Front page | perl.beginners |
Postings from May 2003
Re: Can anyone see where I messed this up?
Thread Previous
|
Thread Next
From:
John W. Krahn
Date:
May 28, 2003 18:39
Subject:
Re: Can anyone see where I messed this up?
Message ID:
3ED564B3.423BE33@acm.org
Chris Zimmerman wrote:
>
> Here's the situation:
>
> I have a program that scans a specially formatted config file and sends files
> to customers by e-mail. Within that file is a field that has
> email@address.com:filename,email@address.com:filename ...
> Each file is sent to the address "attached" to it by a colon and the
> combinations are delimited by a comma.
>
> I have 2 subroutines that run back to back. The first splits the combinations
> at the commas and puts them ultimately into a hash. The second checks for
> the existance of the file, and if it does not exist then it removes if from
> the hash. My problem is that 2 key-value pairs are getting dropped from the
> hash somehow when going from one subroutine to the other.
It sounds like you have duplicate keys.
> When I moved the
> offending combo's to the end of the field in the config file, everything
> worked. There were no syntax problems in the field in the config file, and a
> bunch of print statements in the loops in the first subroutine showed all
> key-value pairs, but in the second there are 2 missing. I hope I have been
> clear enough to explain the problem. Let me know if there is something more
> you would like to see...
All the variables in your subs are global. You should use variables that are lexically
scoped inside the subs.
perldoc perlsub
> Here's the code: (the $multi_flag variable is 1)
>
> sub file_split { # This splits the files up depending if they are separated by a comma or colon
> if ($multi_flag == 0) {
> @files=split(/\,/,$tmpfile);
^^
You don't have to escape the comma, it is not special in a regular expression or a
double quoted string.
@files = split /,/, $tmpfile;
> }
> else {
> @mail_and_files=split(/\,/,$tmpfile);
> $count=$#mail_and_files;
$count is not used anywhere.
> %mail_files=();
> foreach (@mail_and_files) {
> ($f,$m)=split(/\:/);
According to your data (email@address.com:filename,email@address.com:filename)
that should be:
my ( $m, $f ) = split /:/;
> $mail_files{$m}=$f;
> }
You could simplify that as:
%mail_files = split /[,:]/, $tmpfile;
> }
> }
>
> sub see_if_exist { # This removes files from either an array or hash that do not exist
> if ($multi_flag == 0) {
> foreach (@files) {
> if (-s $_) {
> push (@files_exist,$_);
> }
> }
You could simplify that as:
@files_exist = grep -s, @files;
> $count=scalar(@files_exist);
> if ($count == 0) {
You don't need the $count variable, you can test @files_exist directly
if ( @files_exist == 0 ) {
> print LOGFILE scalar(localtime)," No files processed for $cust\n";
You can use the concatenation operator (.) to provide scalar context:
print LOGFILE localtime . " No files processed for $cust\n";
> close LOGFILE;
> die;
> }
> }
> else {
> foreach $key (keys(%mail_files)) {
> if (! (-f $mail_files{$key})) {
> delete $mail_files{$key};
> }
> }
I would probably do it like this: :-)
delete @mail_files{ grep !-f $mail_files{$_}, keys %mail_files };
> unless (keys(%mail_files)) {
> print LOGFILE scalar(localtime)," No files processed for $cust\n";
> close LOGFILE;
> die;
> }
> }
> }
John
--
use Perl;
program
fulfillment
Thread Previous
|
Thread Next