Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Syntax checking without BEGIN blocks

by Anonymous Monk
on Apr 27, 2006 at 18:37 UTC ( [id://546084]=perlquestion: print w/replies, xml ) Need Help??

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

perl -'wc' <programname> will check the syntax of a program, but it will also run the code included in any BEGIN blocks (which are also implicit in "use" statements).

How do I do that if I don't want the BEGIN blocks to run? Some genius made all the modules start running code the minute they're "used"; I don't want to start messing with the codebase just to check the debug statement I've added.

How do I make perl just check the syntax, and do nothing else?

Replies are listed 'Best First'.
Re: Syntax checking without BEGIN blocks
by duff (Parson) on Apr 27, 2006 at 18:47 UTC

    AFAIK, you can't. The BEGIN subs need to execute as they have the potential to warp the syntax.

      Seems (to my unfamiliar-with-internals eyes) like it wouldn't be too much of a stretch to have a check option for each phase, so you could syntax-check only the BEGIN phase, for example. I don't even know in what order BEGIN, CHECK, and INIT get run, but each setting would only run "up to" whatever phase you're interested in.

      Would someone who has a better understanding comment on whether that's doable?

      Update: Looks like people know enough to downvote, but not enough to explain. That's never happened before.


      Caution: Contents may have been coded under pressure.

        I think the down votes are because a) syntax checking only through BEGIN, CHECK, INIT doesn't solve the OP's problem and b) because you said you don't know what order BEGIN, etc run in when it's easily discoverable from the docs (never admit weakness ;-).

        Though, in any case your post does present a potential "solution". The OP could modifiy the modules such that any initialization code is in an INIT block rather than free of subroutine shackles and so executed at module use-time. Of course, this is assuming that the code really isn't warping the syntax of the language to its own nefarious desires and really isn't setting up structures needed by future BEGIN-time processes.

        In some sense, perhaps "free" code in modules should automatically be placed in INIT blocks and the module author, if they really need BEGIN-time processing, should be required to say BEGIN { ... }. I'd wager that that's what many people mean with "free" code anyway.

Re: Syntax checking without BEGIN blocks
by bluto (Curate) on Apr 28, 2006 at 16:36 UTC
    I like to syntax check my own code, esp during a development cycle. (This isn't as useful for other people's modules but that's why test suites exist.) As others have mentioned, perl itself is unable to do this in all cases. IMO it is a module writer's responsibility, if at all possible, to allow the module user to check their own code without side effects. For example, it appears that most simple side effects (e.g. unlink) can be "commented" out with the $^C variable like this...

    unlink("myfile") unless $^C;

    I haven't seen much mention of $^C in the past, so perhaps someone more knowledgable can comment on whether this is always effective.

      IMO it is a module writer's responsibility, if at all possible, to allow the module user to check their own code without side effects.

      That assumes no incompetence or malice on the part of the module writer. One of the first tests of competence is to see if the module is will actually pass a syntax check.

      The problem of how to do that safely is really the one I'd like to address.

        If you are worred about incompetance or malice, you better visually inspect the module and the Makefile that comes with it (I certainly do). Syntax checking is great for finding bugs during compiling your own code, but don't confuse it with keeping things safe. In fact the safest code is code that fails a syntax check.

        Syntax checking can't stop someone from writing syntactically correct, non-BEGIN block, destructive code. All they have to do is bury something like system("rm -rf *") in the module somewhere and you will have lots of fun trying to find out why your system doesn't work.

        A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Syntax checking without BEGIN blocks
by isotope (Deacon) on May 01, 2006 at 22:20 UTC
    PerlTidy can do some basic syntax checking without running the script through perl, but it's not perfect, because it's not running the script through perl. It can also optionally pass it through perl, which of course will execute the BEGIN blocks.

    Your real problem is that you have a bad block of code in the module you want to check. Just what are you going to do with this unsafe code after you add your debug statement?

    I'd also offer the advice that being rude to people you ask for free help probably doesn't get you very far, but I doubt you'd take that advice.


    --isotope
Re: Syntax checking without BEGIN blocks
by TedPride (Priest) on Apr 27, 2006 at 18:55 UTC
    Just write a Perl script to move the BEGIN blocks to the front, and replace the BEGIN with do and comment markers. Test your code. Then use another Perl script to move the blocks back.

      Why write a separate Perl script? Turn this into a module that sticks a codref in @INC to filter the BEGIN blocks into harmless normal subroutines. Acme::Incorporated shows how.

      Yuck. Isn't there an option to the syntax checker to just, you know, check the syntax without actually running anything? :-(

      Is anyone working on this?

        I think you might have missed the point about begin blocks. In order for perl to check syntax it HAS to run the use statments, because the use statments can change perls syntax. Thinks like subs in the modules included could add behaviour to bare words, especialy subs with prototypes.


        ___________
        Eric Hodges

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://546084]
Approved by kvale
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-25 23:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found