Change value of string in a list?

BlitzMax Forums/BlitzMax Programming/Change value of string in a list?

Russell(Posted 2009) [#1]
I can read through a list and cast to whatever I need and change values of other objects, but for some reason I can not change the value of regular string variables in a list:
SuperStrict
Type TTest
	Field str:String
	Field a:Int
End Type

Local obj:TTest = New TTest
Local list:TList = New TList
Local myname:String = "Russell"

list.AddLast(obj)
list.AddLast(myname)

For Local a:Object = EachIn list
	Local temptest:TTest
	Local tempstring:String
	If TTest(a)
		temptest = TTest(a)
		temptest.str = "Goodbye"' THIS WORKS
		temptest.a = 10         ' THIS WORKS TOO
	ElseIf String(a)
		tempstring = String(a)
		tempstring = "Jones"	' WHY DOESN'T THIS WORK?
	EndIf
Next

I have tried various other methods and none of them change the value of the string.

Thanks in advance
Russell


tonyg(Posted 2009) [#2]
Works for me but then you don't exactly say what's wrong.


Russell(Posted 2009) [#3]
If you then go through the list you'll see that the string still equals "Russell", not "Jones" as it should be:
For Local a:Object = EachIn list
	Local temptest:TTest
	Local tempstring:String
	If TTest(a)
		temptest = TTest(a)
		Print temptest.str ' Print correctly
		Print temptest.a   ' Prints correctly
	ElseIf String(a)
		tempstring = String(a)
		Print tempstring  ' Prints "Russell" instead of "Jones"
	EndIf
Next

What code are you using to view the list after it is modified?

Russell


REDi(Posted 2009) [#4]
All you're doing there is changing the local string, it shouldn't change the value of the completely different string in the list.

for example...
local a:int=10
local b:int=0
b=a
b=10

would you expect the value of 'a' to be 10? no ;)


Russell(Posted 2009) [#5]
What I want to be able to do is add various kinds of objects, including strings, to a linked list and then to be able to modify those objects within the list. I modified the TTest object's fields with no problem and it worked exactly as expected, but how do I do the same for the string object that was added?

I see what you mean as far as changing the local string, but it actually does change the value of the first list object's fields. Run this and you'll see that the two fields of the obj:TTest object are actually changed:
SuperStrict
Type TTest
	Field str:String
	Field a:Int
End Type

Local obj:TTest = New TTest
Local list:TList = New TList
Local myname:String = "Russell"

list.AddLast(obj)
list.AddLast(myname)

For Local a:Object = EachIn list
	Local temptest:TTest
	Local tempstring:String
	If TTest(a)
		temptest = TTest(a)
		temptest.str = "Goodbye"' THIS WORKS
		temptest.a = 10         ' THIS WORKS TOO
	ElseIf String(a)
		tempstring = String(a)
		tempstring = "Jones"	' WHY DOESN'T THIS WORK?
	EndIf
Next

For Local a:Object = EachIn list
	Local temptest:TTest
	Local tempstring:String
	If TTest(a)
		temptest = TTest(a)
		Print temptest.str ' Print "Goodbye" : correct
		Print temptest.a   ' Prints 10 : correct
	ElseIf String(a)
		tempstring = String(a)
		Print tempstring  ' Prints original value "Russell" instead of "Jones"
	EndIf
Next

Any ideas on how to change the string object as well?

Russell


REDi(Posted 2009) [#6]
For Local a:Object = EachIn list
	Local temptest:TTest
	If TTest(a)
		temptest = TTest(a)
		temptest.str = "Goodbye"' THIS WORKS
		temptest.a = 10         ' THIS WORKS TOO
	ElseIf String(a)
		TLink(list.findlink(a))._value = "Jones"
	EndIf
Next

Maybe not the fastest of solutions, but I can't think of any other way of doing it.


Russell(Posted 2009) [#7]
Thanks REDI, at least there IS a way to do it! There MUST be a more efficient way, though.

Mark? Brucey? Anyone?

Russell


Perturbatio(Posted 2009) [#8]



Sledge(Posted 2009) [#9]
There MUST be a more efficient way, though.
Either wrap the string in a type or collect your objects within a TMap.


Russell(Posted 2009) [#10]
@Sledge: Yeah, I thought of that one too (and it works). But I just can't believe that a little 'ol string value can't be changed more efficiently/easily.

@Perturbio: Thanks...But YIKES! :)

Russell


REDi(Posted 2009) [#11]
@Perturbio: Thanks...But YIKES! :)


I think that's as good as its going to get.


Perturbatio(Posted 2009) [#12]
@Perturbio: Thanks...But YIKES! :)


It isn't really a big step away from using Eachin, you're simply using the same methods it uses but now have access to the link, ideally though, the list would expose the current link in it's enumerator so that you could do something like:

For Local o:Object = EachIn list

	if string(o) then
		list.enumerator.currentLink.value = "changed value"
	EndIf

Next


(The above code would obviously have some issues (i.e. nested EachIn would need more work since the enumerator in this instance would be overwritten)).

maybe if you had some way to get the enumerator for the current EachIn scope?:

For Local o:Object = EachIn list
	Local enum:TListEnum = getEachInEnum()
	if string(o) then enum then
		enum.currentLink.value = "changed value"
	EndIf
Next



Russell(Posted 2009) [#13]
What I'm wondering is: If a string is an object, doesn't that object have a field (or method to access that field) that actually stores the value for the string?

It's no big deal, really. I was just exploring linked lists and trying some things out and found it weird that it wasn't straightforward. I seem to remember that on the old Blitz Basic 2 (for the Amiga), that linked lists worked on the idea of a "current" link that BB kept track of (no TLinks, etc to be aware of) and that you could access it easily and modify the contents. It's been so long, though, that I don't remember the syntax or even how it worked completely.

Anyway, thanks everyone.

Russell


Otus(Posted 2009) [#14]
What I'm wondering is: If a string is an object, doesn't that object have a field (or method to access that field) that actually stores the value for the string?


BlitzMax strings are immutable (as in many languages). However, if you don't change the length you *could* write over the memory, but then any copies of that string would also change... Not a good idea.

I would just use Remove and Add-methods - the performance effect won't be too much unless you are doing something extreme, in which case Perturbio's code is the way to go.


Russell(Posted 2009) [#15]
Thanks, everyone.

Russell