Forum Discussion

Komag's avatar
Komag
Roku Guru
9 years ago

Is there way to copy an object instead of creating a reference?

If I have a variable A that is an array full of associative arrays, and I set B = A, it's just a reference

Even if I do FOR EACH element in A, B.Push(element), later when I mess around with the elements, I can still go into A and see the changes! So each element (each associative array) was just referenced, not copied.

How can I copy it, make a truly separate object?

11 Replies

  • For my money, adding such "feature" is undesirable - its danger is people don't realize how deep copy they are making - not to mention this cannot be done well/easy if the structure has cycles (pointer loops) in it. Something that makes B/S work hard (e.g. deep copy of complex structures) should be something that takes longer for the developer to type, so they feel a tiny bit of the burden too.

    If you know your data to be acyclic and really, really want to do a deep copy, then use TheEndless's function or marshall/unmarshall through JSON string:
    deep_copy_obj = parseJSON(formatJSON(source_obj))
  • My own solution was to drill down another layer in my copying process and copy each property of each associative array (which properties are each Intrinsic values so they truly get copied and not referenced), building all new associative arrays to put into B one at a time. It's working as desired, leaving A pristine.

    EDIT - found this old thread that talks about it more:
    https://forums.roku.com/viewtopic.php?f=34&t=57775

    It would be nice to have a copy command in BrightScript that we could use to force a new copy instead of a reference.
  • destruk's avatar
    destruk
    Streaming Star
    Yeah I have had to do this before.  +1 to your request for the option to allow for making a new copy.
  • destruk's avatar
    destruk
    Streaming Star
    Interesting "fix" 🙂
    I suppose the code profiler should be enabled to see which way is quicker - formatting json and decoding from json, or simply typing the lines to create and copy the fields.
  • "destruk" wrote:
    Interesting "fix" 🙂
    I suppose the code profiler should be enabled to see which way is quicker - formatting json and decoding from json, or simply typing the lines to create and copy the fields.

    Keep me posted on your findings 🙂
    But seriously, you shouldn't be getting yourself into situations that require deep copying of nested structures. Roku is designed with a very specific focus on video streaming. 
  • destruk's avatar
    destruk
    Streaming Star
    RokuNB - There are many cases where the 'byreference' model is detrimental.  If you add content to a playlist by reference, when the playlist is done it removes the content from the source of the items from the previous screen.  I could make a few examples if you want to see them.  Say I have a list of content on the main screen, then when a user picks one it displays a second screen (by reference), then there is a springboard screen which populates by reference, and from the springboard screen I remove an item from the original main screen - it then disappears from the second screen too.  Since you insist on doing it this way, deep copies of a single level of data are required to work around the problem.
  • "destruk" wrote:
     Since you insist on doing it this way, deep copies of a single level of data are required to work around the problem.

    Do you mean a 1-level-deep (aka "shallow") copy by any chance? Not sarcasm, i am trying to follow your explanation. If so, there is more elegant / idiomatic way of doing it:
    ' shallow copy an array '
    array_copy = []: array_copy.append(array_origin)
    ' shallow copy a dictionary '
    roAA_copy = {}: roAA_copy.append(roAA_origin)
  • destruk's avatar
    destruk
    Streaming Star
    I am just saying with all these ways to do it, since the roku has say, 50mb or 70mb of ram available for the channel to use, and the channel package size is limited to 4mb or it won't pass certification, there should be an allowance made to duplicate your 10MB or so of json/xml data and graphics individually per screen  -- you ought to be able to handle 3-4 full copies of everything the channel could need, with cached graphics even, instead of limiting it to one instance for content.
    https://forums.roku.com/viewtopic.php?t=83002

    As it is now I feel like we have an entirely full swimming pool, but we're only allowed to put a single toe into it, and then each drop of water needs to be portioned out as a single drop to look at.  We're not utilizing the actual capabilities of the device.
  • destruk's avatar
    destruk
    Streaming Star
    Thanks for all the solutions - it's been like this for years, so I wouldn't expect it to change.  It probably wasn't as big a problem before, but with task nodes and server access becoming so dang slow I'd like to be able to do more, quicker, than it currently can.  The box itself has more power than it use to, so making it slower doesn't make much sense. - another note, using a while loop  -- like "while x<20 -- x=x+1 -- end while" in the render thread will result in an execution timeout, but executing "x=x+1" 20 times in succession doesn't, so again we'll need to run some profiling to see how to improve these situations.
  • "destruk" wrote:
    I am just saying with all these ways to do it, since the roku has say, 50mb or 70mb of ram available for the channel to use, and the channel package size is limited to 4mb or it won't pass certification, there should be an allowance made to duplicate your 10MB or so of json/xml data and graphics individually per screen  -- you ought to be able to handle 3-4 full copies of everything the channel could need, with cached graphics even

    You are missing the big picture, in which all this memory is already spoken for - video buffers, tmp:/ filesystem (you did not think it writes to flash, right) and so on. And if you have "10MB or so of json/xml data" to deal on the player, i'll go on a limb here and say "you are doing it wrong". Not to mention there is no justification for duplicating the metadata - it is still the same video, with the same properties as before.

    As it is now I feel like we have an entirely full swimming pool, but we're only allowed to put a single toe into it, and then each drop of water needs to be portioned out as a single drop to look at.  We're not utilizing the actual capabilities of the device.

    It is more like we have olympic-size swimming pool and you are annoyed for not being welcome of bathing in it. To which i say, "use the shower cabin or bathtub (depending on the player model :D) - the pool is reserved for swimming, no soap suds please"