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

hi,,,i have just done reading the "Llama book". at last for atleast 12.5% of the current year. it was really fun, a big thanks to the authors. and im moving on to the intermediate stage of learning.

but a few hours ago, something gets into my mind about making a program that i think would be possible. i made the program right away as it stinks into my mind. what i wanted to do is to insert a Perl codes from the users input, then attach an eval so it won't crash my program. then the codes will be inserted into my current program codes that is currently running.

my novice codes as follows:

#!/perl/bin/perl use strict; if (-e "sign.me") { unlink "sign.me"; } else { print "Please enter the Perl codes you want to insert: \n"; my @nEW_cODES_ = <STDIN>; unshift @nEW_cODES_, "eval {\n"; push @nEW_cODES_, "};\n"; push @nEW_cODES_, "print \"An error occured: \$@\" if \$@;\n"; open FILE, "< ".$0; my @rEVISED_cODES_; for (<FILE>) { if ($_ eq "#END\n") { for (@nEW_cODES_) { push @rEVISED_cODES_, $_; } } push @rEVISED_cODES_, $_; } close FILE; open FILE, "> ".$0; for (@rEVISED_cODES_) { print FILE $_; } close FILE; open FILE, "> sign.me"; close FILE; system "perl ".$0; exit; } #START #END print "Hello World!";

program logic:

1. the program queries for a file called sign.me. but let us just leave the details for that as of this moment.

2. lets say you just have ran the program for the first time. normally, the query will fail then the program will ask the user for Perl codes to be appended on the source file of the currently running program. the input is stored to @nEW_cODES_ variable.

3. then an eval will be attached to the @nEW_cODES_ variable to ensure that the inserted codes won't crash my own program (of course, except for syntax errors but lets input a Perl codes with no errors on syntax).

4. then the current program source file is open for reading. inserting those values from the file to the @rEVISED_cODES_ variable. also inserting the values of the @nEW_cODES_ variable to the @rEVISED_cODES_ variable in between the comment lines #START and #END.

5. then the current program source file is open for writing. so it wipes out the codes of the current program source file, then the values of @rEVISED_cODES_ are placed into the source file.

6. the program will create a file signal called sign.me. it is a signal to inform my program that a user input was just appended on my source file of the currently running program.

7. then the program calls the perl interpreter to interpret again my program source file. then, the first program will exit.

8. the second program will now query for the file sign.me. normally, it will find the file signal, then delete it. the deletion of the file is needed so that when you ran the program again it won't ignore another user input to append codes.

9. the program now executes the appended codes in between #START and #END. then the last statement prints hello world. the last statement is just a decorative statement to signify that any other codes after #END still exist and well executed.

a sample of what i inputted was as follows:

print "Enter the First Number: ";

chomp(my $nUM1_ = <STDIN>);

print "Enter the Second Number: ";

chomp(my $nUM2_ = <STDIN>);

print "The Sum of $nUM1_ and $nUM2_ is ",$nUM1_+$nUM2_."\n";

the whole output of the program looks like this:

Please enter the Perl codes you want to insert:

print "Enter the First Number: ";

chomp(my $nUM1_ = <STDIN>);

print "Enter the Second Number: ";

chomp(my $nUM2_ = <STDIN>);

print "The Sum of $nUM1_ and $nUM2_ is ",$nUM1_+$nUM2_."\n";

^Z

Enter the First Number: 1

Enter the Second Number: 2

The Sum of 1 and 2 is 3

Hello World!

NOTE: ^Z is not typed on the keyboard, it is only used to break a multiline input. it is used on the famous blue screen box (Win***s). just press CTRL+Z then press the return key.

overall the program seems to run as a single running program that dynamically embeds perl codes to the same source file of the currently running program.

QUESTION 1: is there any other way around to embed perl codes on the program source file of the currently running program on the fly?

maybe a function that could sneak into the compiled program directly and embedding perl codes from the users input or from a file. this program is actually a faker in a sense that it tends to sway the end user as if it is a single running application.

i understand that once the program is run, the interpreter checks for syntax errors, then compile the program (but not like C). maybe that would meant of a bytecode manipulation isn't it?

QUESTION 2: when Perl interprets the source file where does the compiled program goes? is it to the memory or a temporary directory on my disk?

thanks in advance guys... i hope there is another way around (efficient enough) of embedding Perl codes into the current program source file of the currently running program on a fly that could be executed in a single wave... keep deep and dark! c",))

From: PerlPhi

Replies are listed 'Best First'.
Re: About Embedding Perl Codes on a Current Running Program
by Joost (Canon) on May 15, 2007 at 16:50 UTC
    A couple of answers. Note: I haven't really read all your code, but it seems to be a bit too complicated for what you're trying to achieve. It's a bit hard to tell what you're trying to achieve exactly, though. :-)

    1. You can insert any perl code into the currently running program using "eval STRING". Like this:

    my $code = 'print "stuff\n"'; # in your example this would be read fr +om STDIN. eval $code; # <- eval STRING, not eval { BLOCK } $@ and warn "Found an error: $@";
    Note that truly malicious code can leave your main program in an incomplete state or even force your program to quit. See also Safe and eval.

    Perl doesn't really compile into bytecode, or at least not like Java does. You can currently mess with the compiled code in the interpreter, but it gets complicated fast and there are few reasons to do it.

    2. The compiled code normally stays in memory. If you really want to you can save the interpreter state/bytecode to a file but that's not well supported and all my personal attempts to use it for anything have failed miserably. See perlcc.

    If you want some sort of "binary distribution" (i.e. one executable file instead of perl interpreter and many modules/scripts) take a look at PAR.

    update: fixed link to PAR.