Navigation

    Fuze Arena Logo
    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Popular
    • Users
    • Groups
    • Help
    • Discord

    ref does nothing when feeding array elements to a function

    Bug Reporting (FUZE 4 Nintendo Switch)
    ref
    7
    19
    850
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Z-Mann
      Z-Mann last edited by

      Consider this code:

      // simple structure
      a = [.x = 1]
      // put a copy of it into an array
      b = [a]
      
      // modify a (or a clone) by refrence
      function incByRef(ref a)
          a.x += 1
      return void
      
      print ("a.x=", a.x, "\n")
      incByRef(a)
      print ("a.x=", a.x, "\n")
      
      print ("b[0].x=", b[0].x, "\n")
      incByRef(b[0])
      print ("b[0].x=", b[0].x, "\n")
      
      update()
      sleep(10)
      

      If I haven't made any typos, this prints

      a.x=1
      a.x=2
      b[0].x=1
      b[0].x=1
      

      So directly passing 'a' in correctly modifies it in place, but 'b[0]' is left unaltered. Not what I expected, I would have thought b[0].x would get altered as well. Of course, maybe my expectations are wrong or I am doing something wrong.

      Workaround for me: In those places where pass by reference is more important than random access, use list-like structures instead. Where random access is important, well...

      c = b[0]
      incByRef(c)
      b[0] = c
      

      looks horrible and copies the element twice, but works.

      1 Reply Last reply Reply Quote 3
      • xevdev
        xevdev F last edited by

        Looks like a is a global try your function with a different input variable.

        1 Reply Last reply Reply Quote 0
        • Z-Mann
          Z-Mann last edited by

          Ah, right, that pitfall. I'll try to keep that in mind. But nope, changed the argument name of incByRef, no change in the output.
          Looks like the fact that 'a' was explicitly declared as an argument was enough information for FUZE to distinguish it from the global.

          1 Reply Last reply Reply Quote 2
          • xevdev
            xevdev F last edited by

            This works


            If you try to extend b it complains that your trying to extend a struct
            That would be
            A = [.x = 1]

            1 Reply Last reply Reply Quote 0
            • xevdev
              xevdev F last edited by xevdev

              Like here


              Seems screwy to me.
              Not really sure of the utility of the ref command
              In your case just return the value and assign it straight back
              A.x = inc(A.x)

              1 Reply Last reply Reply Quote 0
              • Z-Mann
                Z-Mann last edited by

                Thanks for the workaround suggestions. However, the real application I had in mind would not be using arrays with a single element, so turning 'b' into a plain copy of 'a' does not help. And the real structures would be potentially large and expensive to copy, and the functions where I would like to call them by ref would do more than just modify a single value.

                1 Reply Last reply Reply Quote 0
                • xevdev
                  xevdev F last edited by

                  Oops I'm a bit dumb didn't read your comments in the code.
                  So sorry I'm just trying to work out ref myself.

                  1 Reply Last reply Reply Quote 0
                  • Willpowered
                    Willpowered Fuze Team last edited by

                    Just want to let everyone know I'm currently working on the ref keyword and have my eye on this- Thanks for the report! If anyone has more condensed examples of ref not working as expected I would greatly appreciate them.

                    1 Reply Last reply Reply Quote 0
                    • vinicity
                      vinicity F last edited by

                      https://fuzearena.com/forum/topic/1342/the-ref-keyword-doesn-t-work-for-int-string-vector-struct

                      1 Reply Last reply Reply Quote 0
                      • Willpowered
                        Willpowered Fuze Team last edited by

                        Yup, that's what I'm working on! I've got ref working on my end right now for everything except strings. I still have to test the OP's code with my adjustments, they're doing something I wouldn't have expected.

                        1 Reply Last reply Reply Quote 3
                        • vinicity
                          vinicity F last edited by

                          Great! Will it work even if you change the type of the referenced variable inside the called function?

                          1 Reply Last reply Reply Quote 0
                          • Willpowered
                            Willpowered Fuze Team last edited by

                            Good question. I'll put it on my list of things to test!

                            1 Reply Last reply Reply Quote 1
                            • Willpowered
                              Willpowered Fuze Team last edited by Willpowered

                              Following up on this:

                              The issue is related to the core of how ref works internally, and while ref is currently being worked on, we've determined that this is unfortunately not something we can easily change for the next patch. The limitation in this case is that the ref keyword must be used with a defined non-member, non-element variable. A defined variable is a variable that you've declared and assigned to, which isn't a member or element of an array, structure, sprite, etc.

                              In the example in the top post, incByRef(a) works because it's passing a, which matches our definition of a defined non-member/non-element variable. incByRef(b[0]) is not currently valid because while b is a defined variable, b[0] doesn't match the criteria (it's an element of b). The workaround currently is to write an incArrayElementsByRef(ref my_array) function that accepts the array b and operates on its elements.

                              We will, however, look at expanding the ref keyword's capabilities in the future. For the next patch we'll clarify this limitation of the ref keyword in the documentation.

                              1 Reply Last reply Reply Quote 2
                              • R
                                romain337 last edited by romain337

                                Hi!
                                in setTimer

                                function increment(ref x)
                                  x += 1
                                return void
                                
                                function doSomething()
                                  var test = 0
                                  setTimer(1, 5, increment(test))
                                  loop
                                    clear()
                                    printAt(0,0, test)
                                    update()
                                  repeat
                                return void
                                
                                doSomething()
                                

                                The function is called but test is not "ref" incremented. I noticed this behavior when experimentating with timer. It could be a bug ?
                                EDIT* it seem that this will be fixed in the next release as raw type don't work when used with ref keyword if I understand.

                                1 Reply Last reply Reply Quote 0
                                • Willpowered
                                  Willpowered Fuze Team last edited by

                                  That's correct- in version 2.15.0 ref only works with arrays and structures. We're working on expanding it to all variable types for the next patch!

                                  Z-Mann 1 Reply Last reply Reply Quote 1
                                  • Z-Mann
                                    Z-Mann @Willpowered last edited by

                                    @Willpowered Thanks for the explanation! If that is now how the feature is specified, I at least know what to expect. That also explains why 3.0.0 broke this code:

                                    function incByRef(v)
                                        v.x = v.x + 1
                                    return
                                    
                                    a = [.x = 1]
                                    b = [.a = a]
                                    
                                    print("b.a.x=", b.a.x, "\n")
                                    incByRef(b.a) // not a defined variable! won't do a thing.
                                    print("b.a.x=", b.a.x, "\n")
                                    

                                    In 2.1.5, it used to increment b.a.x. Oh well, specs are specs, and at least now things are consistent. I'll be ditching complicated nested data structures I'm used to from other languages and use arrays of primitives and simple structs from now on, that's what the Cool Kids call Data Oriented Design. Many things are even easier to express that way.

                                    1 Reply Last reply Reply Quote 2
                                    • Willpowered
                                      Willpowered Fuze Team last edited by

                                      We're looking at allowing ref to work on structure members and array elements. I'll keep you posted!

                                      1 Reply Last reply Reply Quote 3
                                      • PickleCatStars
                                        PickleCatStars F last edited by

                                        Will that let us do ‘struct.thing = ref otherstruct.otherthing’?

                                        1 Reply Last reply Reply Quote 0
                                        • PB____
                                          PB____ last edited by PB____

                                          I think it means that you would be able to do something like this:

                                          function increase(ref data)
                                              data.value += 1
                                          return void
                                          
                                          example = [
                                              .member = [
                                                  .value = 1
                                              ]
                                          ]
                                          print(example.member.value, "\n")
                                          increase(example.member)
                                          print(example.member.value) // currently this value is not updated
                                          update()
                                          sleep(10)
                                          
                                          1 Reply Last reply Reply Quote 1
                                          • First post
                                            Last post