in reply to Re^9: 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 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

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

Replies are listed 'Best First'.
Re^11: Making a variable in a sub retain its value between calls
by ikegami (Patriarch) on Apr 19, 2005 at 19:09 UTC
    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.

Re^11: Making a variable in a sub retain its value between calls
by ihb (Deacon) on Apr 19, 2005 at 16:08 UTC

    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!

      INIT blocks are not evil--they're just broken in Perl 5, which is why they'll work right in Perl 6. An INIT should just run as soon as possible, but not before the run-time process starts. It should never be "too late" to run an INIT.

      On the other hand, going back to the OP's question, INIT is not the Perl 6 solution to that. Instead, we'll use state variables, which have FIRST semantics rather than INIT semantics. That lets closure clones get individual state variables with individual initializations, but makes Perl keep track of "first use" for the user. INIT is just too blunt of an ax for that purpose.