linkedin/dustjs — pull request #459 by fsoikin (2014-04-29 15:45:18+00:00)
Title: Made Chunk.exists and Chunk.notexists (the "?" and "^" prefixes respectively) unwrap functions the same way Chunk.section (the "#" prefix) does.

When a context property is a function, then {#Prop} will call that function and use its return value, but {?Prop} and {^Prop} will not do that.
This commit fixes this state of affairs by adding the same "function unwrapping" support to the "?" and "^" tags.

Granted, this is somewhat controversial, because the current logic is built in such a way that if the function returns an instance of Chunk, then that chunk is simply returned from Chunk.section (i.e. the function is assumed to know what it's doing and is allowed to generate its own output).
This behavior may not be best for the "?" and "^" tags (their semantics suggest that they should only _check_ for the presence of a value rather than actually render it), but at the same time, the Chunk return value can't be simply discarded either, since apparently Dust is built in such a way that the rendering state is _mutable_ rather than composable, which means that the function may have mutated the state, and therefore we can't just pretend that it was never called.

Having said all that, I think it is still preferable to have "?" and "^" call the function just like "#" does, because otherwise certain constructs become impossible. For example:

```
{?.Collection}
Here go the items:
{#.Collection}
{Name}
{/.Collection}
{?/.Collection}
```

In the above example, I can't replace the first "?" tag with a "#" tag, because then I will have rendered multiple instances of the tag's body, which is not the effect I intended to achieve.

As for the "controversial" part (i.e. the case when the function returns a Chunk instance), that seems to be the realm of high magic anyway, where the consumer is supposed to know what he's doing very precisely, and therefore, I think, it is ok to have the behavior differ in that case.

NOTE: with this change in place, all tests still pass.