Dross has asked for the wisdom of the Perl Monks concerning the following question:

I've been modifying a trivia game (originally written by someone else) for a few weeks. They used CGI.pm extensively, which irritates me to no end, but I wanted to work with it.

I wanted to keep track of which questions had not been asked yet. So, I decided to place this list of unasked questions in a hidden field (rather than a cookie, or a file on the server.) To my surprise, this list remained the same through every post, instead of updating as I had intended.

After reviewing the code several times, becoming increasingly frustrated each time, I determined my code was fine. So, I read the freaking manual. I had no idea that state was maintained with CGI.pm when you use the HTML generating functions to print out fields. And even when I first read that state was maintained, I didn't believe that it applied to my code.

So here are my questions:

  1. Why doesn't the manual tell me how to turn off this state-maintaining feature? Is there a way to do it?
  2. Why would anyone create a feature to maintain state that will not update the state of a field if new data is provided for that field? That's just anti-common-sense to me. The server I'm working on uses v1.49. Is there a newer version available that actually changes state if asked to?

As a note to anyone else that experiences this problem, there are two ways of eleviating the situation.

The first is to not use the CGI.pm function to create the field that has irritatingly consistent data. For example: the script was using hidden() to create a hidden field, and I simply used a print statement and wrote the HTML myself.

The second is to use delete() to delete the problematic field's data before you create the field again (e.g. $query->delete('hidden_field')).

Another way of fixing this would be to turn state-maintenance off, if possible.

# Dross, Professional Dullard

Edited 2001-08-04 by Ovid

Replies are listed 'Best First'.
Re: CGI.pm: How to Stop Maintaining State
by blakem (Monsignor) on Sep 04, 2001 at 14:06 UTC
    Have you tried the -nosticky option? As in:
    use CGI qw(-nosticky :standard);
    I believe this will do what you want.

    It also looks like you can toggle it on individual calls to $q->hidden() et all, using -override=>1

    $query->hidden(-name=>'field_name', -override=>1, );

    -Blake

      Thank you, Blake. I'll look at the -nosticky and -override options, and see what I can come up with. Those are what I was looking for. It still doesn't make sense for the old material to override the new by default, though.

      # Dross, Professional Dullard

Re: CGI.pm: How to Stop Maintaining State
by chipmunk (Parson) on Sep 04, 2001 at 17:56 UTC
    Another way to handle this issue is the approach described in the documentation for CGI:
    Note, that just like all the other form elements, the value of a hidden field is "sticky". If you want to replace a hidden field with some other values after the script has been called once you'll have to do it manually: $query->param('hidden_name','new','values','here');
    I was surprised by this behavior myself when I first encountered it, but now that I'm aware of it it's very useful. In fact, the stickiness of form elements is one of my favorite features of CGI.pm, because making your form elements sticky is a big pain when you're writing the HTML yourself.
(crazyinsomniac) Re: CGI.pm: How to Stop Maintaining State
by crazyinsomniac (Prior) on Sep 05, 2001 at 10:08 UTC

    BEWARE

    Through my personal exploits, I have found that for my Win9x ActivePerl with CGI v2.76, in function mode (qw(-nosticky :standard ...), the nostick did not take. I also tried calling &CGI::nosticky(1); but to no avail.

    And No I wasn't calling any CGI methods before nosticky.

    Maybe this was fixed in a later version, or was fine in an earlier, butt, it's something to be aware of.

     
    ___crazyinsomniac_______________________________________
    Disclaimer: Don't blame. It came from inside the void

    perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"