Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

running same bit of code twice

by Anonymous Monk
on May 04, 2003 at 17:19 UTC ( [id://255496]=perlquestion: print w/replies, xml ) Need Help??

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

Peeps

The following bit of code edits the postfix file, and searches for a domain name. I have 2 domains in the file, but in order to edit the the data for the 2 domaisn in the file, i am running the same code twice, is there a better way to do this using loops or better?
my $req_addr = 'bob@domain1.com'; my ( $name, $domain ) = $req_addr =~ /^([\w.-]+)(@[\w.-]+)$/ ; open FH, $datafile or die "Could Not Read Virtual File" ; my @virtual = <FH> ; close FH ; open FH, ">$datafile" or die "Could Not Write Virtual File" ; my $wrote_it = 0 ; for ( @virtual ) { print FH $_ ; if ( $_ =~ /domain1.com/ && !$wrote_it ) { print FH "$req_addr\t$username\n" ; $wrote_it++ ; } } close FH ; my $req_addr = 'bob@domain2.com'; my ( $name, $domain ) = $req_addr =~ /^([\w.-]+)(@[\w.-]+)$/ ; open FH, $datafile or die "Could Not Read Virtual File" ; my @virtual = <FH> ; close FH ; open FH, ">$datafile" or die "Could Not Write Virtual File" ; my $wrote_it = 0 ; for ( @virtual ) { print FH $_ ; if ( $_ =~ /domain2.com/ && !$wrote_it ) { print FH "$req_addr\t$username\n" ; $wrote_it++ ; } } close FH ;

Replies are listed 'Best First'.
Re: running same bit of code twice
by pfaut (Priest) on May 04, 2003 at 17:45 UTC

    I would recommend reading the file in once. Then updating the array by inserting each new entry in it's proper place with splice. When finished inserting all the new entries, write the file out once.

    my @reg_addrs = qw(bob@domain1.com bob@domain2.com); open FH,"<",$datafile or die "Could not read virtual file"; my @virtual = <FH>; close FH; for my $reg_addr (@reg_addrs) { my ($name,$domain) = split /@/,$reg_addr; my ($i) = 0; for my $entry (@virtual) { ++$i; if ($entry =~ /\Q$domain\E/) { splice @virtual,$i,0,"$reg_addr\t$user\n"; last; } } } open FH,">",$datafile or die "Could not write virtual file"; print FH @virtual; close FH;
    90% of every Perl application is already written.
    dragonchild
      Hi pfaut,

      I'm interested in the phrasing of the open command:

      open FH,"<",$datafile or die "Could not read virtual file";
      I habitually use:
      open FH, "$datafile" or die "Can't open $datafile: $!";
      although I'm aware of the  < being an 'open for read only' tag I would use it as follows:
      open FH, "< $datafile" or die "Can't open $datafile: $!";
      I wondered if you would talk me through your use of it and why you might consider it necessary to use   < at all.

      Thanks for your help

        3-arg open is considered more secure than 2-arg open, as perl won't be looking to change it's behavior based upon any special characters (such as < > |) (update: in the filename). Since 3-arg open has no default (you can't leave the second arg undefined), you must explicitly indicate "open for read-only". Finally, some people simply like to be explicit. Why would you write
        foreach my $apple (qw(McIntosh Empire Gala)){ $apple }
        When this would do just fine
        foreach (qw(McIntosh Empire Gala)){ $_ }

        --
        I'm not belgian but I play one on TV.

      Hi
      Thanks for the info. As the bit before the @domainX.com is not going to be static, how would i change it to $username@domain1.com $username@domain2.com? I have tried  my @reg_addrs = qw($username@domain1.com $username@domain2.com); but this simply writes $username@domainX.com to the file and not the contents of $username.
        That's because qw doesn't interpolate variables. So change that line to
        my @reg_addrs = ("$username\@domain1.com", "$username\@domain2.com");
        and you're set.
Re: running same bit of code twice
by chromatic (Archbishop) on May 04, 2003 at 23:29 UTC

    Untested, and I'm not sure about some of the variables.

    use File::Temp 'tempfile'; use File::Copy; use Mail::Address; my $datafile = 'some file'; open( my $fh, $datafile ) or die "Cannot read $datafile: $!\n"; my ($out, $newfile ) = tempfile(); my %addresses = map { my ($user, $domain) = Mail::Address->parse( $_ ); $domain => $user; } 'bob@domain1.com', 'bob@domain2.com'; my $domains = qr( '(' . join('|', map { quotemeta( $_ ) } keys %addresses) . ')' ); while (<$fh>) { print $out $_; print $out "$addresses{ $1 }\@$1\t$addresses{ $1 }\n" if /$domains/; } close( $out ); close( $fh ); move( $newfile, $datafile );

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://255496]
Approved by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-25 14:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found