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

I am using the following code to get each email address from a list of email addresses and sets of info to send to each address.

ie @emails contains:
firstemailaddress@com secondemailaddress@com
and @requests contains:
first lot of info ------------------------------------------ second lot of info ------------------------------------------
But with the code, the emails get sent out, but each one contains the first set of info. The problem seems to be that @requests resets to the start of the array in each foreach $email loop. Is there any way to stop it resetting but rather carrying on from where it left off?
foreach $email (@emails) { open(MAIL,"|$mailprog -t"); print MAIL "To: $email"; print MAIL "From: $myemail\n"; print MAIL "Subject: test\n\n"; LINE: foreach $requests (@requests) { until ($requests =~ "----------------------------------------- +----------------------------") { print MAIL "$requests"; next LINE; } close (MAIL); } }

Replies are listed 'Best First'.
Re: foreach returning to start of array
by Juerd (Abbot) on Apr 02, 2002 at 10:48 UTC

    Is there any way to stop it resetting but rather carrying on from where it left off?

    No, but you could use your own iterator veriable, or unshift from @requests.

    If $mailprog is sendmail, you might also want -oi (put the parameters in the variable anyhow)

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

Re: foreach returning to start of array
by Mask (Pilgrim) on Apr 02, 2002 at 12:12 UTC
    Why don't you use hash for this? You can keep all your info in the string and as a key for hash you can have an e-mail address. It will be much easier.
Re: foreach returning to start of array
by mrbbking (Hermit) on Apr 02, 2002 at 13:01 UTC
    The problem is that foreach doesn't set any kind of iterator (that I know of, anyhow) - it just knows where it is in the array, and knows how to get to the next element in it.

    If you want to use the for syntax, though, and you know your arrays have the same number of elements, and that they're in the correct order, you can use something like this:

    #!/usr/bin/perl -w use strict; my $myemail = qw( chrisbarton@perlmonks.com ); my @emails = qw( firstemailaddress@com secondemailaddress@com); my @requests = ( "first lot of info\n------------------------------------------\n", "second lot of info\n------------------------------------------\n" ); for( my $i=0; $i<= $#emails; $i++ ){ print "To: $emails[$i]\n"; print "From: $myemail\n"; print "Subject: test\n\n"; print $requests[$i]; }
    Mask's suggestion, though saves you the trouble of keeping your arrays synchronized, and keeps your code more Perlish:
    #!/usr/bin/perl -w use strict; my $myemail = qw( chrisbarton@perlmonks.com ); my %requests = ( 'firstemailaddress@com' => "first lot of info\n------------------------------------------\n", 'secondemailaddress@com' => "second lot of info\n------------------------------------------\n" ); foreach my $email (keys %requests) { print "To: $email\n"; print "From: $myemail\n"; print "Subject: test\n\n"; print $requests{$email}; }
Re: foreach returning to start of array
by particle (Vicar) on Apr 02, 2002 at 13:28 UTC
    expanding on mrbbking's second example, you can build the hash as follows:
    my @emails = qw( firstemailaddress@com secondemailaddress@com); my @requests = ( "first lot of info\n------------------------------------------\n", "second lot of info\n------------------------------------------\n" ); # build a hash, mapping email addresses to text my %address_to_text; @address_to_text{@emails} = @requests;
    then use it as directed in his example.

    ~Particle ;Þ

Re: foreach returning to start of array
by petral (Curate) on Apr 02, 2002 at 14:53 UTC
    Good suggestions, but in direct answer to your question: use ` unless ' instead of ` until '.

        p
Re: foreach returning to start of array
by perlplexer (Hermit) on Apr 02, 2002 at 15:37 UTC
    foreach my $email (@emails) { open MAIL, "|blah" or die "Can't fork : $!"; print MAIL "To: $email\nFrom: $myemail\nSubject: test\n\n"; while(@requests){ my $r = shift @requests; last if $r eq "-----\n"; print MAIL $r; } close MAIL or die "Broken pipe : $!"; last unless @requests; }

    --perlplexer
Re: foreach returning to start of array
by dragonchild (Archbishop) on Apr 02, 2002 at 16:24 UTC
    Actually, that is what you're doing - restarting the the looping through the @requests array. Every time a foreach is encountered, it starts at the beginning of the array.

    Solution - associate the data within each email with the address it's supposed to go to. (Hashes are associative arrays, in case you're wondering.)

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.