Probably also obvious to those who've tried it, but you can do the same thing with HTML::Template. I realized it only very recently.
I originally had a drop-down list that I coded similar to:
(the values came out of a database lookup), but that lost the stickiness. I then realized I could cook up the select in CGI, and pass it to the template. So the only thing in the template file was just <tmpl_var name="the_whole_select"><select name="the_thing"> <tmpl_loop name="select_thing"> <option value="<tmpl_var name="select_value">"> <tmpl_var name="select_tag"> </option> </tmpl_loop> </select>
and I passed it the result of $q->popup_menu, and presto, stickiness returned. It's just a slight variation. (BTW, those samples are from memory, so there may be some inaccuracies in there.)
The nice thing about it is that all the "real" presentation stuff is still in the template; it's a lot more convenient than before, with a very slight loss of maintainability.