Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

substitution in $0

by Discipulus (Canon)
on Oct 02, 2002 at 13:04 UTC ( #202246=perlquestion: print w/replies, xml ) Need Help??

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

Hello monks!
maybe this question is dangerous/stupid but I'm in a blind-way..
I wont to modify the source of the script I'm executing refreshing the value of a variable so that next time I run that code smartly.I don't wont to use another file.
open (PROG, ">>$0"); seek (PROG, 0, 0); #not working while (<PROG>) { if ($_=~/$\$data=/){s/\$_/\$data=$new_value;/} } close (PROG);

If I try with this code above the new resulting code is double (the second with a funny shabang). Seek seems not work (if I try, after seek to print "hello", it print it at the end of the file).Maybe my regex is terrible(I had split for now the substitution)..
Some ideas?

greetings lorenzo*

Replies are listed 'Best First'.
Re: substitution in $0
by Abigail-II (Bishop) on Oct 02, 2002 at 13:34 UTC
    How did you manage to double the content without having a print statement? Don't just follow the advice of the people who suggested to use +< in the open. You probably need it, but you need more too. You cannot simply read a line, write a line in a file that you have open for read/write - it will garble your data horribly.

    But since your code fragment doesn't show any print statements, I expect your real code is different anyway.


•Re: substitution in $0
by merlyn (Sage) on Oct 02, 2002 at 15:54 UTC
Re: substitution in $0
by RollyGuy (Chaplain) on Oct 02, 2002 at 13:18 UTC
    I believe that I can provide an answer for why seek isn't happening how you would like it to. You are opening the file in append mode (with the ">>"). In this mode, anything you write will be appended to the original file. There is a lot of information gained by typing perldoc -f open at your nearest command prompt. And from what I see, I think that you need "+<" in front of the $0.

      I agree, testing your code you need to either do as rollyguy has suggested, or it does work doing:
      open (PROG, "+>>$0");
      In running your code withthe + in it, I have found your regexp does not work as well.
      Here is my version, and followed by the output:

      #!/usr/bin/perl use strict; use warnings; my $new_value = 10; my $data=45; open (PROG, "+>>$0"); seek (PROG, 0, 0); #not working while (<PROG>) { s/^(my .data\s*=\s*)\d+(\s*;)/$1.$new_value.$2/e; print; } close (PROG);
      #!/usr/bin/perl use strict; use warnings; my $new_value = 10; my $data=10; open (PROG, "+>>$0"); seek (PROG, 0, 0); #not working while (<PROG>) { s/^(my .data\s*=\s*)\d+(\s*;)/$1.$new_value.$2/e; print; } close (PROG);

      Note: I'm not writing to the file itself, now that I'm thinking about it you probably want to write a temp file, then copy it over....

      Hope this helps!
        Thanks to all you monks for the precious suggestions you gave to me!
        I know my code is still terrible!!
        #!perl use strict; use warnings; &changemyself(); sub changemyself{ my $new_value = 10; my $data=6666666666666; #next time this value will be 10 open (COPIA, ">copia"); open (PROG, "+>>$0"); seek (PROG, 0, 0); #I don't know why but it's NECESSARY! while (<PROG>) { s/^( my .data\s*=\s*)\d+(\s*;)/$1.$new_value.$2/e; print COPIA; } close (PROG); # close (COPIA); # # the terrible imitation # of the open (COPIA, "<copia"); # three cards game open (PROG, ">$0"); # while (<COPIA>){print PROG}# close (PROG); # close (COPIA); # unlink ("copia"); # }
        Special thank to Helter!
        greetings from roma, lor*
        PS I never noticed the +>> operator!!! l*
Re: substitution in $0
by BrowserUk (Patriarch) on Oct 02, 2002 at 16:12 UTC

    I don't really advocate what you are doing, better I think to store your vars in a seperate file and read them in at runtime, but if you insist, you could use Inline::Files, which make what your doing fairly trivial.

    #! perl -sw use strict; use Inline::Files -backup; BEGIN{ $::name1 = <MY_VARS>; chomp($::name1); $::name2 = <MY_VARS>; chomp($::name2); } print "This time I have $::name1, and $::name2\n"; $::name1 = 'frederica'; $::name2 = 'willamina'; END{ open MY_VARS, '>' or die $!; print MY_VARS "$::name1\n$::name2\n"; close MY_VARS; } __MY_VARS__ fred bill __DATA__ C:\test>202246 This time I have fred, and bill C:\test>202246 This time I have frederica, and willamina C:\test>

    Nice things is that the module is tested, proven and has a backup facility (though only one level of backup).

    Also, doing this way you don't have to worry about making changes to your code and then having to modify your regexes, or risk forgetting and totally screwing your code.

    Using the BEGIN and END blocks makes sure it get done at the right time.

    Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
Re: substitution in $0
by fglock (Vicar) on Oct 02, 2002 at 13:13 UTC

    This is a safer way to do it. It will keep a history of modifications, and you can "undo" it using an editor if you want:

    open (ME, ">>$0"); print ME "data\n"; close(ME); __DATA__
seeking in file
by rir (Vicar) on Oct 02, 2002 at 13:29 UTC
    You are opening the file in append mode!
    open (PROG, "+<$filename");

Log In?

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2023-12-04 20:25 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (25 votes). Check out past polls.