Help -- how to execute "computed Perl code"

Discussion in 'Perl Misc' started by Steve D, Sep 2, 2003.

  1. Steve D

    Steve D Guest

    My code dynamically creates a scalar with a text string that is a
    valid Perl code line.

    How can I get Perl to execute the line contained in that scalar?

    I could write it to a temp file and then "do <file>", but I want to
    avoid that overhead. It does not seem eval and "do BLOCK" are the
    answer.

    Any good solutions?

    Regards,
    Steve D

    Basic idea:

    $x = "Send A message 13 ;" ;
    # how can I execute $x to call (defined in a different module) the
    subroutine:
    # Send ($;@) {...}

    Just putting
    Send A message 13 ;
    at the point of interest does run "Send", so visibility is not a
    problem, at least at that point.
    Steve D, Sep 2, 2003
    #1
    1. Advertising

  2. On 1 Sep 2003 18:41:31 -0700
    (Steve D) wrote:

    > My code dynamically creates a scalar with a text string that is a
    > valid Perl code line.
    >
    > How can I get Perl to execute the line contained in that scalar?
    >
    > I could write it to a temp file and then "do <file>", but I want to
    > avoid that overhead. It does not seem eval and "do BLOCK" are the
    > answer.
    >
    > Any good solutions?


    Not sure if this i what you're looking for or not:

    ==untested==
    #!/usr/bin/perl -w
    use strict;
    #create a reference to a subroutine
    #execute the system command 'ls' (Windows, it would be 'dir')
    my $code = sub { system("ls") };
    #call to the subroutine
    $code->();
    ==untested==

    You can apply this idea to whatever it is that you're doing.

    HTH
    Jim
    ---
    Copyright notice: all code written by the author in this post is
    considered GPL. http://gnu.org for more information.
    ---
    a real quote ...
    Linus Torvalids: "They are somking crack ...."
    (http://www.eweek.com/article2/0,3959,1227150,00.asp)
    ---
    a fortune quote ...
    Surprise your boss. Get to work on time.
    James Willmore, Sep 2, 2003
    #2
    1. Advertising

  3. On Tue, 02 Sep 2003 02:54:28 GMT
    James Willmore <> wrote:
    > On 1 Sep 2003 18:41:31 -0700
    > (Steve D) wrote:
    > > My code dynamically creates a scalar with a text string that is a
    > > valid Perl code line.
    > > How can I get Perl to execute the line contained in that scalar?
    > > I could write it to a temp file and then "do <file>", but I want
    > > to avoid that overhead. It does not seem eval and "do BLOCK" are
    > > the answer.
    > > Any good solutions?

    >
    > Not sure if this i what you're looking for or not:
    >
    > ==untested==
    > #!/usr/bin/perl -w
    > use strict;
    > #create a reference to a subroutine
    > #execute the system command 'ls' (Windows, it would be 'dir')
    > my $code = sub { system("ls") };
    > #call to the subroutine
    > $code->();
    > ==untested==
    >
    > You can apply this idea to whatever it is that you're doing.


    After I posted, I got to thinking (uh-oh). If you want to see other
    examples of what I posted, take a look at the CGI module. Most, if
    not all, the code is done the way you (I think) would like to do.

    HTH
    --
    Jim
    ---
    Copyright notice: all code written by the author in this post is
    released under the GPL. http://www.gnu.org/licenses/gpl.txt
    for more information.
    ---
    a real quote ...
    Linus Torvalids: "They are somking crack ...."
    (http://www.eweek.com/article2/0,3959,1227150,00.asp)
    ---
    a fortune quote ...
    Too often I find that the volume of paper expands to fill the
    available briefcases. -- Governor Jerry Brown
    James Willmore, Sep 2, 2003
    #3
  4. Steve D

    Anno Siegel Guest

    Steve D <> wrote in comp.lang.perl.misc:
    > My code dynamically creates a scalar with a text string that is a
    > valid Perl code line.
    >
    > How can I get Perl to execute the line contained in that scalar?
    >
    > I could write it to a temp file and then "do <file>", but I want to
    > avoid that overhead. It does not seem eval and "do BLOCK" are the
    > answer.


    "eval" is the answer, in the string-eval form. What have you tried?

    Anno
    Anno Siegel, Sep 2, 2003
    #4
  5. (Steve D) writes:

    > My code dynamically creates a scalar with a text string that is a
    > valid Perl code line.


    This is a powerful technique but one that should only be used in very
    special circumstances.

    Unlike some of the regulars here I'm not gripped by a rabid fear of
    this technique, indeed I embrace it. But before you use it you must
    understand how parsing data as code can easily produce obscure hidden
    bugs or security holes.

    > How can I get Perl to execute the line contained in that scalar?
    >
    > It does not seem eval [is] the answer.


    Why? (Oh and don't forget #line)

    > Any good solutions?


    Dunno. The solution you have rejected (for no apparent reason) is the
    solution to your "Y" but there's a fairly good chance it's not a good
    solution to your "X"[1].

    Since you do not tell us anything about your "X" we can't advise on a
    good solution.

    [1] An "XY" problem is where you want to do "X" but ask "How do I do
    Y?" because you think that doing "Y" is part of doing "X" but actually
    doing "Y" is something more complex/riskly/whatever than the direct
    solution to doing "X".

    --
    \\ ( )
    . _\\__[oo
    .__/ \\ /\@
    . l___\\
    # ll l\\
    ###LL LL\\
    Brian McCauley, Sep 2, 2003
    #5
  6. Steve D

    Steve D Guest

    James Willmore <> wrote in message news:<>...
    > On Tue, 02 Sep 2003 02:54:28 GMT


    NOPE. Your "solution" requires the code text to be known at COMPILE
    time.

    I need to compile code text that has been create at RUN time. The
    following is a complete program example of what I want to do (the
    @code_text is just a simple way to define strings -- in reality they
    are composed from much more complex circumstances).

    As I said, I *could* write @code_text to a file, then "do <file>" to
    get the effect I need, but want to avoid writing and reading a file
    just to get evaluation of the code.

    Regards,
    Steve

    #! /bin/perl
    use strict ; use warnings ;

    my $a = 1 ;
    my @code_text = ( '$a += 3 ;', '$a /= 2 ;', 'print $a ; ' ) ;

    for my $code_text ( @code_text ) {
    my $code = sub { $code_text } ;
    print "$code_text\n" ;
    # DOES NOT WORK
    # I want to evaluate the "code" contained in $code_text
    # NOT the "value" of $code_text. $a should get 3 added,
    # then be divided by 2, and then printed.
    $code->() ;
    } ;

    print "$a should be 2 ( 1 plus 3 divided by 2 )\n"
    Steve D, Sep 2, 2003
    #6
  7. Steve D

    Steve D Guest

    James Willmore <> wrote in message news:<>...
    > On Tue, 02 Sep 2003 02:54:28 GMT
    > James Willmore <> wrote:
    > > On 1 Sep 2003 18:41:31 -0700
    > > (Steve D) wrote:
    > > > My code dynamically creates a scalar with a text string that is a
    > > > valid Perl code line.


    James,
    Your code gave me some ideas. Some more experimentation did finally
    come up with a solution:

    #! /bin/perl
    use strict ; use warnings ;

    my $a = 1 ;
    my @code_text = ( '$a += 3 ;', '$a /= 2 ;', 'print "$a\n" ; ' ) ;

    for my $code_text ( @code_text ) {
    my $code = sub { eval "$code_text" } ; # Just need eval to make it
    work
    print "Executing $code_text\n" ;
    $code->() ;
    } ;

    print "$a should be 2 ( 1 plus 3 divided by 2 )\n"

    =================================
    The eval in the sub def is the key. I had tried a do of an eval, an
    eval of an eval, but never a sub of an eval. That's the key.

    Thanks for your help.

    Regards,
    Steve
    Steve D, Sep 2, 2003
    #7
  8. Steve D

    Sam Holden Guest

    On 2 Sep 2003 05:03:27 -0700, Steve D <> wrote:
    [snippage]

    > # I want to evaluate the "code" contained in $code_text

    ^^^^
    And that is what you should do...

    (and make sure you understand the risks associated with executing
    arbitrary code).

    --
    Sam Holden
    Sam Holden, Sep 2, 2003
    #8
  9. Steve D

    Simon Taylor Guest

    Steve D wrote:
    > My code dynamically creates a scalar with a text string that is a
    > valid Perl code line.
    >
    > How can I get Perl to execute the line contained in that scalar?
    >
    > I could write it to a temp file and then "do <file>", but I want to
    > avoid that overhead. It does not seem eval and "do BLOCK" are the
    > answer.
    >
    > Any good solutions?


    I won't elaborate on the answers in this thread to date, but simply
    mention the 'Safe' module. I've found it to be very handy in some
    circumstances when you want to execute arbitrary (dynamically created) code.

    It allows you to run code in a reasonably safe 'compartment'.

    Regards,

    Simon Taylor
    Simon Taylor, Sep 2, 2003
    #9
  10. Steve D

    Uri Guttman Guest

    >>>>> "BM" == Brian McCauley <> writes:

    BM> Unlike some of the regulars here I'm not gripped by a rabid fear of
    BM> this technique, indeed I embrace it. But before you use it you must
    BM> understand how parsing data as code can easily produce obscure hidden
    BM> bugs or security holes.

    then you misunderstand why we always say it is evil. i have used string
    eval but only as a last resort or where is provides a distinct
    advantage. most newbies hear about it and start to use it for every nail
    they see when they can usually use perl structures or other concepts
    instead of eval. so the mantra here is don't use it (unless you know why
    you are using it).

    in this thread i still have no clear understanding of the problem
    itself, let alone why eval is needed or even better, why it didn't work
    at all.

    BM> Dunno. The solution you have rejected (for no apparent reason) is the
    BM> solution to your "Y" but there's a fairly good chance it's not a good
    BM> solution to your "X"[1].

    i smell XY problem as well. poorly articulated problems with eval as a
    potential (and rejected!) solution reeks of XY.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Damian Conway Class in Boston - Sept 2003 -- http://www.stemsystems.com/class
    Uri Guttman, Sep 2, 2003
    #10
  11. Steve D

    Uri Guttman Guest

    >>>>> "SD" == Steve D <> writes:

    SD> my $a = 1 ;
    SD> my @code_text = ( '$a += 3 ;', '$a /= 2 ;', 'print $a ; ' ) ;

    XY all the way.

    use a dispatch table. search google for examples with that very
    phrase. it crops up every month here. eval is the wrong way to solve it
    (and eval would work if you did it correctly. i won't help there since
    it is the wrong path for you).

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Damian Conway Class in Boston - Sept 2003 -- http://www.stemsystems.com/class
    Uri Guttman, Sep 2, 2003
    #11
  12. Steve D

    Uri Guttman Guest

    >>>>> "SD" == Steve D <> writes:

    SD> my $a = 1 ;
    SD> my @code_text = ( '$a += 3 ;', '$a /= 2 ;', 'print "$a\n" ; ' ) ;

    SD> for my $code_text ( @code_text ) {
    SD> my $code = sub { eval "$code_text" } ; # Just need eval to make it
    SD> work

    GACK! that is fugly. use a dispatch table already. you are jumping
    through 3 hoops for no reason.

    SD> print "Executing $code_text\n" ;
    SD> $code->() ;
    SD> } ;

    you are making closures (and don't even realize it), calling eval in the
    wrong place (even as eval is not needed)

    SD> The eval in the sub def is the key. I had tried a do of an eval, an
    SD> eval of an eval, but never a sub of an eval. That's the key.

    no it is not the key.

    use a dispatch table.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Damian Conway Class in Boston - Sept 2003 -- http://www.stemsystems.com/class
    Uri Guttman, Sep 2, 2003
    #12
  13. Steve D

    Bart Lateur Guest

    Steve D wrote:

    >My code dynamically creates a scalar with a text string that is a
    >valid Perl code line.
    >
    >How can I get Perl to execute the line contained in that scalar?
    >
    >I could write it to a temp file and then "do <file>", but I want to
    >avoid that overhead. It does not seem eval and "do BLOCK" are the
    >answer.


    "eval" it is.

    $string = 'print 3+3;';
    print "Let's do it:\n";
    eval $string;

    Saving it to a temp file and then run "do $file;" would indeed do pretty
    much the same.

    --
    Bart.
    Bart Lateur, Sep 2, 2003
    #13
  14. (Steve D) writes:

    > my $code = sub { eval "$code_text" } ; # Just need eval to make it


    > $code->() ;


    That is pointless.

    May as well just:

    eval $code_text;

    I suspect what you were tring to do was:

    my $code = eval "sub { $code_text }";

    Apply standard admionishments about being damn sure that $code_text
    can never contain any text from any source that would not be trusted
    to run their own scripts under the current user ID.

    --
    \\ ( )
    . _\\__[oo
    .__/ \\ /\@
    . l___\\
    # ll l\\
    ###LL LL\\
    Brian McCauley, Sep 2, 2003
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jeff Thur
    Replies:
    2
    Views:
    1,031
    Guest
    Feb 7, 2005
  2. frog
    Replies:
    4
    Views:
    712
    =?Utf-8?B?V2lsbA==?=
    May 18, 2005
  3. William Gill

    help with mysql cursor.execute()

    William Gill, Aug 14, 2005, in forum: Python
    Replies:
    7
    Views:
    613
    Dennis Lee Bieber
    Aug 16, 2005
  4. Fransis il Mulo

    [HELP] Global.asax doen't execute OnBeginRequest

    Fransis il Mulo, Feb 26, 2008, in forum: ASP .Net
    Replies:
    3
    Views:
    1,421
    Fransis il Mulo
    Feb 27, 2008
  5. Savas Ates
    Replies:
    1
    Views:
    278
    Patrice
    Aug 17, 2004
Loading...

Share This Page