The "Tab1" page receives startval as parameter, the custom variable "value" is binded to startval and custom variable "counter" is binded to "value" and increases it each time.
Despite seeming complex this is a very simple example of passing a variable from the URL to a subpage. I log the parameter passed by ParamDemo, then I log the custom variable "value" and then I print the custom variable "counter".
the page Paramdemo is loaded two times at the same time with the startparam = 17 (no idea why double loading happens)
Tab1 page is loaded and the custom variable "counter" is loaded before the value it is binded to with the value saved in the project (60) thus printing the value increased (61).
The custom variable "value" is loaded with the value in the designer (60)
the custom variable "counter" is loaded a second time even though the variable value is always 60 and has not changed.
Tab1 page is loaded and the custom variable "value" is loaded with the correct start param 17 coming from Paramdemo page
the custom variable "counter" is loaded at the onchange of variable "value" which is always 17 and increased of 1 and thus returning 18.
finally 18 is correctly shown on the text box.
The above seems quite wrong to me because the order should simply be:
the page Paramdemo is loaded once with startparam = 17
Tab1 page is loaded and the custom variable "value" is loaded with the correct start param 17 coming from Paramdemo page
the custom variable "counter" is loaded at the onchange of variable "value" which is 17 and increased of 1 and thus returning 18.
finally 18 is correctly shown on the text box.
Can anyone explain what is happening? this is what happens with a single parameter passed through 2 pages, imagine when we have 3 or four parameters passed through 3 or 4 pages and query bindings are used.
Probably what is happening is that you have saved it with 60 in the value, and with persistent enabled (default) on the property it is retaining that and using that binding when the view is opened.
Hi, you are right, I forgot to disable persistence in params in this SSCCE (if they were non-persistent by default in Ignition it would be much better imho).
Now the steps are a little less but still they don't make much sense, what is worse is that the order of execution changes at each run of the page.
the page is still called two times, then Tab1.value in one instance is called with None, in the second instance with the correct value.
Figuring out the order and the number of times each subpage is called seems like a great headache to me.
Ok, I realize changing this behaviour of persistent parameters in Ignition would break a lot of projects. Still I'm more interested in the order of the loading which is a real mess when things get complex.
I'm pretty sure it is a shotgun start. Perspective loves unordered dictionaries, where ordering is pseudorandom (java hashes). Make your expressions robust in the face of missing references (nulls, because the prop doesn't exist yet) to control intermediate values. The coalesce() expression function is your best friend.
Hi pturmel, I see what you are saying however just some remarks:
We decided company-wise to avoid expressions and use Python scripting almost everywhere in our projects so we cannot use the coalesce() expression.
Checking for null can be done but it is time consuming to put these checks and sometimes null is a perfectly valid value. In that case a "special" value never appearing in the variable's range should be chosen which is not very elegant.
even if the above points were somehow declassified I still see some issues:
webpage loading two times and thus firing whatever potentially intensive tasks two times (notice the webpage is loaded with the correct parameter's value so it cannot be filtered away).
custom variables firing out of order, this cannot be dealt with any check for null values and it has both a performance impact and a final result impact (in the small SSCCE above the final result is always correct but if the chain of binding dependencies increases it can happen sometimes the final value is updated before all previous custom variables have completed).
make bindings shotgun start when they have no dependencies (bindings between them) otherwise create an order of execution which respects the chain of dependencies between variables.
the above would be a game changer for companies which deploy complex pages with many custom variables and parameters.
Well... Unfortunately this is an extremely short sided decision. Many things, maybe everything, that an expression does is simply fast and more efficient then a python script. You are going to limit yourself with basic functionality and performance.
Wow. Let me echo what @bschroeder said. This is absolutely insane.
Expressions are multiple times faster than scripts for almost all tasks where they apply. Overuse of scripts will crush gateway (and therefore Perspective) performance.
(This is one of the reasons the Integration Toolkit module has a bunch of new functionality this year--specifically to address the pain points in Perspective performance.)
Well Python is a general purpose language used by million of companies world wide I don't see why it should be on your top 10 "insane things people have said with a straight face".
It is not a general purpose language. It is an interpretedscripting language. In the areas where it has a reputation for speed, it leverages native code plugins like numpy. Which are not applicable in Ignition.
By contrast, Ignition's expressions are pure Java, a byte-code language that is just-in-time compiled to native code. Java is a general purpose language.
The performance differences are implied by this distinction to anyone with a clue, so the omission on IA's website in the scripting section is meaningless.
Let me repeat: Wow.
Whoever made the call on that policy needs to have a rolled up newspaper whack them in the nose, like a bad puppy.
Hi pturmel,
apart from your nitpicking on my terms, being more efficient and fast is one thing, crushing the server is another.
Ignition's expressions are not pure Java (or at least there is no Java editor to edit them). If it were possible in Ignition to write a binding in Java we probably would use them straight away.
can you please show me how to rewrite the following in a readable Expression:
I'd probably start by replacing the script transform with a runScript expression. Script transforms for some reason add a lot of overhead to execution, which might not matter for something that triggers rarely but if it runs a lot or have enough of them you'll notice.
This is a straw man. Nobody here is saying you should never write a Python transform or that any Python script could be represented (for better, worse, or at all) via expression instead.
That's not to say that certain complicated logic couldn't be refactored into expressions or otherwise.
In this case, it looks like the script transform is doing the job of a prop change script, looking for the value of whatever that binding is and then modifying a bunch of other properties based on that value.