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

    I know this is a long shot, but is it possible to create another interpreter instance within an already running perl script? I'm guesssing you could do this by writing some C code (be it XS or Inline) to interface with a PerlInterpreter instance, but I haven't got that far yet ;-)
    The reason I ask is that I'm writing/about to write a not entirely useful module (for my own educational purposes mainly) which would extract subs from a perl source (probably files at this point) and import them into the current package (see. *not* packages + use). I figured parsing would be out of the question, so I thought I'd just walk the optree using the B module turning on the minus_c() switch to stop the running of the perl program. But that then stops the running of the current program to, thus leading me to ponderance of creating a new interpreter instance.
    I'm not sure if this is possible (or even within the realms of sanity), so any help/advice/suggestions would be very much appreciated!

broquaint

  • Comment on Can you create another perl interpreter within the current script?

Replies are listed 'Best First'.
Re: Can you create another perl interpreter within the current script?
by Juerd (Abbot) on Mar 04, 2002 at 20:02 UTC
Re: Can you create another perl interpreter within the current script?
by perrin (Chancellor) on Mar 04, 2002 at 20:03 UTC
    Huh? Import the subs from another package? Just walk the package's symbol table and do some junk with typeglobs. No magic required. Or are you trying to do something fancier than that?
      I guess he wants to import some subs without loading whole package. Sounds like a very crazy idea.

      One possible solution is creation of separate process so it can compile that package without execution. See source code of package O to find how to do it. B::Deparse can be used to obtain source code of those subs.

      --
      Ilya Martynov (http://martynov.org/)

        > Sounds like a very crazy idea.
        It is >:-)

        > B::Deparse can be used to obtain source code of those subs.
        That's close to what I want, and is probably going to be the most practical. I get the feeling I can't compile the optree and then selectively stop execution in the same script. I could just wait til TheDamian has the time to create and finish Parse::Perl ... hmmm.
        Thanks for the input IlyaM!

        broquaint

Re: Can you create another perl interpreter within the current script?
by Sinister (Friar) on Mar 04, 2002 at 22:38 UTC
    Took me a little while, cause I am no closures and eval hero, but here is the trick...

    This is the script holding your routines:
    sub hello { return "Hello"; } sub world { return "world!"; } sub foo_bar { my ($foo, $bar) = @_; print "$foo $bar\n"; }

    And this is the interpreter.
    use strict; # Try to load code from a different perl script. Put it in a closure # and run run run... my $load_file = $ARGV[0]; # $flags my $in = 0; my @subs = (); my %routines = (); my %sub = (); open(IN, "<$load_file"); while (<IN>) { if ( /sub (\w+) \{/ ) { # hey! A routine has begun... $in = 1; push @subs,$1; $routines{$1} = ""; } if ( $in == 1 ) { if ( /\}/ ) { # sub ends. $in = 0; } else { s/^\s+//g; $routines{$subs[$#subs]} .= $_ unless /sub/; } } } close(IN); # mmm - we now have the internals of the routines in core. # let's see what we can do with them. print "You have these subs:\n"; foreach my $subs (keys %routines) { eval("\$sub{$subs} = sub { " . $routines{$subs} . " };"); print "\$sub{$subs} = sub { " . $routines{$subs} . " };\n" } $sub{'foo_bar'}->($sub{'hello'}->(), $sub{'world'}->()),"\n";


    To be honest with you - I am kind of proud of myself *blush blush*

    A righthanded-lefthand....
    "Field experience is something you don't get until just after you need it."
Re: Can you create another perl interpreter within the current script?
by Anonymous Monk on Mar 04, 2002 at 21:05 UTC
    Sure ... stuff this in your pipe and smoke it! pun intended
    #!/usr/bin/perl -w use strict; print "I wonder what will happen?\n"; open ME, "$0|" or die "Cannot do $o:$!\n"; while(<ME>) {print;} close ME;