[clear_variable] cannot be applied to nested variables?

The place to post your WML questions and answers.

Moderator: Forum Moderators

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
SlowThinker
Posts: 876
Joined: November 28th, 2008, 6:18 pm

[clear_variable] cannot be applied to nested variables?

Post by SlowThinker »

It looks to me that [clear_variable] cannot be applied to nested variables.
If this is true, it should be stressed in the wiki, or even better such a syntax should cause an error.

What happened to me:
I used

Code: Select all

{CLEAR_VARIABLE my_var1[0]}
which corrupted a content of another array my_var2

Details (probably not important):
I put 2- dimensional data in a string, then I used [split] twice in order to divide the data from the array. After 2nd [split] I tried to clear the temporary array 'input_split_lev1[$i|]' immediately:
code

Code: Select all

[multiplayer]
	id=test
	name=_"DEBUG a two-level split"
	description=_ "DEBUG a two-level split"
	map_data="{~add-ons/Conquest/maps/middle-earth_1vs1.map}" #any map works
	[event]#data input
		name=prestart
		
		## input area - edit if needed
		## input_string: 2-dimensional input data, delimiters are ';' and ',' 
		## input_split_lev1: a 1-dimensional array to which input data are split 
		## input_split_lev2: a 2-dimensional array to which input data are split 
		{VARIABLE input_string 
		"group1,1,2,3,4,5,6;
		group2,1,2,3,4,5,6;
		group3,1,2,3,4,5,6;
		group4,1,2,3,4,5,6;
		group5,1,2,3,4,5,6;
		group6,1,2,3,4,5,6;
		group7,1,2,3,4,5,6;
		group8,1,2,3,4,5,6;
		group9,1,2,3,4,5,6;
		group10,1,2,3,4,5,6;
		group11,1,2,3,4,5,6;
		group12,1,2,3,4,5,6;
		group13,1,2,3,4,5,6;
		group14,1,2,3,4,5,6
		"}		
		## end of input area

		##process input_string
		[set_variables]
			name=input_split_lev1
			[split]
				list=$input_string
				key=x
				separator=";"
			[/split]
		[/set_variables] 
		{CLEAR_VARIABLE input_string} 
		
		##process input_split_lev1[$i]
		{VARIABLE i 0} 
		[while] 
			{CONDITION input_split_lev1[$i|].x not_equals $empty}
			[do]
				[set_variables]
					name=input_split_lev2[$i|].x
					[split]
						list=$input_split_lev1[$i|].x
						key=x
						separator=","
					[/split]
				[/set_variables] 
				{CLEAR_VARIABLE input_split_lev1[$i|]} ##this line causes error: parts of input_split_lev2 are cleared
				{ERROR "$i $input_split_lev2[$i].x[0].x"}					#debug message
				{SET_LABEL 5 "$(6+$i)" ("$input_split_lev2[$i].x[0].x")}	#debug message
		
				{VARIABLE_OP i add 1} 	
			[/do]
		[/while] 
	[/event]#data input
[/multiplayer]
I work on Conquest Minus • I use DFoolWide, Retro Terrain Package and the add-on 'High Contrast Water'
I moved to Nosebane's corner (Doc Paterson's signature); I am spending my time there, so PM me if I don't answer your post in forums
User avatar
Ken_Oh
Moderator Emeritus
Posts: 2178
Joined: February 6th, 2006, 4:03 am
Location: Baltimore, Maryland, USA

Re: [clear_variable] cannot be applied to nested variables?

Post by Ken_Oh »

You sure about this? I use it all of the time. I put this into the tutorial just to be sure and it didn't produce any unexpected results.
Spoiler:
User avatar
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: [clear_variable] cannot be applied to nested variables?

Post by Pentarctagon »

Code: Select all

{CLEAR_VARIABLE my_var1[0]}
that will clear my_var1[0]. however wesnoth collapses arrays when an index is cleared, so [0] takes the value of [1], [1] takes the value if [2], etc. and the last element of the array is removed entirely.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
SlowThinker
Posts: 876
Joined: November 28th, 2008, 6:18 pm

Re: [clear_variable] cannot be applied to nested variables?

Post by SlowThinker »

Pentarctagon wrote:that will clear my_var1[0]. however wesnoth collapses arrays when an index is cleared, so [0] takes the value of [1], [1] takes the value if [2], etc. and the last element of the array is removed entirely.
Correct! It explains all. So clearing works this way and doesn't damage any other variable.
I processed + cleared my_var1 in a loop, and so a half of my_var1 was not processed (nor cleared)

I think the wiki should document this behavior - I had really a hard time to determine the problem.

Anyway it looks best way is to avoid clearing subvariables - the memory shift slows things down, also the code must be somewhat strange in order it works.
I work on Conquest Minus • I use DFoolWide, Retro Terrain Package and the add-on 'High Contrast Water'
I moved to Nosebane's corner (Doc Paterson's signature); I am spending my time there, so PM me if I don't answer your post in forums
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: [clear_variable] cannot be applied to nested variables?

Post by Sapient »

This is not because of code constraints. Not at all. It was an intentional design decision based on the requests and needs of WML authors... "clearing" an explicit index of an array is thus the way to delete and remove it from the array.

Sure, you could argue that a separate tag should have been made for "remove", but it seems just as logical for "clear" to do it. And for the rare situation where you want to set an empty container at an explicit index, there is [set_variables] mode=replace

Also, my advice about optimization is: don't worry about efficiency in WML execution until you see an actual slowdown in the game. This particular operation, for example, is never going to be a bottleneck.
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
User avatar
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: [clear_variable] cannot be applied to nested variables?

Post by Pentarctagon »

SlowThinker wrote:I think the wiki should document this behavior - I had really a hard time to determine the problem.
feel free to add it yourself, it is a wiki after all.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
SlowThinker
Posts: 876
Joined: November 28th, 2008, 6:18 pm

Re: [clear_variable] cannot be applied to nested variables?

Post by SlowThinker »

Sapient wrote:This is not because of code constraints. Not at all. It was an intentional design decision based on the requests and needs of WML authors... "clearing" an explicit index of an array is thus the way to delete and remove it from the array.
I would expect they required also an opposite operation... :hmm: except they needed it for an implementaion of a set.
Pentarctagon wrote:feel free to add it yourself, it is a wiki after all.
I don't know enough about WML, for example whether clearing containers works same way. I could easily write a wrong statement. And I don't count my weak english.

BTW may a value be assigned to array.length? The answer is another candidate for the wiki.
I work on Conquest Minus • I use DFoolWide, Retro Terrain Package and the add-on 'High Contrast Water'
I moved to Nosebane's corner (Doc Paterson's signature); I am spending my time there, so PM me if I don't answer your post in forums
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: [clear_variable] cannot be applied to nested variables?

Post by Sapient »

SlowThinker wrote: I would expect they required also an opposite operation... :hmm: except they needed it for an implementaion of a set.
Whaaa....? This whole sentence makes no sense to me, sorry.

I think you missed my statement above where I explained how to do what you wanted with [set_variables] mode=replace.
SlowThinker wrote: I don't know enough about WML, for example whether clearing containers works same way.
Clearing a container variable totally deletes it. Clear enough?
SlowThinker wrote: BTW may a value be assigned to array.length? The answer is another candidate for the wiki.
It can be done, technically speaking, but assigning length=value achieves nothing useful; if you ever tried to retrieve the variable, it would return the length of the array instead.
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
User avatar
Ken_Oh
Moderator Emeritus
Posts: 2178
Joined: February 6th, 2006, 4:03 am
Location: Baltimore, Maryland, USA

Re: [clear_variable] cannot be applied to nested variables?

Post by Ken_Oh »

I've always thought an expansion of the "How WML works" section of the WML wiki would be nice, probably in the direction of showing what the data looks like and what happens to it when altered. It wasn't until I started cracking open the save files that I gained a really useful knowledge of how to use WML.
User avatar
pauxlo
Posts: 1047
Joined: September 19th, 2006, 8:54 pm

Re: [clear_variable] cannot be applied to nested variables?

Post by pauxlo »

Sapient wrote:
SlowThinker wrote: I would expect they required also an opposite operation... :hmm: except they needed it for an implementaion of a set.
Whaaa....? This whole sentence makes no sense to me, sorry.
As I understand, he thinks about an "insert element into array, shifting following indexes up", and the only point he could think of where only one of them is needed is when one wants to model a "modifiable set" (a list which can contain each element only once, and where the order does not matter) as a WML variable.
Exasperation
Posts: 462
Joined: June 8th, 2006, 3:25 am

Re: [clear_variable] cannot be applied to nested variables?

Post by Exasperation »

pauxlo wrote:As I understand, he thinks about an "insert element into array, shifting following indexes up", and the only point he could think of where only one of them is needed is when one wants to model a "modifiable set" (a list which can contain each element only once, and where the order does not matter) as a WML variable.
If that's what he's looking for, http://wiki.wesnoth.org/InternalActions ... riables.5D says the following about [set_variables] with mode=insert
insert: will insert the given data at the index specified in the name attribute, such as name=my_array[1]. The default index is zero, which will insert to the front of the array. Note: if an invalid index is used, empty containers will be created before the insertion is performed. In other words, do not attempt to insert at an index unless the variable already contains data at that index. This limitation may be removed in future versions.
SlowThinker
Posts: 876
Joined: November 28th, 2008, 6:18 pm

Re: [clear_variable] cannot be applied to nested variables?

Post by SlowThinker »

Sapient wrote:Whaaa....? This whole sentence makes no sense to me, sorry.
I think you missed my statement above where I explained how to do what you wanted with [set_variables] mode=replace.
Pauxlo is right, I meant "set" as a data type. Anyway the opposite function ("[add_element] to a given position of an array") would not be necessarily needed for the implementation of sets: new elements can be added to the array end.
But the opposite function would be useful for things like a double-ended queue.
Sapient wrote:Clearing a container variable totally deletes it. Clear enough?
Yes, it is clear now.
I asked because it would have sense if the containers worked a similar way as arrays do:
now you can index arrays from 0 to n only. But sometimes it is useful to index them a,b,c,d,e... or red, blue, green,purple...
Ordered containers (alphabetically or by a definition) would be able to stand in for generally indexed arrays.
I work on Conquest Minus • I use DFoolWide, Retro Terrain Package and the add-on 'High Contrast Water'
I moved to Nosebane's corner (Doc Paterson's signature); I am spending my time there, so PM me if I don't answer your post in forums
SlowThinker
Posts: 876
Joined: November 28th, 2008, 6:18 pm

Re: [clear_variable] cannot be applied to nested variables?

Post by SlowThinker »

Exasperation wrote:If that's what he's looking for, http://wiki.wesnoth.org/InternalActions ... riables.5D says the following about [set_variables] with mode=insert
Thank you, this is what I talked about.


Back to the wiki at http://wiki.wesnoth.org/InternalActions ... riables.5D:
name: the name of the container to manipulate
IMO this is not correct.
"name" is the name of the array (in case of mode=replace) or the name of an array item (in case of mode=insert).

Also I don't understand the difference between "merge" and "append". And is there any reason why one talks about "the current array" and another one about "name"?
append: will append given data to the current array
merge: will merge in the given data into name
I work on Conquest Minus • I use DFoolWide, Retro Terrain Package and the add-on 'High Contrast Water'
I moved to Nosebane's corner (Doc Paterson's signature); I am spending my time there, so PM me if I don't answer your post in forums
User avatar
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: [clear_variable] cannot be applied to nested variables?

Post by Pentarctagon »

As I understand it, merge means that you can put 2 separate values into the same array index while append just makes a new index at the end of an array.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
Exasperation
Posts: 462
Joined: June 8th, 2006, 3:25 am

Re: [clear_variable] cannot be applied to nested variables?

Post by Exasperation »

I believe the difference is that append is for adding new elements to the end of an array, merge is for adding new keys into an existing array element. So if you do

Code: Select all

[set_variables]
    name=foo
    mode=replace
    [value]
        bar=1
    [/value]
[/set_variables]
[set_variables]
    name=foo
    mode=append
    [value]
        baz=2
    [/value]
[/set_variables]
you get

Code: Select all

[foo]
    bar=1
[/foo]
[foo]
    baz=2
[/foo]
which you could also get by doing

Code: Select all

[set_variables]
    name=foo
    mode=replace
    [value]
        bar=1
    [/value]
    [value]
        baz=2
    [/value]
[/set_variables]
but if you instead do

Code: Select all

[set_variables]
    name=foo
    mode=replace
    [value]
        bar=1
    [/value]
[/set_variables]
[set_variables]
    name=foo
    mode=merge
    [value]
        baz=2
    [/value]
[/set_variables]
you get

Code: Select all

[foo]
    bar=1
    baz=2
[/foo]
which you could also get by doing

Code: Select all

[set_variables]
    name=foo
    mode=replace
    [value]
        bar=1
        baz=2
    [/value]
[/set_variables]
Post Reply