> > As people have said, DWIM sez [% IF array %] should be true only if array
> > contains something more than nothing.
> 
> As far as I know, there's no way to do this without re-writing large parts
> of TT.  Even then, I don't think it's possible.
> 
> The Perl code generated for 
> 
>   [% IF array %] 
> 
> looks like 
> 
>   if ($stash->get('array'))

It is possible, although probably not a great idea.  What you could do
is add a new rule to Parser.yp for a boolean expression, which is just
expr, but the action wraps the result in a function call that computes
trueness.  Something like:

    bool_expr:      expr        { "expr2boolean($_[1])" }

expr2boolean() is a sub that is a no-op for a scalar, and returns true
for non-empty array refs and hash refs.

Then you replace rules that expect boolean expressions with bool_expr,
such as IF, WHILE, the first expr in ?:, and perhaps the lhs of ||
and &&.  The generated code for the IF example above would then
look like:

    if (expr2boolean($stash->get('array')))

while other expressions and assignments would be unchanged.

> Perhaps the best solution is to have a '.size' method which works
> consistently across all data types:
> 
>   [% item.size %]    # 1
>   [% hash.size %]    # scalar(keys %$hash)
>   [% list.size %]    # scalar(@$list)
> 
> It's not as DWIMmy as [% IF something %], but at least you could then be
> sure that [% IF something.size %] will always work as expected.

I prefer the idea of an operator to changing the grammar.  How about
".true"?  That has the right connotation (check for "trueness") without
confusion over length/size etc.  Then you can write:

    [% IF array.true %]

Other ideas might be "nonempty" (a bit clunky) or ".boolean".

Craig


Reply via email to