Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
EnTerr
Level 8

BrS: comparing 2 objects for identity?

I find myself needing to check if two variables point to the same object. Here is a naive attempt that does not work (it should have said "True"):
BrightScript Debugger> A = { }
BrightScript Debugger> B = A
BrightScript Debugger> ? A = B
Type Mismatch. (runtime error &h18) in $LIVECOMPILE(1197)

Here is a practical situation: i want to display multiple elements on roScreen and that job is delegated to a Manager object. Manager's job is to keep list of the elements and redraw them as needed in the right order. Let's say each element is a roAA (contains x,y,h,w,img and other things it may need). Such elements would be added and removed dynamically. Adding is easy - but for removal when i say Manager.remove(A), it should be able to enumerate its bag and find "by reference" the element in question, then remove it. But that is not possible currently.

My request is, when comparing for equality 2 objects of the same* type: "A = B" should return True if A and B are the very same object (i.e. references are equal) and False otherwise.

Alternative approach would be to add a global function id(obj), that given an object, returns an integer. Typically (and simplest) is for that int to be the memory address of the object as a number - but the relevant/guaranteed part is that if id(A) = id(B), then A and B are the very same object (and vice versa, the relation is if-and-only-if).

(*) What should happen when trying to compare 2 objects of different type (e.g. "if { } = [ ] then ...") may vary. It may (a) be left with the current "Type Mismatch" error or (b) it may simply return False, since the two objects are not identical (the 2 memory references differ, a check as brutal as that). And by "objects" here i mean any boxed (non-intrinsic) type.
0 Kudos
10 Replies
greubel
Level 7

Re: BrS: comparing 2 objects for identity?

I don't know if this has any use but by keeping a dual index and object table resolved my problem.
I hate having to scan tables doing Lookup() for something.
This way I have a direct index to the AA object and can reorder or delete them easily using values other than the AddReplace(key).

m.History = {VID:{table:{},index:[]}, AUD:{table:{},index:[]}}
*** Insert Code ***
if fld[0] = "2"
a = m.History.VID
else
a = m.History.AUD
end if

e = a.table.Lookup( key )
if e = invalid
x = a.index.Count()
o = { Name:key, IDX:x, Type:fld[0], Pos:fld[1].ToInt(), Time:fld[2].ToInt(), IP:fld[3], Dev:fld[4] }
a.table.AddReplace( key, o )
a.index.Push( a.table.Lookup(key) )
else
Logit([ "History Dupicate entry ", key ])
end if
0 Kudos
RokuMarkn
Level 7

Re: BrS: comparing 2 objects for identity?

When I need to compare objects, I just store an unique ID number in each AA when it is created.

--Mark
0 Kudos
EnTerr
Level 8

Re: BrS: comparing 2 objects for identity?

"RokuMarkn" wrote:
When I need to compare objects, I just store an unique ID number in each AA when it is created.

Thanks Mark, i like this workaround for my case of AAs.
I like it even better than what i came up with (it was for Manager.Add(obj) to return back handle on object registration, that is to be used later to do Manager.Remove(handle) ).

How likely is it to get a general fix for this in BrS?
I.e. that roArray, roBitmap etc can be compared for identity. (Or that id(obj) would return unique ID per object)
Question has been asked before (this viewtopic.php?f=34&t=69386&p=439791#p439791 was 5mo ago) and i imagine there is opinion on that by now?
0 Kudos
TheEndless
Level 7

Re: BrS: comparing 2 objects for identity?

"greubel" wrote:
I don't know if this has any use but by keeping a dual index and object table resolved my problem.
I hate having to scan tables doing Lookup() for something.
This way I have a direct index to the AA object and can reorder or delete them easily using values other than the AddReplace(key).

m.History = {VID:{table:{},index:[]}, AUD:{table:{},index:[]}}
*** Insert Code ***
if fld[0] = "2"
a = m.History.VID
else
a = m.History.AUD
end if

e = a.table.Lookup( key )
if e = invalid
x = a.index.Count()
o = { Name:key, IDX:x, Type:fld[0], Pos:fld[1].ToInt(), Time:fld[2].ToInt(), IP:fld[3], Dev:fld[4] }
a.table.AddReplace( key, o )
a.index.Push( a.table.Lookup(key) )
else
Logit([ "History Dupicate entry ", key ])
end if

I may be interpreting that code wrong, but it seems like this will break down really fast if you ever need to delete an element from the array, unless you have a separate loop that updates every item in the AA, which could add a lot of additional overhead. Maybe I'm overlooking something, but how does this make it easier to reorder and/or delete items?

"RokuMarkn" wrote:
When I need to compare objects, I just store an unique ID number in each AA when it is created.

This is what I do as well, but that only works on AAs. Currently, there's no way at all to compare two brightscript components for equality. For example, if I wanted to check to see if two screen references or two message ports were identical, there's no way to do it. Being able to compare by reference would be a very welcome addition.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
greubel
Level 7

Re: BrS: comparing 2 objects for identity?

When you do a delete or insert, you would have to reindex the AA index values from that point to the bottom of the Array [].
But this enables you to have an AA array indexed by another key, in my case time. The AA is keyed by Title and the index is by time.
As far as overhead which is better, "for each and Lookup()" or a for i=0 to index.Count()-1 and a direct pointer to the AA ???
0 Kudos
TheEndless
Level 7

Re: BrS: comparing 2 objects for identity?

"greubel" wrote:
When you do a delete or insert, you would have to reindex the AA index values from that point to the bottom of the Array [].
But this enables you to have an AA array indexed by another key, in my case time. The AA is keyed by Title and the index is by time.
As far as overhead which is better, "for each and Lookup()" or a for i=0 to index.Count()-1 and a direct pointer to the AA ???

I'm not sure how you can avoid either one. You'll either need to loop through the AA and update all of the IDX values, or you'll need to loop through the array and rebuild the AA. Six of one, half dozen of the other as near as I can tell. Of course, as I mentioned before, I may just be misunderstanding the way you're using it.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
greubel
Level 7

Re: BrS: comparing 2 objects for identity?

For instance, this would add a new AA as the first entry.

a.index.Unshift( e )
for i=0 to a.index.Count()-1
x = a.index[i]
x.idx = i
end for
0 Kudos
EnTerr
Level 8

Re: BrS: comparing 2 objects for identity?

"RokuMarkn" wrote:
When I need to compare objects, I just store an unique ID number in each AA when it is created.

Ha, i just came with an evil hack of how to check for identity of two unknown roAA. Two objects of unknown origin, which looked to have identical key/values but i was unsure. The hack being, i tried storing a new value in one and checked it showed in the other

BrightScript Debugger> ? A = B
Type Mismatch. (runtime error &h18) in $LIVECOMPILE(93)
BrightScript Debugger> A.someBogusKey = "some bogus value"

BrightScript Debugger> ? B.someBogusKey
some bogus value 'oh okay - so A and B are the same obj

But seriously, can we get this fixed already? So that comparing objects of the same type will return true iff they references to the same object. Don't care much what to do if they are different type - either throw the "type mismatch" or false.

I have meditated over WTH this haven't been added and came with the idea maybe it was to avoid things like [ ] = [ ] and { } = { } being false (false because different objects are being constructed on each side) - which would be counter-intuitive to beginner programmers at which B/S presumably was targeted. And that's fine then - but give us instead an ID(x) function that will return the address of a reference type and that naturally can be used to compare for identity.

Actually when i think of it, ID() can have other beneficial uses, like generating runtime-unique keys that can be used to hash said objects.
0 Kudos
sdpetersen
Level 7

Re: BrS: comparing 2 objects for identity?

Finding this post 4 years later, I was looking for a way to compare arrays as well. I came up with what I feel is a pretty decent hack: convert the arrays to strings and then compare them.

When you want to do this:
if m.top.array = newArray


Do this instead:
if FormatJSON(m.top.array) = FormatJSON(newArray)


I'm sure this runs into trouble for arrays that have all the same elements in a different order, but if you're just trying to figure out if a referenced array is the same as the original, this should do the trick. This should also work well for comparing Associative Arrays, since Brightscript always outputs them in the same order.
0 Kudos