Programmer's notebook: static variables in Perl

Discussion in 'Perl Misc' started by Irving Kimura, Jan 25, 2004.

  1. I'm a newcomer to Perl, and though I can already write useful
    scripts, I'm still at the stage of learning about good Perl idioms.
    Here I'm interested in learning more about static-like variables.

    When programming C, I like using static variables to hold function-local
    constants that will not change value throughout the program's
    execution. E.g.

    int foo( int bar, int baz ) {
    static int frobozz = SOME_CONFIG_MACRO;
    int retval;

    /* do stuff with bar, baz, and frobozz */

    return retval;
    }

    Here frobozz is initialized only once, no matter how often foo is
    called.

    In Perl, one can use block scoping to achieve a similar effect
    (almost):

    FOO_BLOCK:
    {
    my $frobozz = SOME_CONFIG_CONSTANT;

    sub foo {
    my ($bar, $baz) = @_;

    # do stuff with $bar, $baz, and $frobozz;

    $retval;
    }
    }

    But there's a problem with this version of a static variable. If
    a call to foo() happens lexically before FOO_BLOCK, then $frobozz
    is undefined. This forces a potentially undesired ordering in the
    placement of such sub definitions in the file.

    The only way around this that I can think of is this:

    FOO_BLOCK:
    {
    my $frobozz;

    sub foo {
    $frobozz ||= SOME_CONFIG_CONSTANT;
    my ($bar, $baz) = @_;

    # do stuff with $bar, $baz, and $frobozz;

    $retval;
    }
    }

    This means that $frobozz gets evaluated one extra time, tested,
    and possibly assigned to (if SOME_CONFIG_CONSTANT happens to evaluate
    to false) during every call to foo.

    Is there a way to more closely replicate the behavior of C statics
    than this?

    TIA,

    Irv
     
    Irving Kimura, Jan 25, 2004
    #1
    1. Advertising

  2. Irving Kimura

    Bob Walton Guest

    Irving Kimura wrote:

    ....
    > Here I'm interested in learning more about static-like variables.
    >
    > When programming C, I like using static variables to hold function-local
    > constants that will not change value throughout the program's
    > execution. E.g.
    >
    > int foo( int bar, int baz ) {
    > static int frobozz = SOME_CONFIG_MACRO;
    > int retval;
    >
    > /* do stuff with bar, baz, and frobozz */
    >
    > return retval;
    > }
    >
    > Here frobozz is initialized only once, no matter how often foo is
    > called.
    >
    > In Perl, one can use block scoping to achieve a similar effect
    > (almost):

    ....


    Check out the "use constant" pragma. It might be what you are looking for:

    perldoc constant

    > Irv


    --
    Bob Walton
    Email: http://bwalton.com/cgi-bin/emailbob.pl
     
    Bob Walton, Jan 25, 2004
    #2
    1. Advertising

  3. Bob Walton <> wrote:
    > Irving Kimura wrote:
    >


    >> Here I'm interested in learning more about static-like variables.
    >>
    >> When programming C, I like using static variables to hold function-local
    >> constants



    > Check out the "use constant" pragma.



    But that is package-scoped.

    The OP wanted it block-scoped (to a function's block).


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jan 25, 2004
    #3
  4. Irving Kimura

    Jay Tilton Guest

    Irving Kimura <> wrote:

    : FOO_BLOCK:
    : {
    : my $frobozz;
    :
    : sub foo {
    : $frobozz ||= SOME_CONFIG_CONSTANT;
    : my ($bar, $baz) = @_;
    :
    : # do stuff with $bar, $baz, and $frobozz;
    :
    : $retval;
    : }
    : }
    :
    : This means that $frobozz gets evaluated one extra time, tested,
    : and possibly assigned to (if SOME_CONFIG_CONSTANT happens to evaluate
    : to false) during every call to foo.
    :
    : Is there a way to more closely replicate the behavior of C statics
    : than this?

    Do the initialization in a BEGIN or INIT block.

    {
    my $frobozz;
    INIT{ $frobozz = SOME_CONFIG_CONSTANT; }
    sub foo {
    my ($bar, $baz) = @_;
    # do stuff with $bar, $baz, and $frobozz;
    $retval;
    }
    }

    See "Persistent Private Variables" in perlsub.
     
    Jay Tilton, Jan 25, 2004
    #4
  5. (Jay Tilton) writes:

    > Irving Kimura <> wrote:
    >
    > : FOO_BLOCK:
    > : {
    > : my $frobozz;
    > :
    > : sub foo {
    > : $frobozz ||= SOME_CONFIG_CONSTANT;
    > : my ($bar, $baz) = @_;
    > :
    > : # do stuff with $bar, $baz, and $frobozz;
    > :
    > : $retval;
    > : }
    > : }
    > :
    > : This means that $frobozz gets evaluated one extra time, tested,
    > : and possibly assigned to (if SOME_CONFIG_CONSTANT happens to evaluate
    > : to false) during every call to foo.
    > :
    > : Is there a way to more closely replicate the behavior of C statics
    > : than this?
    >
    > Do the initialization in a BEGIN or INIT block.
    >
    > {
    > my $frobozz;
    > INIT{ $frobozz = SOME_CONFIG_CONSTANT; }
    > sub foo {
    > my ($bar, $baz) = @_;
    > # do stuff with $bar, $baz, and $frobozz;
    > $retval;
    > }
    > }


    What is the point of INIT{} there?

    I can see why sometimes you'd want BEGIN{} there but I have to try
    really hard to contrive a situation when...

    my $frobozz;
    INIT { $frobozz = SOME_CONFIG_CONSTANT; }

    ....is better than...

    my $frobozz = SOME_CONFIG_CONSTANT;

    --
    \\ ( )
    . _\\__[oo
    .__/ \\ /\@
    . l___\\
    # ll l\\
    ###LL LL\\
     
    Brian McCauley, Jan 26, 2004
    #5
  6. Irving Kimura

    Jay Tilton Guest

    Brian McCauley <> wrote:

    : I can see why sometimes you'd want BEGIN{} there but I have to try
    : really hard to contrive a situation when...
    :
    : my $frobozz;
    : INIT { $frobozz = SOME_CONFIG_CONSTANT; }
    :
    : ...is better than...
    :
    : my $frobozz = SOME_CONFIG_CONSTANT;

    Yes, if it's in a module, using either BEGIN{} or INIT{} just to give
    values to variables is wasted effort. Worse, using INIT{} in a module
    being require()d can be disastrous.

    But it's not hard at all to create that situation when the code is in
    the main program file.
     
    Jay Tilton, Jan 27, 2004
    #6
  7. In article <buv6tr$6fs$>,
    Irving Kimura <> wrote:
    >
    >
    >I'm a newcomer to Perl, and though I can already write useful
    >scripts, I'm still at the stage of learning about good Perl idioms.
    >Here I'm interested in learning more about static-like variables.
    >
    >...
    >But there's a problem with this version of a static variable. If
    >a call to foo() happens lexically before FOO_BLOCK, then $frobozz
    >is undefined. This forces a potentially undesired ordering in the
    >placement of such sub definitions in the file.
    >
    >The only way around this that I can think of is this:
    >
    > FOO_BLOCK:
    > {
    > my $frobozz;
    >
    > sub foo {
    > $frobozz ||= SOME_CONFIG_CONSTANT;
    > my ($bar, $baz) = @_;
    >
    > # do stuff with $bar, $baz, and $frobozz;
    >
    > $retval;
    > }
    > }
    >
    >This means that $frobozz gets evaluated one extra time, tested,
    >and possibly assigned to (if SOME_CONFIG_CONSTANT happens to evaluate
    >to false) during every call to foo.
    >
    >Is there a way to more closely replicate the behavior of C statics
    >than this?
    >


    You could 'require' inside a BEGIN to circumvent the ordering problem;

    foo.pl:
    -------
    my $foobozz = SOME_CONFIG_CONSTANT;
    { sub foo { ... }
    1;


    BEGIN { require .foo.pl'; }
    ....
    foo();


    hth,
    --
    Charles DeRykus
     
    Charles DeRykus, Feb 3, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sanny
    Replies:
    391
    Views:
    41,637
    anish.mathew84
    Jan 6, 2010
  2. Sanny
    Replies:
    396
    Views:
    7,080
    Noah Roberts
    Dec 17, 2008
  3. Isaac
    Replies:
    0
    Views:
    389
    Isaac
    Dec 8, 2010
  4. Irving Kimura

    Programmer's notebook: config files

    Irving Kimura, Jan 18, 2004, in forum: Perl Misc
    Replies:
    6
    Views:
    125
  5. Irving Kimura
    Replies:
    2
    Views:
    243
    Tassilo v. Parseval
    Jan 30, 2004
Loading...

Share This Page