Android Question Read a list from a Map

iCAB

Well-Known Member
Licensed User
Longtime User
Hi There

I had this code working properly for years.
I am not sure at which point it started to behave weird, but I am using B4A 10.2

B4X:
Public Sub ISET_EventsLog_Get(lstEvents As List) As List
    
    lstEvents.Initialize
    
    If mINTSettingMap.ContainsKey(CISET_DEBUG_EVENTS_LOG) = True Then
            'reads the list as written
        Dim lst1 As List  = mINTSettingMap.Get(CISET_DEBUG_EVENTS_LOG)       
        
            'reads back an empty list
        lstEvents = mINTSettingMap.Get(CISET_DEBUG_EVENTS_LOG)       
    End If

    Return lstEvents
End Sub

I am attaching a sample project, so you can reproduce the problem (it gets even worse with the sample project)
Please read the comments inside "GetCards"
 

Attachments

  • MapListTest.zip
    9.5 KB · Views: 80

DonManfred

Expert
Licensed User
Longtime User
B4X:
Sub Button1_Click
    xui.MsgboxAsync("Hello world!", "B4X")
 
    Dim lstCardsList As List
    lstCardsList.Initialize
 
    For iIndex = 0 To 5
        Dim TCard1 As TestType
        TCard1.Initialize
        TCard1.CardNumber = "1234" & iIndex
        TCard1.CVV = NumberFormat2(iIndex, 3, 0,0,False )
     
        lstCardsList.Add(TCard1)
    Next
    Log($"Size of Cards List: ${lstCardsList.Size}"$)
    mSettings.Put( "Cards", lstCardsList )

    Dim lstNothingReadBack As List
    lstNothingReadBack.Initialize
    GetCards(lstNothingReadBack)
    Log($"Size of Cards List: ${lstNothingReadBack.Size}"$)

 
End Sub



Private Sub GetCards( lstCards As List)
 
 
        'Doesn't read back anything
    ' NO REASON to initialize the given list!!!!!
    'lstCards.Initialize
    'lstCards = mSettings.Get("Cards")

  ' Dim lstLocalCards As List
   lstLocalCards.Initialize
   lstLocalCards.AddAll(mSettings.Get("Cards"))

    For iIndex = 0 To lstLocalCards.Size -1
        Dim TCard1 As TestType
        TCard1.Initialize
        TCard1 = lstLocalCards.Get(iIndex)
        lstCards.Add( TCard1 )        'lstLocalCards2 Size increases by 1
    Next

 
    'Return lstLocalCards2    'Size 18 entries ; second round size 54
' As you are given a List. Use use this list. No need to return it
End Sub

 
Last edited:
Upvote 0

iCAB

Well-Known Member
Licensed User
Longtime User
Hi Don,

The inner initialization and returning the list were simply added for testing purposes.
The original code didn't have any of that.

2 things in here:
1. This exact same code worked for couple of years and now it doesn't work, why?
2. Why adding items to the local list in the sample code, affected the the list passed to the function?

This doesn't make any sense.

Thanks,
iCAB
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
This is a programming mistake:
B4X:
lstCards.Initialize
lstCards = mSettings.Get("Cards")
See the "code smells" link in my signature.

You are correct that this code did work in the past although it shouldn't. It was related to a bug that was fixed.

Assigning a variable should never affect previous references

This means that:
B4X:
GetCards(MyList)

Private Sub GetCards( lstCards As List) As List
    lstCards = mSettings.Get("Cards") 'this will never affect the original MyList object
 
Upvote 0

iCAB

Well-Known Member
Licensed User
Longtime User
Sorry Erel, I didn't understand what you meant by the above.

Is the code below supposed to work or not?

B4X:
Private Sub GetCards_3( lstCards As List)
    lstCards = mSettings.Get("Cards")
End Sub

if not, why?
 
Upvote 0

iCAB

Well-Known Member
Licensed User
Longtime User
This used to work perfectly ok, and I believe it is still working with B4I (if I am not mistaken).

So do I have search the code and change it everywhere now? -- I hope not :(

is this the replacement code?
B4X:
Private Sub GetCards_3( lstCards As List)
    lstCards.AddAll( mSettings.Get("Cards"))
End Sub
 
Upvote 0

iCAB

Well-Known Member
Licensed User
Longtime User
ok thanks, let me start working on it.
But just for me to know if this is going to impact other areas where a list is passed as a parameter.

Is the issue related to the "get" operation or to the list as a parameter?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Is the issue related to the "get" operation or to the list as a parameter?
No and no.

It is related to:
B4X:
Sub SomeSub (SomeType Par1)
 Par1 = SomethingElse
End Sub

SomeSub (MyPar)
MyPar will never be affected by the assignment of SomethingElse to Par1.

There was a bug in older versions of B4X where in some cases this wasn't true (related to an underlying wrapping feature).
 
Upvote 0

iCAB

Well-Known Member
Licensed User
Longtime User
Sorry to keep going back and forth, but I have this type of code all over.

Based on our discussions

lstCard1 is ok in the code below
B4X:
Private Sub GetCards_3( lstCards As List)
        Dim lstCards1 As List =  mSettings.Get("Cards")
End Sub

and lstCards2 is ok in the code below
B4X:
Dim lstCards2 As List = GetCards_3

Private Sub GetCards_3() As List
    Return mSettings.Get("Cards")
End Sub

It seems that the issue is related to implicit casting. Where implicit casting is used, the code is fine.
Can I assume that at least?

Thanks,
iCAB
 
Upvote 0
Top