Data added to Array lost 3 commands deep

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

mrcoollion
Posts: 719
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Data added to Array lost 3 commands deep

Post by mrcoollion » Thu Mar 10, 2022 4:34 pm

Hello all,

I have the following problem.
I first put data into an array aOutputData_A with key 0
then I call several commands and in the last command 'Routine_C ' I add data to array aOutputData_A with key -1 .
Although this data is available within command 'Routine_C ' as soon as i am back at the level of mouse up
that data is lost ?
How can I solve this? I need to add data to an array several levels deep.
Not even making the array variable global helps.

Copy code below in a button and test....

Code: Select all

local aOutputData_A
on mouseup
   Routine_A 0,aOutputData_A 
   --
   Routine_B "DEF",aOutputData_A,OutputData_B
   --
   put aOutputData_A[0] into tData_0
   put aOutputData_A[-1] into tData_1
   
   breakpoint
End mouseup
---
command Routine_A InNbr @aOutputData_A
   put "ABC_"&InNbr into aOutputData_A[InNbr]
end Routine_A
---
command Routine_B InData,aOutputData_A @OutputData_B
   put InData & "XYZ" into OutputData_B
   Routine_C "GHI",aOutputData_A,aOutputData_C
end Routine_B
---
command Routine_C Input,aOutputData_A @OutputData_C
   put -1 into tNbr
   Routine_A tNbr,aOutputData_A
   put Input into OutputData_C
   put aOutputData_A[0] into tData_00
   put aOutputData_A[-1] into tData_01
end Routine_C
Kind regards,

Paul

Klaus
Posts: 13806
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Data added to Array lost 3 commands deep

Post by Klaus » Thu Mar 10, 2022 6:07 pm

Very, very strange!? No idea what's going on there. :shock:

stam
Posts: 2634
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Data added to Array lost 3 commands deep

Post by stam » Thu Mar 10, 2022 6:38 pm

Hi Paul,

that's some choice spaghetti code right there ;)
I'm guessing there is another way to express the same commands that doesn't involve jumping back and forth like that (if nothing else it's makes debugging much harder!)

I'll give it a go, but first:
  • why are you referencing the script variable aOutputData_A as a parameter, when it's available as a script variable?
  • you are using undeclared variables tData_0 and tData_00, tData_1 and tData_01. I take it these differences are intentional?
  • it's weird that you include handler parameters seemingly as a declaration rather than passing data - and use the handler to assign values to it's own parameters!
  • what is the the point of this code/what are you trying to achieve?
anyway i'll play around with the code as a challenge...

edit: It would REALLY help to know what you're trying to achieve here

stam
Posts: 2634
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Data added to Array lost 3 commands deep

Post by stam » Thu Mar 10, 2022 7:06 pm

Hi Paul
Your code is very confusing and probably suffering with some circular logic errors...

take this example:

Code: Select all

local aOutputData_A

command Routine_B InData,aOutputData_A @OutputData_B
   put InData & "XYZ" into OutputData_B
   Routine_C "GHI",aOutputData_A,aOutputData_C
end Routine_B
As aOutputData_A is a script variable you should not need to pass it as a parameter within the same script
OutputData_B is passed as a parameter but is used as a variable - no data is read from this, it's only used to assign data.
You seem to be use the '@' symbol to replace the usage of script variables and makes everything extremely convoluted.
Not to mention the handler and variable naming is really quite confusing...

I've refactored your code (and given a saner naming convention, for me at least!) and this works:

Code: Select all

local sOutputA, sOutputB, sOutputC

on routine_A pFactor
	put "ABC_" & pFactor into sOutputA[pFactor]
end routine_A

on routine_B pFactor
	put pFactor & "XYZ" into sOutputB
	routine_C "GHI"
end routine_B

on routine_C pFactor
	local tNbr, tData_0, tData_1
	put - 1 into tNbr
	routine_A tNbr
	put pFactor into sOutputC

	put sOutputA[0] into tData_0
	put sOutputA[- 1] into tData_1
end routine_C

on mouseup
	local tData_0, tData_1
	routine_A 0
	routine_B "DEF"

	put sOutputA[0] into tData_0
	put sOutputA[- 1] into tData_1
	breakpoint
end mouseup
sOutputA[-1] retains it's value.
Hope this helps...
Stam

SparkOut
Posts: 2839
Joined: Sun Sep 23, 2007 4:58 pm

Re: Data added to Array lost 3 commands deep

Post by SparkOut » Thu Mar 10, 2022 10:41 pm

Not done more than skim read but I would echo stam's comments and try that code.
I also note that your handlers are declared with the parameter list separated by space, not comma. Typo?

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3990
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Data added to Array lost 3 commands deep

Post by bn » Fri Mar 11, 2022 11:33 am

Paul,

This works

Code: Select all

local aOutputData_A
on mouseup
   Routine_A 0,aOutputData_A 
   --
   Routine_B "DEF",aOutputData_A,OutputData_B
   --
   put aOutputData_A[0] into tData_0
   put aOutputData_A[-1] into tData_1
   
   breakpoint
End mouseup
---
command Routine_A InNbr @aOutputData_A
   put "ABC_"&InNbr into aOutputData_A[InNbr]
end Routine_A
---
command Routine_B InData aOutputData_A, @OutputData_B
   put InData & "XYZ" into OutputData_B
   Routine_C "GHI",aOutputData_A,aOutputData_C
end Routine_B
---
command Routine_C Input @aOutputData_A, @OutputData_C
   put -1 into tNbr
   Routine_A tNbr,aOutputData_A
   put Input into OutputData_C
   put aOutputData_A[0] into tData_00
   put aOutputData_A[-1] into tData_01
end Routine_C
it was just a bit of cleanup of your code, e.g. referencing and putting commas in where they where missing.

Kind regards
Bernd

mrcoollion
Posts: 719
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Data added to Array lost 3 commands deep

Post by mrcoollion » Sat Mar 12, 2022 1:51 pm

Hello Bernd,

Hi all,
Thanks for helping me...

I simplified the code names a bit to make it easier to read, checke comma's and @ signs and used Bernd version.
However in this version on mouse up level 'aData_A[-1] ' is still empty!
I think it has to do that the data is cahnged/added two levels deep and going back to the initial level the data is somehow lost going back from 'Routine_B ' to the highest level (on mouse up ).

I know it looks like spaghetti code but this is the situation I face. I did make a workaround but that is ugly. I still would like to understand why the added data in 'aData_A[-1] ' by calling routine Routine_A in routine Routine_C does not make it all the way up?

Code: Select all

local aData_A
on mouseup
   Routine_A 0,aData_A 
   --
   Routine_B "DEF",aData_A,tData_B
   # check if data is added to aData_A
   put aData_A[0] into tData_0 // Original data is stil there.
   put aData_A[-1] into tData_1 // Data is gone ?!
   breakpoint
End mouseup
---
command Routine_A InNbr @aData_A
   put "ABC_"&InNbr into aData_A[InNbr] // Fill array with original data.
end Routine_A
---
command Routine_B InData, aData_A @tData_B // This routine needs the data from aData_A
   put InData & "XYZ" into tData_B
   Routine_C "GHI",aData_A,tData_C // Routine_B needs Routine_C
   # check if data is added to aData_A
   put aData_A[0] into tData_B00 // Original data is stil there.
   put aData_A[-1] into tData_B01 // Data is added is available.
   breakpoint
end Routine_B
---
command Routine_C Input @aData_A, @tData_C
   put -1 into tNbr
   Routine_A tNbr,aData_A // Call Routine_A  with number is -1 so additional data is added to aData_A
   put Input into tData_C
   # check if data is added to aData_A
   put aData_A[0] into tData_C00 // Original data is stil there.
   put aData_A[-1] into tData_C01 // Data is added is available.
   breakpoint
end Routine_C


mrcoollion
Posts: 719
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Data added to Array lost 3 commands deep

Post by mrcoollion » Sat Mar 12, 2022 2:02 pm

Hi Stam,

Thanks for the example code and explenations.
As I understand, because you make the needed array a local variable I do not need to use the @ for getting the array data out of routine _A and I do not have to pass the array variable into other routines. Because if I do the behaviour changes and data can be lost.
Does 'on routinename' work any different than 'command routinename' ?

Regards,

Paul

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3990
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Data added to Array lost 3 commands deep

Post by bn » Sat Mar 12, 2022 3:49 pm

Paul,

I try to expain what is happening. You pass in handler "mouseUp"

Routine_B "DEF",aData_A,tData_B

aData_A unreferenced to Routine_B, from there it goes referenced through some permutations and comes back unreferenced to handler "mouseUp".
This means your initial value is unchanged.

A command does not return anything except for the result which you have to set and read explicitly.
The unreferenced aData_A coming back is the same as when it was sent off to Routine_B.

To show this effect you could turn Routine_B into a function and return

Like this

Code: Select all

function Routine_B InData, aData_A, @tData_B // This routine needs the data from aData_A
   put InData & "XYZ" into tData_B
   Routine_C "GHI",aData_A,tData_C // Routine_B needs Routine_C
   # check if data is added to aData_A
   put aData_A[0] into tData_B00 // Original data is stil there.
   put aData_A[-1] into tData_B01 // Data is added is available.
   breakpoint
   return aData_A
end Routine_B
and call it in mouseUp

Code: Select all

put Routine_B ("DEF",aData_A,tData_B) into aData_A
That works

However you could use the referencing trick and simply add "@" to aData_A like this

Code: Select all

command Routine_B InData, @aData_A, @tData_B
Then it keeps aData_A open for changes and you do not have to return it explicitly. (by the way in your current use "@tData_B" does not have to be referenced)

for completeness here is you revised code and just one "@" added.

Code: Select all

local aData_A
on mouseup
   Routine_A 0,aData_A 
   --
   Routine_B "DEF",aData_A,tData_B
   # check if data is added to aData_A
   put aData_A[0] into tData_0 // Original data is stil there.
   put aData_A[-1] into tData_1 // Data is gone ?!
   breakpoint
End mouseup
---
command Routine_A InNbr @aData_A
   put "ABC_"&InNbr into aData_A[InNbr] // Fill array with original data.
end Routine_A
---
command Routine_B InData, @aData_A @tData_B // This routine needs the data from aData_A
   put InData & "XYZ" into tData_B
   Routine_C "GHI",aData_A,tData_C // Routine_B needs Routine_C
   # check if data is added to aData_A
   put aData_A[0] into tData_B00 // Original data is stil there.
   put aData_A[-1] into tData_B01 // Data is added is available.
   breakpoint
end Routine_B
---
command Routine_C Input @aData_A, @tData_C
   put -1 into tNbr
   Routine_A tNbr,aData_A // Call Routine_A  with number is -1 so additional data is added to aData_A
   put Input into tData_C
   # check if data is added to aData_A
   put aData_A[0] into tData_C00 // Original data is stil there.
   put aData_A[-1] into tData_C01 // Data is added is available.
   breakpoint
end Routine_C
That it the reason why your modified code does not work.
Or at least how I understand the flow of events. I hope my attempted explanation makes some sense.

Kind regards
Bernd

stam
Posts: 2634
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Data added to Array lost 3 commands deep

Post by stam » Sat Mar 12, 2022 4:47 pm

mrcoollion wrote:
Sat Mar 12, 2022 2:02 pm
Hi Stam,

Thanks for the example code and explenations.
As I understand, because you make the needed array a local variable I do not need to use the @ for getting the array data out of routine _A and I do not have to pass the array variable into other routines. Because if I do the behaviour changes and data can be lost.
Does 'on routinename' work any different than 'command routinename' ?

Regards,

Paul
Hi Paul, as i understand it, 'on' and 'command' are the same.
When sharing data between handlers, my preference is to use script local variables, which are a bit like global variables for that script - data will not get lost.

Bernd's post explains the passing by reference '@' in more detail - for me it is less easy to troubleshoot and i'd hate to come back to this code a year later to try and figure out why something has stopped working... but that's a personal preference!

Stam

Klaus
Posts: 13806
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Data added to Array lost 3 commands deep

Post by Klaus » Sat Mar 12, 2022 5:09 pm

Hi Paul,
mrcoollion wrote:
Sat Mar 12, 2022 2:02 pm
...
Does 'on routinename' work any different than 'command routinename' ?
...
some years ago, LC advised developers to use "command handlername" for our "custom" handlers,
because "on handlername" might be reserved for LCs own handlers like "on mouseup" etc.,
but that did not happen. :-)
So there is no difference.

However some developers like stam and me still stick to this (non)convention.


Best

Klaus

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3990
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Data added to Array lost 3 commands deep

Post by bn » Sat Mar 12, 2022 5:54 pm

stam wrote:
Sat Mar 12, 2022 4:47 pm
When sharing data between handlers, my preference is to use script local variables, which are a bit like global variables for that script - data will not get lost.
Bernd's post explains the passing by reference '@' in more detail - for me it is less easy to troubleshoot and i'd hate to come back to this code a year later to try and figure out why something has stopped working... but that's a personal preference!
Stam
OK, the confusing thing for me in Paul's script was that he indeed used a script-local variable. But by passing it also to the commands it changed in scope and was not really a script-local variable anymore in the context of handler execution.

Here is a version of Paul's latest script that treats aData_A as a script local. Note that I eliminated it as a parameter when passing data to the sub handlers

Code: Select all

local aData_A
on mouseup
   Routine_A 0
   --
   Routine_B "DEF",tData_B
   # check if data is added to aData_A
   put aData_A[0] into tData_0 // Original data is stil there.
   put aData_A[-1] into tData_1 // Data is gone ?!
   breakpoint
End mouseup
---
command Routine_A InNbr
   put "ABC_"&InNbr into aData_A[InNbr] // Fill array with original data.
end Routine_A
---
command Routine_B InData, tData_B // This routine needs the data from aData_A
   put InData & "XYZ" into tData_B
   Routine_C "GHI",tData_C // Routine_B needs Routine_C
   # check if data is added to aData_A
   put aData_A[0] into tData_B00 // Original data is stil there.
   put aData_A[-1] into tData_B01 // Data is added is available.
   breakpoint
end Routine_B
---
command Routine_C Input tData_C
   put -1 into tNbr
   Routine_A tNbr // Call Routine_A  with number is -1 so additional data is added to aData_A
   put Input into tData_C
   # check if data is added to aData_A
   put aData_A[0] into tData_C00 // Original data is stil there.
   put aData_A[-1] into tData_C01 // Data is added is available.
   breakpoint
end Routine_C
If anybody is _NOT_ confused by now please say so....

Kind regards
Bernd

SparkOut
Posts: 2839
Joined: Sun Sep 23, 2007 4:58 pm

Re: Data added to Array lost 3 commands deep

Post by SparkOut » Sat Mar 12, 2022 6:45 pm

I'm confused...
Since a command handler does not return a value like a function would, and tData_B is not declared as a script local (nor has any value) what is the point of passing it as a parameter to Routine_B? The empty argument gets a value inserted, but that in essence remains a (handler specific) local variable. It doesn't get referenced, nor returned.
I'm really not understanding the purpose of all this. Maybe if I got to a computer and actually checked out the handlers it might make more sense in the flow, but I think I would still be dubious about the purpose. There's bound to be a better way.

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3990
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Data added to Array lost 3 commands deep

Post by bn » Sat Mar 12, 2022 6:53 pm

Hi Sparkout,

I just concentrated on aData_A and did not a complete cleanup. It was aData_A that was causing problems. And the interesting part was that although it is a script-local variable it is not treated as such when passing as an argument to a handler. When referenced by "@" it probably is still not treated as script-local but it changes its value in the targeted handler.

Kind regards
Bernd

bwmilby
Posts: 438
Joined: Wed Jun 07, 2017 5:37 am
Location: Henrico, VA
Contact:

Re: Data added to Array lost 3 commands deep

Post by bwmilby » Sat Mar 12, 2022 11:51 pm

This the root of the problem:

Code: Select all

command Routine_B InData,aOutputData_A @OutputData_B
You are shadowing your script local via the function call, so the data is not being saved.
In Routine_B, aOutputData_A is a copy of what is passed in (LC does a copy on write for parameters not passed by reference)

You either need to just use your script local without passing it (as demonstrated above), or you need to use the @ everywhere it is delcared as a parameter. It would be much clearer if your parameters were all prefixed with "p" and did not shadow.

See the "Naming Conventions" section here:
http://fourthworld.com/embassy/articles ... style.html

There are a couple of additions that I like:
  • @x - in/out parameter (what you are actually doing)
  • @r - return only parameter (input value is ignored)
Brian Milby

Script Tracker https://github.com/bwmilby/scriptTracker

Post Reply

Return to “Getting Started with LiveCode - Experienced Developers”