Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Unable to save changes using IO::File

by pelp (Initiate)
on Sep 07, 2002 at 01:19 UTC ( #195814=perlquestion: print w/replies, xml ) Need Help??

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

Hi -

The problem is that I'm unable to save my changes after making subsitutions, and I don't understand why.

Here's the code.

#!/usr/vendor/bin/perl use strict; use IO::File my $FRAME_FILE = new IO::File; my $change_on = "FChangeBar Yes"; my $change_off = "FchangeBar No"; $FRAME_FILE -> open("+<test.mif") or die "can't open file"; while (<$FRAME_FILE>) { if (/$change_on/) { s/$change_on/$change_off/g; } } $FRAME_FILE -> close;
After debugging the code myself for a bit, I don't see where the problem could lay.

Thanks ahead!!

Replies are listed 'Best First'.
Re: Unable to save changes using IO::File
by erikharrison (Deacon) on Sep 07, 2002 at 02:08 UTC

    You are opening a file, reading it's contents, and then altering those contents in memory. Your not operating on the file directly nor are you writing the changes back to the file. Solving these problems is left as an exercise to the reader, but your code shows enough competence that I imagine you'll fix it quickly. A suggestion though - if I were in this position, unless the filehandle object needed to stick around for other reasons (or maybe even if it did) I'd prolly use Tie::File. Check it out on the CPAN.

    Cheers,
    Erik

    Light a man a fire, he's warm for a day. Catch a man on fire, and he's warm for the rest of his life. - Terry Pratchet

Re: Unable to save changes using IO::File
by Aristotle (Chancellor) on Sep 07, 2002 at 04:51 UTC
    See erikharrison's post. Just a quick comment from me: your code first tries a match and then a substitution which has to find the same match again. It is ok to try substitution on strings where the match would fail - the result will simply be no change. You can just remove the if:
    while (<$FRAME_FILE>) { s/$change_on/$change_off/g; }
    or simpler s/$change_on/$change_off/g while <$FRAME_FILE>; In fact, you can use substitutions in conditions as well:
    if(s/$change_on/$change_off/) { ... }
    The block will only execute if a substitution happened.

    Makeshifts last the longest.

      To All Helpers:

      Again thanks for all the help. I now saw what I did wrong and have a better understanding of the logic.

      Also, thanks for the recommendation of TIE::FILE. It works great but unfortunately I'm not able to use it in my final program.

      Well happy programming...

(jeffa) Re: Unable to save changes using IO::File
by jeffa (Bishop) on Sep 07, 2002 at 01:31 UTC
    If you want to edit the file in place, just use the -p and -i switches on the command line:
    perl -pi -e 's/(FChangeBar )Yes/$1No/g' test.mif
    That is soooo much easier.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Jeffa-

      Thanks for your reply and help but how can I modify my existing program? The reason being is that the ending program won't be as a simple as I have it. There will be numerous changes throughout.

      Again thanks :-)

        erikharrison is dead on. In order for your existing program to work, you really have to open a temp file, write to it, then clob the first file by moving the temp file over the first file:
        use strict; use IO::File; my $in = IO::File->new; my $out = IO::File->new; my $change_on = "FChangeBar Yes"; my $change_off = "FchangeBar No"; # hmmm, lower case c? $in->open('test.mif') or die "can't read input"; $out->open('>tmp.mif') or die "can't write output"; while (<$in>) { s/$change_on/$change_off/g; print $out $_; } $in->close or die "can't close input"; $out->close or die "can't close output"; rename('tmp.mif','test.mif') or die "can't rename";
        Here is a much cooler version that uses Tie::File:
        use strict; use Tie::File; my @file; tie @file, 'Tie::File', 'test.mif' or die "cannot tie file"; s/(FchangeBar )Yes/$1No/g for @file;
        But, you might not be able to incorporate this into your ending program. At any rate, you are welcome and good luck! :)

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)
        

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2021-04-21 05:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?