Re: [htmltmpl] Patch to fix global_vars and loop problem...
Brought to you by:
samtregar
From: Mathew R. <mat...@re...> - 2004-05-13 02:19:12
|
> > here you create a global variable called 'gvar' > > > $t->param(gvar =3D> "global variable"); > >=20 > > here you are creating a loop specific variable called 'gvar' > > > { loopvar =3D> "GVar should be set", gvar =3D> "Loop = GVar 1" }, > >=20 > > These two 'gvar's are two different variables.=20 > >=20 > > In this case > > > { loopvar =3D> "GVar should be blank again", gvar =3D> undef = }, > >=20 > > you are saying that the loop specific 'gvar' is not part of the loop = - ie equivalent to: > > { loopvar =3D> "GVar should be blank again" } >=20 > here is where i think we differ...=20 >=20 > 1. $href =3D { loopvar =3D> "GVar should be blank again", gvar =3D> = undef } > to me (and in general perl programming is VERY different from:=20 > 2. $href =3D { loopvar =3D> "GVar should be blank again" } umm... not quite... Perl treats 'unknown' and 'undef' as the same thing = if "use strict" is in effect (which it always should be) - and this is a = compile-time test. (Aside: I think 'exists' on a plain scalar / = array_ref would solve this problem - but Perl doesn't have that = capability). Perl will try to lookup 'gvar' in its symbol table. If the value = doesn't exist in the symbol table, then any use of the 'gvar' gets = flagged as a warning - this is a run-time test. Hash'es on the other hand, always get autovivified, thus 'exists' makes = sense. Relating this to TMPL_LOOP's... the question becomes, "Is a variable = inside a loop considered to be equivalent to a hash key, or equivalent = to a variable?", alternatively it could be asked "What is the = 'strict'ness of TMPL_LOOP variables (as compared to Perl's use of = 'strict'ness)?". =20 > In (1), you are explicitely saying that you want "gvar" to be = undefined. > In (2), you are not saying that... you are effectively saying that you > don't care what "gvar" is... no - in (2) I said nothing about gvar - I didn't say "I dont care" =20 > To see how perl treats them differently, here is an example of a very > common function (keys) that returns all the keys in a hash...=20 >=20 > (1) perl > print "Keys: ". join(',', keys %$href) . "\n"; > (1) output> Keys: gvar,loopvar >=20 > (2) perl > print "Keys: ". join(',', keys %$href) . "\n"; > (2) output> Keys: loopvar Since we are talking about TMPL_LOOP variables, not Perl hash keys, it = gets back to the question(s) posed above. > Another example: >=20 > -- test.pl -- > #!/usr/bin/perl > my $tvar =3D "this is a test"; > $tvar =3D undef; > print "Tvar=3D$tvar\n"; > ----------------------------------------- > The above prints: Tvar=3D true - but only if you dont do: use strict; use warnings; ... and I cant find a single reference suggesting to not use the 'use's. > Now, so in the same context if "undef" should mean... take the outer > scope, then perl should have ignored my "$tvar =3D undef" line...=20 No - setting a value to 'undef' means - "remove me from the symbol = table" - it doesnt mean, "make my value to be 'undef'" (although you get = this behaviour if 'use strict' is not in effect). > I think its definitely a bug :-)=20 > It has infact been flagged before as well... its partially on a thread > at: > = http://www.mail-archive.com/htm...@li.../msg= 00728.html > although that thread digressed a bit... but this topic has been bought > up a few times... so maybe we can find more threads about it in the > history of the list...=20 fair enough - although, that doesn't constitute a reason to modify the = behaviour. A change to the code, should require us to agree on the = answer to the question(s) posed above. Mathew >=20 >=20 >=20 >=20 >=20 > >=20 > > thus requesting the outer global gvar to come into scope. > >=20 > > Consider: > >=20 > > t->param(gvar =3D> "Global gvar"); > > my $gvar_val; > > my @loop; > > for.... { > > if (something) { > > $gvar_val =3D "Loop GVar 1"; > > } elsif (somethign else) { > > $gvar_val =3D ""; > > } > > my $tmp; > > $tmp->{loopvar} =3D ...; > > $tmp->{gvar} =3D $gvar; > > push @loop, $tmp; > > } > > t->param(testloop =3D>\@loop); > >=20 > > What would you expect the TMPL_LOOP to do in that example?=20 > > I would have expected that the third iteration to use the global = gvar value. > >=20 > > Mathew > >=20 > >=20 > > > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > > test.tmpl: > > > ---------- > > > Global Variable gvar is: <tmpl_var name=3Dgvar> > > >=20 > > > Loop: <tmpl_loop name=3Dtestloop> > > > loopvar: <tmpl_var name=3Dloopvar> > > > gvar : <tmpl_var name=3Dgvar> > > > </tmpl_loop> > > > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > > test.pl > > > ------- > > >=20 > > > use strict; > > > use HTML::Template; > > >=20 > > > my $t =3D new HTML::Template(filename =3D> "test.tmpl", = global_vars =3D> 1,) > > > || die; > > >=20 > > > my $testloop =3D [ > > > { loopvar =3D> "GVar should be set", gvar =3D> "Loop = GVar 1" }, > > > { loopvar =3D> "GVar should be blank", gvar =3D> "" = }, > > > { loopvar =3D> "GVar should be blank again", gvar =3D> undef = }, > > > ]; > > >=20 > > > $t->param(gvar =3D> "global variable"); > > > $t->param(testloop =3D> $testloop); > > > print $t->output(); > > > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > >=20 > > > When you run test.pl.. you get the following output: > > > = ------------------------------------------------------------------------ > > > Global Variable gvar is: global variable > > >=20 > > > Loop:=20 > > > loopvar: GVar should be set=20 > > > gvar : Loop GVar 1 > > > =20 > > > loopvar: GVar should be blank > > > gvar :=20 > > > =20 > > > loopvar: GVar should be blank again > > > gvar : global variable > > > = ------------------------------------------------------------------------ > > >=20 > > > Now, the issue is that "gvar" in the third iteration of the loop, > > > "should have been blank"... i explicitely set it to "undef" in the > > > code.. however, since global_vars was on, it ignored my "undef".=20 >=20 >=20 > |