Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Self-Modifying-Perl-Script

by crazyinsomniac (Prior)
on Jul 02, 2000 at 23:22 UTC ( [id://20821]=perlquestion: print w/replies, xml ) Need Help??

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

Hi,

Is there a way to write a self-modifying perl script?

Meaning, I have a perl script, that does something, and it needs to keep track of a counter for example.

Now instead of opening a separate file, that keeps track of the counter, i keep track of it at the end of the perl script that uses it.


Replies are listed 'Best First'.
Re: Self-Modifying-Perl-Script
by chromatic (Archbishop) on Jul 02, 2000 at 23:45 UTC
    You could do this with the __END__ tag. Just keep your number there. Something like the following would work (actually tested and updated, but occasionally I get one right):
    #!/usr/bin/perl -w use strict; chomp(my $num = <DATA>); print "My counter is set to $num.\n"; $num++; { local *FILE; local $/ = "\n__END__"; open (FILE, "counter.pl") || die "Can't open my file for reading: +$!\n"; chomp(my $file = <FILE>); close FILE; open (FILE, ">counter.pl") || die "Can't open file for writing: $! +"; print FILE $file, "\n__END__\n$num"; close FILE; } __END__ 0
    I wouldn't do it this way, though. It's easy to get these wrong and overwrite your program in the blink of an eye, and it's easy to use one of the DBM modules that comes with Perl and get things right. Still, it's good to know some of these techniques.
      Here's something I whipped up for fun:
      #!/usr/bin/env perl -pi.orig use warnings; use strict; BEGIN { @ARGV = $0; while (<>) { do { print; last; } if /^__DATA__$/; } continue { print; } } tr/A-Z/N-ZA-M/; tr/a-z/n-za-m/; __DATA__ Guvf vf n cebtenz gung zbqvsvrf vgfrys va cynpr. Vg ebg13 rapbqrf vgf bja __QNGN__ frpgvba jura lbh eha vg. Nalguvat orsber gur __QNGN__ frpgvba vf yrsg hazbqvsvrq. Lbh jvyy frr gur sbyybjvat qvntabfgvp reebe, juvpu lbh pna vtaber: -v hfrq jvgu ab svyranzrf ba gur pbzznaq yvar, ernqvat sebz FGQVA.
Re: Self-Modifying-Perl-Script
by c-era (Curate) on Jul 03, 2000 at 16:28 UTC
    Put your code in a variable and eval it.
    $end = 0; $var = 1; $code='print "test $code"; $end = 1 if ($var >= 2); $var++; eval ($code) if ($end == 0);'; eval($code);
    This will let you modify your code (I didn't modify mine, but it gives you an idea of how to do it).
    PS. Opening a file is much safer, easier, and better coding practice.
RE: Self-Modifying-Perl-Script
by BigJoe (Curate) on Jul 03, 2000 at 03:27 UTC
    I my self have thaught of doing this too. I really don't like opening up more files than I have too. I have been trying to weigh out the pros and cons of have a separate config file for some of my scripts rather than have the configuration at the top of my script.

    But I have always been to timid of this because of like what chromatic said about deleted out your whole script.

    --BigJoe
      for what it's worth, i can not conceive, other than as a test scenario, for a reason to make a script self modifying in such a manner. Look at the program's design from a logical standpoint. If it makes sense for an external file to contain your configuration information, or your test data, or something NOT internal to the logic of your code, then put it an external file! Remeber, we want to make our code as readable and accessible to people other than ourselves. Anyone who ever has to look at your code somday down the road will thank you for it. Let's make sure that this isn't a case of us being too clever for our own good!
Re: Self-Modifying-Perl-Script
by Anonymous Monk on Jan 28, 2010 at 01:38 UTC
    In essence it would look like this:
    #!/usr/bin/perl # lives tracks the number of times the program has run. # the line number is stored for later use in an array # called @program, so if consensual hackers decide to # rearrange, the program can still find the variable. $lives = 0; $line{lives} = (__LINE__ - 1); # The source code of the file is read into @program open( THIS, "$0" ); @program = <THIS>; close( THIS ); # The line number from earlier points at the line of code # storing the variable '$lives'. # Render the line and store it back into @program over the # old line of code. $program[ $line{lives} ] = '$lives = ' . ($lives+1) . '; $line{lives} = (__LINE__ - 1);' . "\n"; # Output the program's slightly modified source # code over the old file. open( THIS, ">$0" ); print THIS @program; close( THIS ); # Clear the screen buffer and 'exec' the modified source. system( 'clear' ); exec( $0 ); # exec() does not return to this program. print "This does not get displayed.";
    abatek~

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-04-19 17:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found