i am having problem with a function. It loops through all the referrals and finds the few i am interested. I did a mel trace and around 4th loop, it executes "fire trigger" and starts executing watcher expressions including library function
/**LIBRARY::OrderLib**/fnOrder1(orderStatus,orderDesc)
snippet of the function
{
local orderArray = getfield(dataSymbol, "|", "")
local i, n, relevantOrders = "", retString = ""
local orderDesc, serviceProvider,placeHolderArray
returnIdentifier = getfield(returnIdentifier,"|","")
local orderFlag = val(returnIdentifier[1])
local searchString = returnIdentifier[2]
for i=1, i<=size(orderArray), i=i+1 do
orderArray[i] = getfield(orderArray[i], "^", "")
endfor
for n=1, n<=size(orderArray),n=n+1 do
orderDesc = replacestr( (tolower(str(orderArray[n][1])) + " [" + str(orderArray[n][3]) + "]" ), ",","")
orderStatus = orderArray[n][20]
placeHolderArray = orderStatus + "^" + orderDesc
cond
case searchString == findString
if match(tolower(serviceProvider),1,searchString)>0, relevantOrders = relevantOrders + "|" + placeHolderArray, ""
It is difficult to tell with only a portion of the function as well not knowing the status of variables and the context they are referenced in the form and/or update.
The best I can suggest is that a variable or list is in a global status and being referenced by code external of the function. I see several variable names (i.e. dataSymbol (bad variable - borders on reserved keyword), returnIdentifier, orderStatus, etc.) that are not declared local. If these variables are used elsewhere in your code, it would be expected behavior that their associated expressions external from the function would be triggered.
Ensure your variables inside functions are properly declared. Declare them as local if their values are to stay inside of the function and be certain to account for all of them (it is not unusual to create variables needed on the fly - so be certain to add them to the local list). If you are intentionally meaning to make them available to the code outside of the function, ensure they are uniquely named, otherwise you will see the results you describe, which again, based on syntax presented here, is not only expected, but can actually be desired.
Hope this points you in the right direction.
Hello Lee, Thank you for your suggestions. dataSymbol and returnIdentifier are parameters to the function. I included the complete function below. Also fnOrderToArray and getRelevantOrders are both in libaray.
I will change the variable names to see if it makes any difference.
{fn fnOrderToArray(dataSymbol, returnIdentifier)
{
local orderArray = getfield(dataSymbol, "|", "")
local i, n, relevantOrders = "", retString = ""
local orderDesc, serviceProvider,placeHolderArray
returnIdentifier = getfield(returnIdentifier,"|","")
local orderFlag = val(returnIdentifier[1])
local searchString = returnIdentifier[2]
for i=1, i<=size(orderArray), i=i+1 do
orderArray[i] = getfield(orderArray[i], "^", "")
endfor
for n=1, n<=size(orderArray),n=n+1 do
orderDesc = replacestr( (tolower(str(orderArray[n][1])) + " [" + str(orderArray[n][3]) + "]" ), ",","")
orderStatus = orderArray[n][20]
placeHolderArray = orderStatus + "^" + orderDesc
cond
case orderFlag == 3
if match(tolower(orderDesc),1,searchString)>0, relevantOrders = relevantOrders + "|" + placeHolderArray, ""
case orderFlag == 4
serviceProvider = (if str(orderArray[n][13]) <> "", str(orderArray[n][13]) + hret, "")
+ (if str(orderArray[n][14]) <> "", str(orderArray[n][14]) + hret, "")
+ (if str(orderArray[n][15]) <> "", str(orderArray[n][15]) + hret, "")
+ (if str(orderArray[n][16]) <> "", str(orderArray[n][16]) + hret, "")
+ (if str(orderArray[n][17]) <> "", str(orderArray[n][17]) + hret, "")
cond
case searchString == "kphc"
if match(tolower(serviceProvider),1,searchString)>0, relevantOrders = relevantOrders + "|" + placeHolderArray, ""
case searchString == "hdrs"
if match(tolower(serviceProvider),1,searchString)>0, relevantOrders = relevantOrders + "|" + placeHolderArray, ""
case searchString == "imaging"
if match(tolower(serviceProvider),1,searchString)>0 and match(tolower(serviceProvider),1,"hdrs")<=0, relevantOrders = relevantOrders + "|" + placeHolderArray, ""
case searchString == "rest"
if match(tolower(serviceProvider),1,"kphc")<=0 and match(tolower(serviceProvider),1,"imaging")<=0, relevantOrders = relevantOrders + "|" + placeHolderArray, ""
endcond
endcond
endfor
cond
case orderFlag == 3 or orderFlag == 4
retString = getRelevantOrders(relevantOrders)
endcond
return retString
}
}
and below is when mel trace gets out of the functions and starts to error out
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] execute>Array[4]
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] results>Array
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] execute>Array[20]
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] results>"H"
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] execute>ORDERSTATUS = "H"
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] >>
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] Fire trigger: {
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] fnOrderToArray(dataSymbol, returnIdentifier)
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] fnSortOrderByStatus(orderStatus,orderDesc)
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace]
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] }
07/27/2017 16:10:05.466 INFO Process Id #1048 ML Thread [MelTrace] execute>>call FNORDERTOARRAY(NULL, NULL)
07/27/2017 16:10:05.467 INFO Process Id #1048 ML Thread [MelTrace] >>
Thank you for posting! It looks like orderStatus is left as global in the function. As such, I suspect that since the variable is also an argument in fnOrderToArray, when it's value is updated, the function is being triggered. This is supported in the MEL trace as well.
Try adding 'local orderStatus = "" ' to the function to isolate it and prevent the triggering of the other function's argument.
Thank you Lee. It looks like i forgot to declare orderStatus. it is also good to know how the function acts when local variable is not declared explicitly.
I have a different problem now but the problem with exiting the loop has been resolved.
Thank you again
It can be a useful tool when daisy chaining functions based on a dynamic variable, but when not desired, it is a very inefficient process, as you discovered. As such, I developed the habit of declaring nearly all of my variables as local inside the function and reassigning them to a global as needed, just prior to exit. It has helped to keep the execution stack clean and the results predictable.
oh it is good to know that local variable can be reassigned as global. Thank you
Allow me to clarify - you can assign a local variable to a global variable's value and a global variable to a local variable's value. If a local variable shares the same name as the global variable, it can cause problems, especially if the local is declared after the global (it is not supposed to do this, but I have seen it happen in too many traces to dismiss it outright).
To avoid this, I typically will use 'g' to identify global variables (defined outside of a function) and 'l' to identify local variables (declared inside the function). As such, you can do the following in a function:
{
local results = ""
local lVar = ""
lVar = gVar
<code sequence here>
gVar = lVar
return results
}
In the example above, I bring in the external global value, assign it to a local variable (thus preventing triggering other functions that reference the global variable), process the code, assign the local back to the global and optionally also return a result from the function itself.
Hope that clarifies.