No way to do neat ternary IF variable setting?
Asked Answered
D

8

0

In other languages you can do
var foo = a[0] | b
which sets foo to a[0] unless it evaluates as false (undefined, null, false etc), then it sets it to b.

It looks like in godot you have to do
var foo = a[0] if a[0] else b
which is an unfortunate repeat of a[0] meaning you either have to define a[0] to a new variable first, or look it up twice...

Dunno answered 27/11, 2023 at 14:57 Comment(0)
R
0

Dunno or look it up twice

GDScript is likely optimized not to do so under the hood.

Roanne answered 27/11, 2023 at 15:2 Comment(0)
S
0

Dunno You are correct.

Sarsenet answered 27/11, 2023 at 15:2 Comment(0)
S
0

Roanne Sadly looks like it isn't.

var prop: bool:
    get:
        print("You called?")
        return true

func _ready() -> void:
    print(prop if prop else false)
You called?
You called?
true

But prop gets evaluated only once if it returns false at least.

Although... thinking about it. This is a property with a getter so it makes sense that it needs to be evaluated every time. Maybe it only gets evaluated once if its just plain old data like an int or bool.

Sarsenet answered 27/11, 2023 at 15:10 Comment(0)
R
0

Sarsenet Yeah function call is not optimized but array lookup might be. Maybe this is worth putting up as an issue on Godot's github.

Roanne answered 27/11, 2023 at 15:16 Comment(0)
S
0

That could be a breaking change, if someone's code depends on the behavior as in Toxe's example. (I'm not recommending writing code that depends on side effects such as that.)

That's a deficiency in the Godot documentation. Many details are not specified, and you have to experiment or look at the source code to find out how things work.

Solace answered 27/11, 2023 at 15:27 Comment(0)
D
0

Thanks for the discussion. In this case I'm reading a lot of key mappings and need it to be a blank string if there's no mapping so InputMap.action_get_events("ui_accept")[0].as_text()

I'm currently thinking of storing the length of the action events and then using that for the boolean test.

var actionCount = InputMap.action_get_events("ui_accept").size()
UiAcceptButton1.text = InputMap.action_get_events("ui_accept")[0].as_text() if actionCount >= 1 else ""
UiAcceptButton2.text = InputMap.action_get_events("ui_accept")[1].as_text() if actionCount >= 2 else ""
UiAcceptButton3.text = InputMap.action_get_events("ui_accept")[2].as_text() if actionCount >= 3 else ""
UiAcceptButton4.text = InputMap.action_get_events("ui_accept")[3].as_text() if actionCount >= 4 else ""

Dunno answered 27/11, 2023 at 15:28 Comment(0)
R
0

Dunno Umm, why is this not done in a loop? Call action_get_events() once and iterate over the returned array.

var buttons = [UiAcceptButton1, UiAcceptButton2, UiAcceptButton3, UiAcceptButton4]
var events = InputMap.action_get_events(&"ui_accept")
for b in buttons: b.text = ""
for i in events.size(): buttons[i].text = events[i].as_text()
Roanne answered 27/11, 2023 at 15:36 Comment(0)
W
0

I started a discussion in the proposals repo a few months back suggesting a better ternary alternative. It didn't gain too much traction, but now it seems to me like most discussions don't.

https://github.com/godotengine/godot-proposals/discussions/7202

Waggery answered 27/11, 2023 at 18:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.