http://www.perlmonks.org?node_id=993032


in reply to Re^2: How to do perl -c inside perl?
in thread How to do perl -c inside perl?

There were a couple of use cases of which this is one.

Another use is where you want to write a front-end to call a debugger, profiler, code coverage tool, or anything else that adds some sort of instrumentation (and thus, modules and options to Perl) before runnining it. In this situation, one may want to do a syntax check first before taking the plunge. So being able to correctly handle:

__END__ $x =
does matter.

But in the situation inside the debugger where one needs to be able to check for valid expressions or statements, wrapping inside a sub{ .. } is useful.

I hadn't thought about using this inside the debugger eval command to automatically figure out if a continuation is needed. So I will probably add that. Thanks!

It can also be used as a more fool-proof way to determine a source-code line that is shown is complete over the method currently in use by perl5db.pl which is confused by:

eval " # not a comment ";
which thinks that the line inside the eval is a comment.

If "the more or less" code you use is interesting and useful, please expand upon that. Also, I don't understand what you mean by thinking of something "more elaborate". All I was looking for was something to get the job done. If it is interesting, elaborate on what you mean by "more elaborate".

It's only by having people work out various approaches that we've been able to weight the pros and cons of each and thus understand what the right thing is for particular situations. Thanks.

Replies are listed 'Best First'.
Re^4: How to do perl -c inside perl?
by LanX (Saint) on Sep 12, 2012 at 13:54 UTC
    Hi

    > Also, I don't understand what you mean by thinking of something "more elaborate"

    well for instance, you won't catch all possible syntax errors:

    lanx:/tmp$ cat tst.pl }; $hash = { lanx:/tmp$ perl -c /tmp/tst.pl Unmatched right curly bracket at /tmp/tst.pl line 1, at end of line syntax error at /tmp/tst.pl line 1, near "}" Missing right curly or square bracket at /tmp/tst.pl line 1, at end of + line syntax error at /tmp/tst.pl line 1, at EOF /tmp/tst.pl had compilation errors. lanx:/tmp$ perl $code = '}; $hash = {'; eval "sub { $code } "; print $@; __END__ lanx:/tmp$ perl $code = '}; $hash = '; eval "sub { $code } "; print $@; __END__ Unmatched right curly bracket at (eval 1) line 1, at end of line syntax error at (eval 1) line 1, at EOF

    you might be interested in my slides from YAPC::EU

    http://act.yapc.eu/ye2012/talk/4204

    unfortunately ATM I have no time to elaborate deeper... :(

    Cheers Rolf

      With respect to using a debugger as a Pseudo-REPL see my blog post Devel::Trepan Debugger evaluation of Perl statements where I address things like the missing "print" in RE(P)L. Also addresssed is the fundamental fact that Perl has an array and scalar context in evaluation. The debugger also even tries to come to grips with the fact that although there's no "hash" context, because Perl has hash variables, something probably needs to be done to smooth that out. It is possible more needs to be done for subroutines, globs, and file handles.

      Now back to detecting when continuation of input is warranted. The real crux of the problem as has been noted, is the lack of a Perl parser; that Perl is the only thing that can really parse Perl properly. So we have these wrapped "sub" solutions. But if you are willing to put your code in a file, then one can "eval" or "do" that file. That obviates the cut and paste problem mentioned in the slides.

      But a failing of the eval approach as you note is that if there's a syntax error somewhere inside you'll never know when to stop. No suffix of the previous input will never be valid. A slight improvement might be to parse the error message to see there's something that is unambiguously unfixable. Things like "Can't find string terminator" or "... anywhere before EOF" suggest continuation. Too many things fall in the middle though.

      For Devel::Trepan you could probably write your own Devel::Trepan command for multi-line input. It would be clean and you can make it a package on CPAN. At a minimum Devel::Trepan gives you cleaner ways to extend code than perl5db.

      Something related to figuring out whether input should be continued is trying to show all the full statement that starts on a given line, no matter how many lines it spans. This is useful in a debugger to show the source code statement where the program is stopped.

      The sub-wrapped eval heuristic has more hope here for two reasons. First, we know that the underlying text is valid. Second, if a statement spans several lines, then when that statement ends programmers don't generally start a new statement on the same line. That is, there generally isn't something like:

      $x = 5; $y = 6; $z = 7;

      Finally in the slides you seem to place a big emphasis on using things that are in Perl core. But for anything reasonable that is a chicken and egg problem. People have to start using, likiing and advocating Devel::Trepan before it would be put into core.

        > But a failing of the eval approach as you note is that if there's a syntax error somewhere inside you'll never know when to stop. No suffix of the previous input will never be valid. A slight improvement might be to parse the error message to see there's something that is unambiguously unfixable. Things like "Can't find string terminator" or "... anywhere before EOF" suggest continuation. Too many things fall in the middle though.

        ATM I'm solving this by stopping multi-line after manually typing a double semicolon ";;". I just patched the mechanism for parsing "\" at end of line.

        And yes on the long run one needs a better "perl parser".

        Thats why I started a spin off project for "empiric" parsing, which even works well detecting nested structures in its actual very Q&D form (mentioned in the slides)

        I plan to release it on GitHub/CPAN, as soon as my actual proj€ct end$, maybe it can even help with other REPL projects.

        > Finally in the slides you seem to place a big emphasis on using things that are in Perl core.

        perl5db is deeply integrated in many tools, including my preferred IDE. And thankfully my patches work there out-of-the box!

        And I'm regularly working on remote servers where installing new modules is very "political" ... but nobody can fire me for my personal rc-file.

        I like Devel::Trepan and I can follow many of your arguments and I certainly didn't mean to attack your efforts.

        But ATM there are so many shell/repl/debugger solutions on CPAN and none became core till now.

        And I need solutions now.

        Cheers Rolf