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/

_______________________________________________
templates mailing list
[email protected]
http://lists.template-toolkit.org/mailman/listinfo/templates

Reply via email to