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

    SparksTheGamer or look it up twice

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

    • Toxe replied to this.

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

      • xyz replied to this.

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

        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.

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

        • xyz replied to this.

          SparksTheGamer 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()