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

Hello. I have heard that it is possible from within a perl program to compile a string to perl bytecode once, and then execute that bytecode afterwards without incurring the expense of compiling it every time. Does anyone know how one would go about this?
With humble thanks,
-Chris
--
They laughed at Einstein. They laughed at the Wright Brothers. But they also laughed at Bozo the Clown. - Carl Sagan
  • Comment on Storing the bytecode compiled with eval()

Replies are listed 'Best First'.
Re: Storing the bytecode compiled with eval()
by ZZamboni (Curate) on Apr 30, 2001 at 19:47 UTC
    You could define it as an anonymous subroutine and store it in a code ref:
    $subref=eval 'sub { your code here }' die $@ if $@; ...
    And then call it any time you want as:
    $subref->();
    or define it like a normal subroutine:
    eval 'sub mysub { your code here }'; die $@ if $@;
    And then call it with:
    mysub();

    --ZZamboni

Re: Storing the bytecode compiled with eval()
by chromatic (Archbishop) on Apr 30, 2001 at 19:49 UTC
    That depends on what you mean by 'compile once'. If you mean, once per invocation of the program, it's not too terribly difficult to do. Simply build a text string that can be read as valid Perl code containing an anonymous subroutine:
    my $sub <<SUB; sub { print "I've been compiled once! I'm anonymous!\n"; } SUB my $sub_ref = eval $sub;
    This is off the top of my head, so you may have to play around with it slightly.

    If you're looking for a way to compile a string once and have that persist across invocations of the program, you'll have to look into something like B::Bytecode, which is experimental and may not gain you very much.

    Other options include normal anonymous subroutines and closures. There's probably a way to get around most specific problems there, but knowing how to eval an anonymous subroutine into existence can occasionally come in handy.

Re: Storing the bytecode compiled with eval()
by Dominus (Parson) on Apr 30, 2001 at 22:06 UTC
    Use
    perl -MO=Bytecode yourprogram.pl > yourprogram.bcp
    To compile. (use perldoc B::Bytecode for more information about this.) Use the bytecode.pl program that comes with Perl to re-run the bytecode.

    Note that this is all "experimental", which in this case probably means "does not work".

    --
    Mark Dominus
    Perl Paraphernalia

(Ovid - closures?) Re: Storing the bytecode compiled with eval()
by Ovid (Cardinal) on Apr 30, 2001 at 20:16 UTC

    Can you give us a more specific example of what you are trying to do? The closest thing that I can think of, from what you're describing, is to use AUTOLOAD to autogenerate a subroutine and install it in the symbol table to avoid the repeated expense of regenerating the code. I have an example of that here.

    If what you're trying to do is use a closure, merlyn has an article on closures that you may wish to read.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.