What is the role of the BEGIN block in Perl?

前端 未结 3 1526
青春惊慌失措
青春惊慌失措 2021-01-31 15:49

I know that the BEGIN block is compiled and executed before the main body of a Perl program. If you\'re not sure of that just try running the command perl -cw over this:

3条回答
  •  不思量自难忘°
    2021-01-31 16:07

    Have you tried swapping out the BEGIN{} block for an INIT{} block? That's the standard approach for things like modperl which use the "compile-once, run-many" model, as you need to initialize things anew on each separate run, not just once during the compile.

    But I have to ask why it's all in special block anyway. Why don't you just make some sort of prepare_db_connection() function, and then call it as you need to when the program starts up?

    Something that won't work in a BEGIN{} will also have the same problem if it's main-line code in a module file that gets used. That's another possible reason to use an INIT{} block.

    I've also seen deadly-embrace problems of mutual recursion that have to be unravelled using something like an require instead of use, or an INIT{} instead of a BEGIN{}. But that's pretty rare.

    Consider this program:

    % cat sto-INIT-eg
    #!/usr/bin/perl -l
    print               "    PRINT: main running";
    die                 "    DIE:   main dying\n";
    die                 "DIE XXX /* NOTREACHED */";
    END         { print "1st END:   done running"    }
    CHECK       { print "1st CHECK: done compiling"  }
    INIT        { print "1st INIT:  started running" }
    END         { print "2nd END:   done running"    }
    BEGIN       { print "1st BEGIN: still compiling" }
    INIT        { print "2nd INIT:  started running" }
    BEGIN       { print "2nd BEGIN: still compiling" }
    CHECK       { print "2nd CHECK: done compiling"  }
    END         { print "3rd END:   done running"    }
    

    When compiled only, it produces:

    % perl -c sto-INIT-eg 
    1st BEGIN: still compiling
    2nd BEGIN: still compiling
    2nd CHECK: done compiling
    1st CHECK: done compiling
    sto-INIT-eg syntax OK
    

    While when compiled and executed, it produces this:

    % perl sto-INIT-eg 
    1st BEGIN: still compiling
    2nd BEGIN: still compiling
    2nd CHECK: done compiling
    1st CHECK: done compiling
    1st INIT:  started running
    2nd INIT:  started running
        PRINT: main running
        DIE:   main dying
    3rd END:   done running
    2nd END:   done running
    1st END:   done running
    

    And the shell reports an exit of 255, per the die.

    You should be able to arrange to have the connection happen when you need it to, even if a BEGIN{} proves too early.

    Hm, just remembered. There's no chance you're doing something with DATA in a BEGIN{}, is there? That's not set up till the interpreter runs; it's not open to the compiler.

提交回复
热议问题