Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[doc] perl -c vs. "outside" #22143

Open
jidanni opened this issue Apr 13, 2024 · 5 comments
Open

[doc] perl -c vs. "outside" #22143

jidanni opened this issue Apr 13, 2024 · 5 comments

Comments

@jidanni
Copy link
Member

jidanni commented Apr 13, 2024

man perlrun says

  -c   causes Perl to check the  syntax  of  the  program  and  then  exit
       without  executing  it.   Actually,  it  will  execute any "BEGIN",
       "UNITCHECK", or "CHECK" blocks and any "use" statements: these  are
       considered  as  occurring  outside  the  execution of your program.
       "INIT" and "END" blocks, however, will be skipped.

It seems the word "outside" needs to be changed to "inside", for the
above paragraph to make sense.

Anyway, some people would just like to check the syntax of the single file in
front of them, without needing to comment out any "use", or providing
paths.

Just like if their program said open(my $fh, "<", "input.txt"), when not having such a input.txt ready yet. It shouldn't affect the syntax check.

So maybe an option could be added for that.

@Grinnz
Copy link
Contributor

Grinnz commented Apr 13, 2024

"outside" is correct, the compilation is considered outside the execution, though this may better be replaced with "before". Syntax cannot be checked without executing these blocks and use statements, because these things can and commonly do modify the parser (the simplest example is "use strict").

@mauke
Copy link
Contributor

mauke commented Apr 13, 2024

Conceptually, Perl programs have a compilation phase (where source code is parsed and translated to an internal representation) and a run-time phase (where the internal representation is executed). In practice, perl always performs these two steps together, one directly after the other, so for the most part, you don't have to care. But technically the steps are:

  • parsing (including BEGIN blocks and use statements)
  • "checking" (including CHECK blocks)
  • compile time ends
  • runtime begins
  • initialization (including INIT blocks)
  • main script starts running
  • ...
  • program calls exit or die or falls off the end of the main script
  • cleanup (including END blocks)
  • global objects are destroyed (so their destructors are called)

The -c switch stops after compile time ends, so all the runtime parts are skipped.

Not executing use would break a lot of code. Not just in obvious cases like use strict or use feature (which have a big impact on how the following code is parsed), but also seemingly harmless cases like:

use Scalar::Util qw(looks_like_number);
if (looks_like_number "31.42-1") {
    print "yay\n";
}

This code just imports and calls a subroutine. But without executing the use statement, we get:

String found where operator expected (Do you need to predeclare "looks_like_number"?) at - line 2, near "looks_like_number "31.42e-1""
syntax error at - line 2, near "looks_like_number "31.42e-1""
Execution of - aborted due to compilation errors.

@jidanni
Copy link
Member Author

jidanni commented Apr 13, 2024

Okay okay okay. So let's just concentrate on that word "outside". Seems like it's just checking the things outside the program and not the things inside or something.

If we change it to "before" then where should we put the word "after" etc.?

I think somebody needs to do a professional redo on that paragraph. Not some amateur like me.

@jidanni jidanni changed the title [doc] perl -c vs. "use" [doc] perl -c vs. "outside" Apr 13, 2024
@guest20
Copy link

guest20 commented Apr 15, 2024

@jidanni

I think it's also worth nothing that you can't just "focus on this one word in a sentence", you need to look at 'em all, and form a kind of parse tree, and then extract the meaning from that.

I'd like to propose that we just concentrate on "statements [that] are considered as occurring outside the execution of your program".

If you include those other words into your reading it becomes clearer that it's not checking the parts "considered as occurring outside the execution of your program", it's executing the parts "considered as occurring outside the execution of your program".

</@ mention>

To me it seems like an explanation of why these blocks need to be run/skipped is more than one can readily boil down into a single sentence, so it might be worth not including it in a summary/usage message and just describing the behaviour direclty:

 -c   causes Perl to check the  syntax  of  the  program  and  then  exit without  executing  it. 
      Security note: -c will run some code blocks (BEGIN/use/require/CHECK/etc)
                     and skip others (END/INIT). 
                     see L<perlrun/why-minus-c-runs-some-stuff> for more.

@jidanni
Copy link
Member Author

jidanni commented Apr 17, 2024

Hey that's a good idea. Just tell what it is going to do. No need to get into deep logic about it. OK, please make the edit. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants