in reply to Execution order of END/CHECK vs BEGIN/INIT

Think about nested objects. You create A, then using A, you create B. When you go to destroy B, you may call some A methods, then finally destroy B, so you want A to still exist while B is finalizing itself.

Always do "startup" stuff in FIFO and "shutdown" stuff in LIFO and everything nests nicely.

  • Comment on Re: Execution order of END/CHECK vs BEGIN/INIT

Replies are listed 'Best First'.
Re: Re: Execution order of END/CHECK vs BEGIN/INIT
by belden (Friar) on Jun 27, 2003 at 21:11 UTC

    I'd think that timely destruction of nested objects would be taken care of by DESTROY{}'s happening in the right order. Can you expand your point? I don't see how it applies to END{} blocks...

    blyman
    setenv EXINIT 'set noai ts=2'

      I think he was making an anology.

      If module A "uses" module B, then you want modula A's BEGIN block to run before modules B's BEGIN block. When cleanup happens, you want module B's END block to run before module A's END block.

      Update: ... I thought i knew what i talking about .. but i clearly didn't, i'm not even sure what i was trying to say anymore. so i retract it all (except for the analogy part)

        But that's quite opposite of what's usually happening. If you have:
        package A; use B; BEGIN { ... } END { ... }

        Then the BEGIN blocks of B are run before the one's in A (because the compiler sees them earlier), while the END blocks of A are run after any END blocks of B (because the compiler sees the one in A after the one's in B).

        With apologies, because I'm sure my question has already been answered but I'm too dense to recognize that fact... :)

        If module A "uses" module B, then you want module A's BEGIN block to run before modules B's BEGIN block. When cleanup happens, you want module B's END block to run before module A's END block.

        Given these modules

        # this is A.pm package A; BEGIN { print "Haven't used B yet\n" } use B; BEGIN { print "Just used B\n" } END { print "Exiting A\n" } 1; # this is B.pm package B ; BEGIN { # open a file or exit(1) with a message to STDERR open B_FH, 'somefile' or exit warn "somefile: $!\n" ; } END { close B_FH ; print "Exiting B\n" ; } 1;

        If I read your post correctly, you're saying that I want module B's END block to run before module A's END block. If this is what I wanted, I think I'd be disappointed: A use's B, which means that 'use B' in A causes us to fully parse B before finishing parsing A. Therefore, B's END block is loaded before A's END block. This makes A's END block Last In, thereby First Out.

        The truth is, I actually don't care in which order ENDs and CHECKs get called. I just want to know why BEGIN/INIT are FIFO and END/CHECK are LIFO.

        blyman
        setenv EXINIT 'set noai ts=2'
      If the objects survive to global destruction, there's no guarantee of destruction order. Perl just sweeps the arenas and blows everything away in whatever order it finds things in.

        Right- I've read that dozens of times through the perldocs, but never understood what that meant until now. Thanks for the reinforcement :)

        blyman
        setenv EXINIT 'set noai ts=2'