perl feature request

Discussion in 'Perl Misc' started by dt, Mar 21, 2007.

  1. dt

    dt Guest

    I find the following useful and would like to see it as a new perl
    feature:

    I often have to cache a variable based on a complex function. it owuld
    be nice if perl had something like this built in. here is an example:

    our $html;
    if ($html !~ /./)
    {
    $html = load_as_string($fh, "filename.html");
    }


    a datatype such as:

    cache $html = load_as_string($fh, "filename.html");

    would be really cool. basically, if the var is not set, it sets the
    var. if it is set, it skips the call.

    it would have to still be there if the function is exited and recalled
    (same scope as our).
     
    dt, Mar 21, 2007
    #1
    1. Advertising

  2. dt

    Uri Guttman Guest

    >>>>> "d" == dt <> writes:

    d> I find the following useful and would like to see it as a new perl
    d> feature:

    d> I often have to cache a variable based on a complex function. it owuld
    d> be nice if perl had something like this built in. here is an example:

    d> our $html;

    that will mean $html is undef. where would another value come from?

    d> if ($html !~ /./)

    that will generated an undefined warning.

    d> {
    d> $html = load_as_string($fh, "filename.html");
    d> }


    huh? what is wrong with just doing this:

    $html ||= load_as_string($fh, "filename.html");

    and load_as_string is already in File::Slurp as read_file().


    d> a datatype such as:

    d> cache $html = load_as_string($fh, "filename.html");

    d> would be really cool. basically, if the var is not set, it sets the
    d> var. if it is set, it skips the call.

    but you can't declare and also optionally assign. where would a preset
    value come from??

    d> it would have to still be there if the function is exited and recalled
    d> (same scope as our).

    easy. just declare it my in a block that also includes the sub:

    use File::Slurp ;

    {

    my $html ;

    sub do_stuff {

    $html ||= read_file( $filename ) ;

    }

    }

    so it already is in perl.

    and that only fails if the html file is a false value (just '0', or
    empty) which is unlikely.

    in perl 5.10 you can do //= and test for defined and that solves that
    problem.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Mar 21, 2007
    #2
    1. Advertising

  3. dt

    -berlin.de Guest

    Uri Guttman <> wrote in comp.lang.perl.misc:
    > >>>>> "d" == dt <> writes:

    >
    > d> I find the following useful and would like to see it as a new perl
    > d> feature:
    >
    > d> I often have to cache a variable based on a complex function. it owuld
    > d> be nice if perl had something like this built in. here is an example:
    >
    > d> our $html;
    >
    > that will mean $html is undef. where would another value come from?


    From anywhere, it's a package variable. Unlike "my", "our" doesn't
    reset the value at run time.

    I quite agree with the rest of your posting.

    Anno
     
    -berlin.de, Mar 21, 2007
    #3
  4. dt

    Uri Guttman Guest

    >>>>> "a" == anno4000 <-berlin.de> writes:

    a> Uri Guttman <> wrote in comp.lang.perl.misc:
    >> >>>>> "d" == dt <> writes:

    >>

    d> I find the following useful and would like to see it as a new perl
    d> feature:
    >>

    d> I often have to cache a variable based on a complex function. it owuld
    d> be nice if perl had something like this built in. here is an example:
    >>

    d> our $html;
    >>
    >> that will mean $html is undef. where would another value come from?


    a> From anywhere, it's a package variable. Unlike "my", "our" doesn't
    a> reset the value at run time.

    of course i know what our is. but his example didn't show any other
    assignment to it. he was looking for a static type variable and our was
    all he could come up with. even file scoped my would be fine. the real
    point was not knowing about ||=.

    a> I quite agree with the rest of your posting.

    as do i. :)

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Mar 21, 2007
    #4
  5. dt

    Ben Morrow Guest

    Quoth Uri Guttman <>:
    > >>>>> "d" == dt <> writes:

    >
    > d> a datatype such as:
    >
    > d> cache $html = load_as_string($fh, "filename.html");
    >
    > d> would be really cool. basically, if the var is not set, it sets the
    > d> var. if it is set, it skips the call.
    >
    > but you can't declare and also optionally assign. where would a preset
    > value come from??
    >
    > d> it would have to still be there if the function is exited and recalled
    > d> (same scope as our).
    >
    > easy. just declare it my in a block that also includes the sub:


    <code snipped>

    I was going to say 'in 5.10 this exact feature has been included, as the
    new 'state' variables', but perlsub says

    | B<Caveat>: the code at the right side of the assignment to a state
    | variable will be executed every time; only the assignment is disabled.
    | So, avoid code that has side-effects, or that is slow to execute. This
    | might be optimized out in a future version of Perl.

    Doesn't this make state variables, uh, rather useless? Given that they
    are basically exactly equivalent to your example above, so all you save
    is one compile-time block? Have I missed something?

    > and that only fails if the html file is a false value (just '0', or
    > empty) which is unlikely.
    >
    > in perl 5.10 you can do //= and test for defined and that solves that
    > problem.


    ....well, unless undef is *also* a valid return value :). Also (to the
    OP) note that testing for defined is perfectly possible in current
    perls, just rather awkward:

    {
    my $html;

    sub foo {
    defined $html or $html = load_as_string(...);
    }
    }

    An alternative solution to look into is Memoize. It has a rather
    different set of appropriate uses, but if you [one] find yourself
    [s himself] creating a whole lot of these loaded-only-once variables it
    may be easier just to memoize the loading function.

    Ben

    --
    Although few may originate a policy, we are all able to judge it.
    Pericles of Athens, c.430 B.C.
     
    Ben Morrow, Mar 21, 2007
    #5
  6. dt

    Uri Guttman Guest

    >>>>> "BM" == Ben Morrow <> writes:

    BM> Quoth Uri Guttman <>:
    >>
    >> easy. just declare it my in a block that also includes the sub:


    BM> <code snipped>

    BM> I was going to say 'in 5.10 this exact feature has been included, as the
    BM> new 'state' variables', but perlsub says

    BM> | B<Caveat>: the code at the right side of the assignment to a state
    BM> | variable will be executed every time; only the assignment is disabled.
    BM> | So, avoid code that has side-effects, or that is slow to execute. This
    BM> | might be optimized out in a future version of Perl.

    BM> Doesn't this make state variables, uh, rather useless? Given that they
    BM> are basically exactly equivalent to your example above, so all you save
    BM> is one compile-time block? Have I missed something?

    well, it works fine for expressions with no side effects from what i
    understand. so you can initilize it one time and the other times it gets
    executed the expression results are tossed away. it would work in the
    OP's example but it would cost a full file slurp each time. but if you
    did something like state $foo = [ 1, 2, 3 ] then you would have that
    only assigned the first time and then the [ 1, 2, 3] would still be
    evaluated and then tossed away. yes it is clunky and not optimized. if
    you care, then use the my in a private block with the sub and ||=.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Mar 21, 2007
    #6
  7. dt

    -berlin.de Guest

    Ben Morrow <> wrote in comp.lang.perl.misc:
    >
    > Quoth Uri Guttman <>:
    > > >>>>> "d" == dt <> writes:

    > >
    > > d> a datatype such as:
    > >
    > > d> cache $html = load_as_string($fh, "filename.html");
    > >
    > > d> would be really cool. basically, if the var is not set, it sets the
    > > d> var. if it is set, it skips the call.
    > >
    > > but you can't declare and also optionally assign. where would a preset
    > > value come from??
    > >
    > > d> it would have to still be there if the function is exited and recalled
    > > d> (same scope as our).
    > >
    > > easy. just declare it my in a block that also includes the sub:

    >
    > <code snipped>
    >
    > I was going to say 'in 5.10 this exact feature has been included, as the
    > new 'state' variables', but perlsub says
    >
    > | B<Caveat>: the code at the right side of the assignment to a state
    > | variable will be executed every time; only the assignment is disabled.
    > | So, avoid code that has side-effects, or that is slow to execute. This
    > | might be optimized out in a future version of Perl.
    >
    > Doesn't this make state variables, uh, rather useless? Given that they
    > are basically exactly equivalent to your example above, so all you save
    > is one compile-time block? Have I missed something?


    No, they're not useless because they keep their value from one call to
    another, while still being lexical variables. Currently, we must
    declare a lexical variable outside the sub for that purpose.

    Anno
     
    -berlin.de, Mar 21, 2007
    #7
  8. dt

    -berlin.de Guest

    Uri Guttman <> wrote in comp.lang.perl.misc:
    > >>>>> "a" == anno4000 <-berlin.de> writes:

    >
    > a> Uri Guttman <> wrote in comp.lang.perl.misc:
    > >> >>>>> "d" == dt <> writes:
    > >>

    > d> I find the following useful and would like to see it as a new perl
    > d> feature:
    > >>

    > d> I often have to cache a variable based on a complex function. it owuld
    > d> be nice if perl had something like this built in. here is an example:
    > >>

    > d> our $html;
    > >>
    > >> that will mean $html is undef. where would another value come from?

    >
    > a> From anywhere, it's a package variable. Unlike "my", "our" doesn't
    > a> reset the value at run time.
    >
    > of course i know what our is.


    I know you do, but what you said seemed to imply otherwise.

    Anno
     
    -berlin.de, Mar 21, 2007
    #8
  9. dt

    DJ Stunks Guest

    On Mar 21, 12:46 pm, "dt" <> wrote:
    > if ($html !~ /./)
    > <snip>
    > basically, if the var is not set...


    this is a very poor test for "set"-ness

    how about defined() or length()

    -jp
     
    DJ Stunks, Mar 21, 2007
    #9
  10. dt

    Ben Morrow Guest

    Quoth -berlin.de:
    > Ben Morrow <> wrote in comp.lang.perl.misc:
    > >
    > > I was going to say 'in 5.10 this exact feature has been included, as the
    > > new 'state' variables', but perlsub says
    > >
    > > | B<Caveat>: the code at the right side of the assignment to a state
    > > | variable will be executed every time; only the assignment is disabled.
    > > | So, avoid code that has side-effects, or that is slow to execute. This
    > > | might be optimized out in a future version of Perl.
    > >
    > > Doesn't this make state variables, uh, rather useless? Given that they
    > > are basically exactly equivalent to your example above, so all you save
    > > is one compile-time block? Have I missed something?

    >
    > No, they're not useless because they keep their value from one call to
    > another, while still being lexical variables. Currently, we must
    > declare a lexical variable outside the sub for that purpose.


    Yes, I realise that. What I was saying is that if

    sub foo {
    state $foo;
    ...;
    }

    is equivalent to

    {
    my $foo;
    sub foo {
    ...;
    }
    }

    is this really terribly useful? I suppose if you had something like

    sub foo {
    # lotsa stuff

    {
    state $foo;
    ...;
    }
    }

    then you've gained a decrease in scope, but why not just use another
    sub? Is there some other use case I'm missing?

    Ben

    --
    #!/bin/sh
    quine="echo 'eval \$quine' >> \$0; echo quined"
    eval $quine
    # []
     
    Ben Morrow, Mar 22, 2007
    #10
  11. dt <> wrote:

    > if ($html !~ /./)
    > {
    > $html = load_as_string($fh, "filename.html");
    > }


    > if the var is not set, it sets the
    > var. if it is set, it skips the call.



    But it would *not* skip the call if

    $html = "\n";

    ....


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Mar 22, 2007
    #11
  12. dt

    -berlin.de Guest

    Ben Morrow <> wrote in comp.lang.perl.misc:
    >
    > Quoth -berlin.de:
    > > Ben Morrow <> wrote in comp.lang.perl.misc:
    > > >
    > > > I was going to say 'in 5.10 this exact feature has been included, as the
    > > > new 'state' variables', but perlsub says
    > > >
    > > > | B<Caveat>: the code at the right side of the assignment to a state
    > > > | variable will be executed every time; only the assignment is disabled.
    > > > | So, avoid code that has side-effects, or that is slow to execute. This
    > > > | might be optimized out in a future version of Perl.
    > > >
    > > > Doesn't this make state variables, uh, rather useless? Given that they
    > > > are basically exactly equivalent to your example above, so all you save
    > > > is one compile-time block? Have I missed something?

    > >
    > > No, they're not useless because they keep their value from one call to
    > > another, while still being lexical variables. Currently, we must
    > > declare a lexical variable outside the sub for that purpose.

    >
    > Yes, I realise that. What I was saying is that if
    >
    > sub foo {
    > state $foo;
    > ...;
    > }
    >
    > is equivalent to
    >
    > {
    > my $foo;
    > sub foo {
    > ...;
    > }
    > }
    >
    > is this really terribly useful?


    That is, of course, a judgement call.

    I have never been happy about having to use a bare block, and an extra
    level of indentation, just to introduce a state-keeping variable.

    Bare blocks containing lexicals and a set of functions to access them
    are a useful means for structuring code. If you *have* to use that
    technique for a single function and one or a few (state-) variables that
    are conceptually part of the sub, that blurs the image and makes the
    structure less obvious.

    > I suppose if you had something like
    >
    > sub foo {
    > # lotsa stuff
    >
    > {
    > state $foo;
    > ...;
    > }
    > }
    >
    > then you've gained a decrease in scope, but why not just use another
    > sub? Is there some other use case I'm missing?


    I don't know of any though I'm sure people will come up with the
    weirdest uses for state variables. It's a small step that gets rid
    of a small nuisance in Perl programming.

    Compare it to the introduction of the fat comma "=>". All it does is
    allow barewords on its left, a ridiculously small difference in the
    abstract. Yet it has become very much part of the language.

    Anno
     
    -berlin.de, Mar 22, 2007
    #12
    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. Brian Birtle
    Replies:
    2
    Views:
    2,070
    John Saunders
    Oct 16, 2003
  2. Michele Simionato

    feature request: a better str.endswith

    Michele Simionato, Jul 18, 2003, in forum: Python
    Replies:
    24
    Views:
    782
    Peter Hansen
    Jan 9, 2004
  3. Daniel Ortmann
    Replies:
    0
    Views:
    259
    Daniel Ortmann
    Oct 13, 2003
  4. Michele Simionato
    Replies:
    16
    Views:
    467
    Terry Reedy
    Mar 2, 2004
  5. Thomas Guettler

    Feature Request: Current time in traceback

    Thomas Guettler, Aug 20, 2004, in forum: Python
    Replies:
    2
    Views:
    240
    Jeff Epler
    Aug 21, 2004
Loading...

Share This Page