Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re^4: Making a variable in a sub retain its value between calls

by tlm (Prior)
on Apr 19, 2005 at 00:11 UTC ( [id://449068] : note . print w/replies, xml ) Need Help??


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

Yes, but I want this initialization to happen just before run time. There's absolutely no reason, in general, for the initialization of the typical static variable to happen at compile time.

the lowliest monk

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

Replies are listed 'Best First'.
Re^5: Making a variable in a sub retain its value between calls
by ihb (Deacon) on Apr 19, 2005 at 00:24 UTC

    I'm talking about program run-time, not any file's run-time. If you have a module Foo that uses INIT you'll get a "Too late to run INIT block" warning if you require Foo during program run-time. E.g. you have

    # Foo.pm INIT { print 'Foo' } # foo.pl require Foo;
    That won't execute like one would hope. By using INIT to initialize variables to constants you impose a completely unnecessary constraint on your module. No module that uses your Foo can be loaded at program run-time, meaning you can't ever use Foo, directly or indirectly, in any module that is dynamically loaded (like plugin modules). That's quite a serious limitation.

    There's absolutely no reason, in general, for the initialization of the typical static variable to not happen at compile-time.

    ihb

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

      We disagree on what we consider general programming practice vs. programming for special cases, but it seems to me that this is a tomayto-tomahto difference of opinion.

      Update: Perhaps I should clarify that, most of my programming is scripting, not module-writing, and of the module writing I do, 90% of it is OO classes. In the case of scripts, INIT is perfectly fine; it gives me a hook that I know will happen after all the BEGINs I have scattered throughout my code. In my OO code I rarely if ever need static variables.

      the lowliest monk

        I assure you, it certainly isn't a tomayto-tomahto difference of opinion. This isn't about opinions. This is about not putting extremely excessive limitations on your code without reason. I get the feeling that you don't realize how far the consequences propagate -- the consequences go far beyond your reach as a module author. (Yes, the world will probably end, too. ;-)) Any user that uses your module will be effected by this completely useless limitation.

        See CHECK and INIT under mod_perl and call a modules INIT-section for examples of when INIT can cause trouble. (The second problem is completely unnecessary and wouldn't have been a problem if the author would've understood the purpose of INIT, as I point out in my reply.)

        Reply to the update:
        Right, if you use it only for scripts it's OK, but if I'll have an opinion then it's that it's far better to use a solution that, in general, always works over a solution that, in general, sometimes works.

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

        ihb

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

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

    Since the other argument wasn't convincing enough, here's an argument that hopefully is.

    There's absolutely no reason, in general, for the initialization of the typical static variable to happen at compile time.

    Yes there is. Now, a very real-world example:

    # Foo.pm package Foo; use base 'Exporter'; our @EXPORT = qw/ foo_init foo_begin /; { my $thing; INIT { $thing = 'init' }; sub foo_init { print "init: $thing"; } } { my $thing; BEGIN { $thing = 'begin' }; sub foo_begin { print "begin: $thing"; } } 1; # Bar.pm package Bar; use Foo; # This can be put in &import if you # think that's more real-world. foo_init(); foo_begin(); 1; # foo.pl #!/usr/bin/perl -wl use Bar;
    The output of this will be
    Use of uninitialized value in concatenation (.) or string at Foo.pm li +ne 9. init: begin: begin

    Again, if you put unnecessary INITs in a module you render that module close to useless for many applications where it could've been used.

    ihb

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