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

I have a perl script

#!perl -w use strict; my $param = shift; eval print $param; sub egal () { my $result; my @arg = @_; $test = $arg[0]; @test = grep (/$test/i, @arg); print "++++"; if ($#test == $#arg) { $result = true; } else { $result = false; } return $result; }

Now I am calling the script :-

perl 'egal("20090316","7006")'

I want the script to eval the parameter and return me the result. The output should be like:


But it is not returning me any result. On the other hand if I set a variable to the value whatever I am passing through parameter and then pass the variable to eval, it is giving the desired output

#!perl -w use strict; #my $param = shift; my $param = egal("7006","7006"); eval print $param; sub egal () { my $result; my @arg = @_; my $test = $arg[0]; my @test = grep (/$test/i, @arg); print "++++"; if ($#test == $#arg) { $result = "true"; } else { $result = "false"; } return $result; }

Now I am calling the script :-


Output :


So now how do I make the first piece of code work... so that I can make the sub program call dynamic??

Replies are listed 'Best First'.
Re: perl eval
by Corion (Pope) on Jul 05, 2010 at 13:49 UTC

    Would your code work without the eval?


    sub egal ()

    does not do what you want, or, maybe in this case, actually does what you intended at one time.

    Consider this program:

    #!perl -w use strict; my $param = shift; print "About to run: [$param]\n"; my @res = eval($param); print $@ if $@; sub egal () { print "Got arguments [@_]\n"; }

    Also, consider running your programs using perl -w. That way, Perl will tell you about things that might not be what you think them to be. Especially, there are no true or false keywords in Perl.

Re: perl eval
by ww (Archbishop) on Jul 05, 2010 at 14:25 UTC

    The reason you're not getting any output here is that you never call your sub, "egal ()" in You could have learned this with judicious insertion of (debugging) print statements (to test the content/existence of the vars in your sub) or running the script in the deugger, >perl -d 'egal("20090316","7006")'/p>

    Further, if you are trying to ensure that egal() gets called, leaving it out of the command line invocation makes no difference.

    If you insert a line 26, "egal($param);  # call the sub!", your script will (try to) execute the sub (and as far as printing the plus signs); the balance of your problem (your regex usage) is left as an exercise for the OP.

    Stock advice (you were going to get it sooner or later, even though it's not the root of your problem here): It's often a mistake to omit use strict and warnings which would have told you that your barewords, "true" and "false" (lines 17 & 21) might be a problem. But that's a generic problem and bit of advice. Use strict and warnings to help you uncover common problems, albeit, not the real problem here.

      $param itself has the calling argument so when i am calling eval with the $param it should get executed... atleast that is what I want..!

        "... atleast that is what I want..!"

        and I want a pony... but I've never found a hayburner in my Christmas stocking.

        Others monks have explained the shortcomings of your eval print $param; but, for emphasis:

        >perl 'egal("20090316","7006")' 'egal(20090316,7006)' is $param at line 10 'egal(20090316,7006)' Line 11 $param: |'egal(20090316,7006)'| At 13, $test: 'egal(20090316,7006)' Use of uninitialized value in concatenation (.) or string at 848064_xy line 22. ++++ >

        And, just BTW, note that your double_quotes -- the "s -- don't pass through the windows shell (my Linux box is down, but IIRC, you'll have a mirror-image issue there).

        Here's your code, slightly modified at 5, 6, 9, 10, 12, 19 and 34 for illustration (thus, "line 26" in my previous reply is now line 38).

        #!/usr/bin/perl use strict; use warnings; # OP says: Now I am calling the script : # 001: perl 'egal("20090316","7006")' my $param = shift; chomp $param; print "\n\n\t $param is \$param at line 10\n\n"; eval print $param; print "\n\tLine 11 \$param: |$param| \n"; sub egal { my $result; my @arg = @_; my $test = $arg[0]; print "\n At 13, \$test: $test\n\n"; my @test = grep (/$test/i, @arg); print "\t $test[0] \n"; print "++++"; if ($#test == $#arg) { $result = 'true'; } else { $result = 'false'; } return $result; print " $result\n"; } egal($param); # call the sub!

        ... and 'Doh!' on /me.

        Modify beginning at line 32 as follows:

        } print "Inside the sub at line 34: |$result|\n"; return $result; } my $ result = egal($param); # call the sub! print "At line 39 (after the sub), \$result is: |$result|\n";

        and, lo and behold the output, as above but with a difference after the uninit... :

        ... Use of uninitialized value in concatenation (.) or string at 848064_xy line 22. ++++Inside the sub at line 34: |false| At line 39 (after the sub), $result is: |false|
Re: perl eval
by JavaFan (Canon) on Jul 05, 2010 at 14:19 UTC
    eval print $param;
    That code prints out the value of $param, then evals the return value of print. You probably want something like:
    my $result = eval $param; die "eval failed: $@" unless defined $result; print $result;
Re: perl eval
by moritz (Cardinal) on Jul 05, 2010 at 13:49 UTC
    Most likely an error happens during the eval call. To get more information, print the error message. The documentation tells you where to find it.
    Perl 6 - links to (nearly) everything that is Perl 6.