Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
rmrnc opened this issue Sep 6, 2024 · 3 comments
Closed

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

rmrnc opened this issue Sep 6, 2024 · 3 comments

Comments

@rmrnc
Copy link

rmrnc commented Sep 6, 2024

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
Copy link
Owner

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...

@rmrnc
Copy link
Author

rmrnc commented Nov 1, 2024

Sorry, for my late reply.

why are you using index when you could just refer to the item by .key?

Unfortunately, the clumsy use of index is due to the fact, that if a key does not exist, referring to it results in an map has no entry for key error.

I suppose the documentation is somewhat misleading

I am afraid, I have to agree.

Still worse, trying to apply test.Ternary for some sort of "nil-coalescing", forces an arguably cumbersome

{{ (ne (index . "key") "") | ternary .key "some default" }}

expression. What is your take on providing a dedicated operator/function for this common situation in gomplate?

@rmrnc
Copy link
Author

rmrnc commented Nov 1, 2024

Just realized, that

'{{ (has . "key") | ternary .key "some default" }}

provides a more palatable option. I guess, that's as good as it gets.

@rmrnc rmrnc closed this as completed Nov 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants