Your Digital Media Has Never Looked So Good

 
EnTerr
** Valued Community Member **
Topic Author
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

BrS: comparing 2 objects for identity?

Sat Oct 11, 2014 11:43 pm

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.
Last edited by EnTerr on Wed Oct 15, 2014 9:42 pm, edited 3 times in total.
 
greubel
Posts: 694
Joined: Wed Feb 10, 2010 4:21 pm

Re: BrS: comparing 2 objects for identity?

Sun Oct 12, 2014 11:36 am

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
 
User avatar
RokuMarkn
Roku Engineering
Posts: 1582
Joined: Mon Jun 09, 2008 9:20 am

Re: BrS: comparing 2 objects for identity?

Sun Oct 12, 2014 12:48 pm

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

--Mark
 
EnTerr
** Valued Community Member **
Topic Author
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

Re: BrS: comparing 2 objects for identity?

Sun Oct 12, 2014 4:47 pm

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?
Last edited by EnTerr on Wed Oct 15, 2014 9:34 pm, edited 1 time in total.
 
User avatar
TheEndless
** Valued Community Member **
Posts: 9232
Joined: Mon Oct 04, 2004 10:15 am
Location: US
Contact:

Re: BrS: comparing 2 objects for identity?

Sun Oct 12, 2014 4:55 pm

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)
 
greubel
Posts: 694
Joined: Wed Feb 10, 2010 4:21 pm

Re: BrS: comparing 2 objects for identity?

Sun Oct 12, 2014 5:11 pm

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 ???
 
User avatar
TheEndless
** Valued Community Member **
Posts: 9232
Joined: Mon Oct 04, 2004 10:15 am
Location: US
Contact:

Re: BrS: comparing 2 objects for identity?

Sun Oct 12, 2014 7:49 pm

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)
 
greubel
Posts: 694
Joined: Wed Feb 10, 2010 4:21 pm

Re: BrS: comparing 2 objects for identity?

Sun Oct 12, 2014 8:03 pm

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
 
EnTerr
** Valued Community Member **
Topic Author
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

Re: BrS: comparing 2 objects for identity?

Thu Jan 14, 2016 1:22 am

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.
 
sdpetersen
Posts: 9
Joined: Fri Oct 26, 2018 5:33 am

Re: BrS: comparing 2 objects for identity?

Fri Nov 30, 2018 7:21 am

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.
 
User avatar
Komag
Posts: 748
Joined: Fri Aug 22, 2014 3:42 am

Re: BrS: comparing 2 objects for identity?

Sun Dec 02, 2018 12:05 am

That seems like it would work, but holy cow, two big string conversions and a super giant string compare!

Who is online

Users browsing this forum: No registered users and 3 guests