hairyhenderson / gomplate

A flexible commandline tool for template rendering. Supports lots of local and remote datasources.
https://gomplate.ca
MIT License
2.67k stars 182 forks source link

Unexpected behavior of evaluating "index" in "test.Ternary" #2222

Open rmrnc opened 1 month ago

rmrnc commented 1 month ago

Hi Maybe it's just me, but somehow the semantic of gomplate's test.Ternary processing the result of index eludes me.

$ gomplate --version

gomplate version 4.1.0
$ echo '{ "key": "value"  }' | gomplate --context .=stdin:///in.json \
    --in '{{ index . "key" | ternary (index . "key") (printf "unexpected %s" (index . "key")) }}'

unexpected value

$ echo '{ "key": "value"  }' | gomplate --context .=stdin:///in.json \
    --in '{{ index . "not_a_key" | ternary (index . "not_a_key") "expected" }}'

expected                                               

Especially, when compared to

echo '{ "key": "value"  }' | gomplate --context .=stdin:///in.json \
    --in '{{ $x := "initial" }}{{ if (index . "key") }}{{ $x = (index . "key") }}{{ else }}{{ $x = "default" }}{{ end }} x={{ $x }}'

x=value

echo '{ "key": "value"  }' | gomplate --context .=stdin:///in.json \
    --in '{{ $x := "initial" }}{{ if (index . "not_a_key") }}{{ $x = (index . "key") }}{{ else }}{{ $x = "default" }}{{ end }} x={{ $x }}'

x=default

Would you mind pointing out where I went wrong?

Thank you very much

hairyhenderson commented 2 weeks ago

It may just be an over-simple example, but why are you using index when you could just refer to the item by .key?

One other issue here is that the test.Ternary expects a boolean (or boolean-like string), so feeding it "value" is indeed going to cause confusion.

The reason the second example works is that the if keyword is much broader in scope - given a non-boolean value it'll consider any non-empty value to be true. I suppose the documentation is somewhat misleading:

This is effectively a short-form of the following template:

the word "effectively" does a lot of heavy lifting there, as what I really meant was "this is similar in concept, but with subtle and very important differences" 🤦‍♂️

Perhaps simply removing that block would reduce confusion...