in reply to Re^2: eval sub
in thread eval sub

I don't believe prototyping to be an issue here.

Maybe.  What I meant is probably best expressed with a simple snippet of code, which resembles in essence what I understood you're trying to do (but without the XML and stuff):

my $code = << 'EOC'; sub mySub() { print "args: @_\n"; } EOC eval $code; print qq(\ncalling 'mySub()'\n); eval 'mySub()'; print "error: $@" if $@; print qq(\ncalling 'mySub("hello world")'\n); eval 'mySub("hello world")'; print "error: $@" if $@;

Running this gives:

calling 'mySub()' args: calling 'mySub("hello world")' error: Too many arguments for main::mySub at (eval 3) line 2, near ""h +ello world")

As you can see, the second call (with arguments) fails with the prototype in place.  And it fails silently, unless you check $@.

Replies are listed 'Best First'.
Re^4: eval sub
by samip (Novice) on Oct 10, 2008 at 13:49 UTC
    Thanks again almut. I understand and agree with what you are saying. I checked for the errors and this is what I got "error: Can't find string terminator '"' anywhere before EOF at (eval 5) line 1."

    This made me realize that even though I might be quoting the arguments string in the code posted here correctly, I wasn't doing that right in the actual code where I also needed to first escape both $ in my hash to be \$\$myHash. Adding that extra stuff fixed it. I didn't even think that was the problem - there's a duh! moment. :)

    While I am not sure why I wasn't getting the "Too many arguments..." error in my direct call to mySub("Hello world"), it is likely I would have got that error once I actually quoted my string right in the eval. I added the direct call in your code to highlight what I am saying about not getting the error when making the direct call:

    my $code = << 'EOC'; sub mySub() { print "args: @_\n"; } EOC eval $code; print qq(\ncalling 'mySub()'\n); eval 'mySub()'; print "error: $@" if $@; print qq(\ncalling 'mySub("hello world")' directly\n); mySub("hello world"); print qq(\ncalling 'mySub("hello world")'\n); eval 'mySub("hello world")'; print "error: $@" if $@;

    Running this returned:

    calling 'mySub()' args: calling 'mySub("hello world")' directly args: hello world calling 'mySub("hello world")' error: Too many arguments for main::mySub at (eval 3) line 2, near ""h +ello world")"
      ...I am not sure why I wasn't getting the "Too many arguments..." error in my direct call to mySub("Hello world")

      The reason for this is that the error is thrown at compile time. In the case of the direct call, the subroutine definition (and its prototype) isn't known yet, as it gets eval-ed later at runtime...

      Put that code in a BEGIN {...} block, i.e.

      BEGIN { my $code = << 'EOC'; sub mySub() { print "args: @_\n"; } EOC eval $code; } ...

      and you'll see the difference. Due to the compilation error, the script now doesn't run at all:

      $ ./716452.pl Too many arguments for main::mySub at ./716452.pl line 19, near ""hell +o world")" Execution of ./716452.pl aborted due to compilation errors.