[Templates] Accessing variables which contain period or dot in
the name
Tosh Cooey
tosh@1200group.com
Wed, 06 Jun 2007 12:11:37 +0200
No big deal, I wouldn't "fix" it since the workaround is quite
reasonable. The part about $secret(1) is really amazing, and hopefully
this email will be found by anyone who has the same problems.
Thanks for everything Andy!!
Tosh
Andy Wardley wrote:
> Tosh Cooey wrote:
> > So of course you *might* expect it to work like this:
> [...]
> > But it doesn't.
>
> Hi Tosh,
>
> Hmmm, yes. That's strange.
>
> Ah yes. Now I see. It *does* work if you do this.
>
> VARIABLES = {
> badguys => {
> 'C.I.A' => ['American', 'Dirty'],
> 'MI6' => ['British', '007'],
> 'F.S.B' => ['Russian', 'K.G.B.'] }
> },
> }
>
> [% FOREACH secret IN badguys.keys %]
> [% FOREACH keyword IN badguys.$secret %]
> [% keyword %]
> [% END %]
> [% END %]
>
> The reason is that when you've got a variable that already has a dot
> in it, like this:
>
> badguys.$secret
>
> then the parser turns it into this:
>
> $stash->get([badguys, 0, $stash->get('secret'), 0]);
>
> When passed a list ref like that, get() treats each pair of elements
> as (name, args) (with 0 indicating no args) and all is well.
>
> But when you don't have any dots in a variable, and no args,
> like this:
>
> foo
>
> the parser "optimises" it to this:
>
> $stash->get('foo');
>
> Rather than
>
> $stash->get(['foo', 0]);
>
> And if you have this:
>
> secret = 'C.I.A'
> $secret
>
> Then it gets optimised to this:
>
> $stash->set(secret => 'C.I.A');
> $stash->get($stash->get('secret'))
>
> Which is the same as:
>
> $stash->get('C.I.A')
>
> Which the stash then parses into ['C', 0, 'I', 0, 'A', 0]
> thinking you meant that dotop sequence all along because you
> passed it a string and not a list ref.
>
> So if you define C => { I => { A => [...] } } then you will
> see the values coming back, just as if you typed:
>
> [% C.I.A %]
>
> But that's not what you want :-(
>
> And just to add to the weirdness of it, if you add an argument
> to the single variable then it works because the parser no longer
> optimises it down:
>
> $secret(1)
>
> This becomes:
>
> $stash->get([$stash->get('secret'), [1]]);
>
> And the value gets returned. In this case, the (1) argument is ignored
> so it makes no difference to the outcome. Other than making it work,
> of course.
>
> So yes, I guess it is a bug. But I'll probably hold off on fixing it until
> TT3 given that it's something of an edge case. And you've got a workaround
> (just add an argument), however counter-intuitive it might be!
>
> Incidentally, this works OK:
>
> badguys.${'C.I.A'}
>
> And this will work in TT3:
>
> badguys.'C.I.A'
>
> I guess that means this will/should work, too:
>
> $'C.I.A'
>
> Cheers
> A
>
--
McIntosh Cooey - Twelve Hundred Group LLC - http://www.1200group.com/