in reply to Re^7: Making a variable in a sub retain its value between calls
in thread Making a variable in a sub retain its value between calls

I'm curious. When do you need to use INITs to delay execution after all BEGIN blocks in scripts?

The point is that I don't have to even think about it. This is all very simple: I have a script, I have various bits of initialization code that need to be executed before run time scattered throughout; so I put them INIT blocks, without having to give a second's thought to what possible conflict any one of these INIT blocks may have with some BEGIN block later in the code.

The point of using INIT blocks to solve the static variable initialization problem is to give the programmer the flexibility to arrange code as desired; otherwise it would have been sufficient to stick all subs with static variables at the top of the file. If one puts this initialization code in BEGIN blocks now one goes back to having to worry about the position of these initalization BEGIN blocks relative to other BEGIN blocks (including implicit ones in use statements) in the file, which makes no sense to me.

the lowliest monk

  • Comment on Re^8: Making a variable in a sub retain its value between calls

Replies are listed 'Best First'.
Re^9: Making a variable in a sub retain its value between calls
by ikegami (Patriarch) on Apr 19, 2005 at 04:49 UTC
    Are you aware that BEGIN also executes before run-time? Using BEGIN should require less thought than INIT, given that INIT is very similar but has extra limitations, yet you incorrectly claim that you "don't have to even think about it".

      I don't know how to reply to this other than to re-iterate what I wrote in nodes 449075 and 449081. But I'd like to remark that from your response and ihb's, you apparently consider INIT blocks to be at best useless, at worst harmful, and certainly misnamed (i.e. not suitable for initialization). Do you have any use for them?

      Update: OK, I looked up INIT blocks in the Camel, wondering if I would find some dire warnings against their use. On p. 223 (3d edition), in a discussion of precisely the problem the OP posted, the book states

      ...you'll need to make sure any run-time assignment to my is executed early enough, either by putting the whole block before your main program, or, alternatively, by placing a BEGIN or INIT block around it to make sure it gets executed before your program starts.
      So what I wrote is essentially the same thing that the Perl docs say. If INIT blocks are so evil, why is the Camel giving such advice?

      the lowliest monk

        If INIT blocks are so evil, why is the Camel giving such advice?

        The other day, I listed a few methods to start a child process. Should the user randomly pick one of the methods I listed? No. Each item in my list has its own features and quirks. For example, system 1, ... only works on Windows, and fork is broken on Windows.

        If Camel's reader doesn't know the difference between BEGIN and INIT, he should look it up. That brings us to your previous question:

        But I'd like to remark that from your response and ihb's, you apparently consider INIT blocks to be at best useless, at worst harmful, and certainly misnamed (i.e. not suitable for initialization). Do you have any use for them?

        No. I didn't say INIT should not be used. All I said is that INIT should be used only after consideration, since it's broken. INIT blocks should not be used without thought as you say you do.

        you apparently consider INIT blocks to be at best useless, at worst harmful, and certainly misnamed (i.e. not suitable for initialization). Do you have any use for them?

        Useless: no. Harmful: no. Misnamed: no. Misunderstood: yes! They're useful when, and only when, you need to delay execution of something to before the program starts. For instance, Attribute::Handlers use INIT out of necessity, because it has no way of doing what it needs to do (for subroutines) at compile-time, so it needs to delay it to run-time (but even there it's not optimal to use INIT because it delays execution unnecessarily much, but it's the best Perl currently gives you). INIT should be used when you need to delay initialization code, not just execute initialization code in general.

        Regarding p 223 in Camel 3rd: It doesn't say that BEGIN and INIT may be equivalently used. It says that you can use both. It doesn't mean that one of them in general isn't better or that they don't have different uses.

        If INIT blocks are so evil, why is the Camel giving such advice?

        I guess that's a question the authors answer best. Update: As should be clear in my very first four sentences in this post I don't consider INITs evil. The misuse of them is though. (Whether the Camel misuse them or not I don't know since I don't own the Camel.)

        ihb

        See perltoc if you don't know which perldoc to read!