Assign value to interface element without previous instantiation of the implementation - codesys

I have a STRUCT (DUT) which one element is an interface.
STRUCT myStruct
element : iInterf;
END_STRUCT
In declaration session, I have to instantiate first (with same implementation) before assign value to this element.
instance : iInterf_implementation := (some initialization values);
myVar : myStruct := ( element := instance );
Is possible to assign value and instantiate an interface element without create another variable?

Not that I know of. Here's a quote from the CODESYS documentation: CODESYS always treats variables declared with the type of an interface as references. If an interface is essentially a reference, which is essentially a pointer, then you need a variable for the interface to refer/point at.

Related

Array as Type for Interface Property CoDeSys

I am attempting to implement the Observer design pattern in CoDeSys using structured text. I'm encountering an error where I can't call the ., [], nor [..] on an interface property. Is it possible to have an interface property that is an array? The interface property in question is the following:
PROPERTY observers : ARRAY[0..20] OF IObserver
And the interface structure follows the observer patter like the following.
The implementation of the notifyAllObservers method is the following.
METHOD notifyAllObservers
VAR
i : INT;
END_VAR
FOR i := 0 TO 20 DO
CommandHandler.observers[i].update(CommandHandler.commands);
END_FOR
I think the problem with your CommandHandler.observers[i] is that you don't have any instances of anything implementing the IObserver.
You cannot access your observers property the way you do since it is not an object.
If you delete the observers property, define an observer FB implementing the IObserver and then add an array of observer (FB) inside CommandHandler your notifyAllObservers code will work.
You can't access the array fields that way.
There are several other ways you can achieve what you want in Structured Text:
Since your property is public there is no reason not to declare the array of IObserver as an input field of the Function Block.
If you do so you can access it the way you desire.
Declaration part:
FUNCTION_BLOCK CommandHandler
VAR_INPUT
IObservers : ARRAY[0..19] OF IObserver;
END_VAR
Example call:
fbCommandHandler.IObservers[i].update();
Another way is you access (and modifiy, etc..) your IObservers from inside the update method:
Create a new Interface IObserverArray with an update method:
METHOD update : BOOL
VAR_INPUT
index : INT;
cmd : INT;
END_VAR
Create a new Function Block implementing the IObserverArray itf:
FUNCTION_BLOCK ObserverArray IMPLEMENTS IObserverArray
//declaration part of the update method
METHOD update : BOOL
VAR_INPUT
index : INT;
cmd : INT;
END_VAR
VAR
itfObservers : ARRAY [0..19] OF IObserver;
END_VAR
//imlementation part of the update method
itfObservers[index].update(cmd);
Create a method getObservers() in your CommandHandler Function Block that returns a IObserverArray:
METHOD getObservers : IObserverArray
//imlementation part of the getObservers method
getObservers := aObservers;
Now you just declare aObservers : ObserverArray; in your CommandHandler as a VAR
and call it like this : fbCommandHandler.getObservers().update(5,12);
https://help.codesys.com/api-content/2/codesys/3.5.12.0/en/_cds_operator_new/
_new(8,nLength +1)
Make a list with memcpy(new,old)
__DELETE(old);
Something like that should work!
How did you set up the property observers?
If you just got an array of objects you are not able to access 1 of the array members individually. However if you only use a get action and instead of getting the array of observers, get a reference to an array of observers it will work. like so
PROPERTY PUBLIC observers : REFERENCE TO ARRAY[*Lower_Bound*..*Upper_Bound*] OF *Class to be returned*
In the get action set the following:
observers REF= *object to be returned*
In this way the getter wil return a pointer/reference instead of the object. With the reference you can reach for an individual item in the array.
Hope this helps

What are the semantics of input variables passed by reference?

Beckhoff's TwinCat-3, as well as Codesys 3 it's based on, adds references as an extension to IEC-61131-3 languages. I'm wondering what is the exact grammar and semantics of this non-standard addition (that's the problem with them: nobody bothers documenting them as well as a standard would).
It the following F_IsNonEmpty function valid and doing what one would expect, when invoked from the F_Test test function below?
FUNCTION F_IsNonEmpty : BOOL
VAR_INPUT
text : REFERENCE TO STRING;
END_VAR
F_IsNonEmpty := LEN(text) > 0;
END_FUNCTION
FUNCTION F_Test1
VAR
testMessage : STRING := '123';
END_VAR
IF F_IsNonEmpty(text := testMessage) THEN
{...}
END_IF
END_FUNCTION
Given that the target of the reference must be initialized using the REF= operator (v.s. e.g. C++ where reference targets are immutable), I'd have expected that the following invoking code would be correct instead - but it doesn't even compile:
FUNCTION F_Test2
VAR
testMessage : STRING := '123';
END_VAR
IF F_IsNonEmpty(text REF= testMessage) THEN
{...}
END_IF
END_FUNCTION
It seems that F_Test1 works correctly, but I'd like someone who actually uses Codesys 3 or TwinCat-3 REFERENCE TO feature to confirm.
When you use a REFERENCE in a VAR_INPUT, it's as if you were using a VAR_IN_OUT variable.
Otherwise if you declare your REFERENCE in the VAR section, you need to use REF= when assigning another variable to it (or get an exception).
In essence, REFERENCE (like a VAR_IN_OUT var) is a more convenient and "safe" pointer because the dereference operator ^ is not needed and because the type is checked at compile time.

When does Chapel pass by reference and when by constant?

I am looking for examples of Chapel passing by reference. This example works but it seems like bad form since I am "returning" the input. Does this waste memory? Is there an explicit way to operate on a class?
class PowerPuffGirl {
var secretIngredients: [1..0] string;
}
var bubbles = new PowerPuffGirl();
bubbles.secretIngredients.push_back("sugar");
bubbles.secretIngredients.push_back("spice");
bubbles.secretIngredients.push_back("everything nice");
writeln(bubbles.secretIngredients);
proc kickAss(b: PowerPuffGirl) {
b.secretIngredients.push_back("Chemical X");
return b;
}
bubbles = kickAss(bubbles);
writeln(bubbles.secretIngredients);
And it produces the output
sugar spice everything nice
sugar spice everything nice Chemical X
What is the most efficient way to use a function to modify Bubbles?
Whether Chapel passes an argument by reference or not can be controlled by the argument intent. For example, integers normally pass by value but we can pass one by reference:
proc increment(ref x:int) { // 'ref' here is an argument intent
x += 1;
}
var x:int = 5;
increment(x);
writeln(x); // outputs 6
The way that a type passes when you don't specify an argument is known as the default intent. Chapel passes records, domains, and arrays by reference by default; but of these only arrays are modifiable inside the function. ( Records and domains pass by const ref - meaning they are passed by reference but that the function they are passed to cannot modify them. Arrays pass by ref or const ref depending upon what the function does with them - see array default intent ).
Now, to your question specifically, class instances pass by "value" by default, but Chapel considers the "value" of a class instance to be a pointer. That means that instead of allowing a field (say) to be mutated, passing a class instance by ref just means that it could be replaced with a different class instance. There isn't currently a way to say that a class instance's fields should not be modifiable in the function (other than making them to be explicitly immutable data types).
Given all of that, I don't see any inefficiencies with the code sample you provided in the question. In particular, here:
proc kickAss(b: PowerPuffGirl) {
b.secretIngredients.push_back("Chemical X");
return b;
}
the argument accepting b will receive a copy of the pointer to the instance and the return b will return a copy of that pointer. The contents of the instance (in particular the secretIngredients array) will remain stored where it was and won't be copied in the process.
One more thing:
This example works but it seems like bad form since I am "returning" the input.
As I said, this isn't really a problem for class instances or integers. What about an array?
proc identity(A) {
return A;
}
var A:[1..100] int;
writeln(identity(A));
In this example, the return A in identity() actually does cause a copy of the array to be made. That copy wasn't created when passing the array in to identity(), since the array was passed by with a const ref intent. But, since the function returns something "by value" that was a reference, it's necessary to copy it as part of returning. See also arrays return by value by default in the language evolution document.
In any case, if one wants to return an array by reference, it's possible to do so with the ref or const ref return intent, e.g.:
proc refIdentity(ref arg) ref {
return arg;
}
var B:[1..10] int;
writeln(refIdentity(B));
Now there is no copy of the array and everything is just referring to the same B.
Note though that it's currently possible to write programs that return a reference to a variable that no longer exists. The compiler includes some checking in that area but it's not complete. Hopefully improvements in that area are coming soon.

Can you pass by reference in PeopleCode?

I'm new to PeopleCode and as I'm learning functions, I noticed that in PeopleCode, we'd normally pass value using %PATIENT_ID. A friend told me that you can also pass by reference in PeopleCode but how?
PeopleCode passes by reference for functions.
Function addOne(&num As integer)
&num = &num + 1
End-Function;
Local integer &val = 9;
addOne(&val);
MessageBox(0, "", 0, 0,String(&val));
Results in 10
If you are using App Classes it behaves differently
for methods:
Pass by value for simple types (string, int, number,etc)
Pass by reference for objects (rowsets, records, app classes)
Can pass by reference for simple types using the OUT keyword in the parameter list
method addOne(&num as integer out)
Functions which are defined in the same context as the executing code, e.g. page/component/record/field event PeopleCode, always consider parameters as refernces.
Within Application Classes, parameters of simple types on methods can be defined with the 'out' key word to state that they are a references. Methods also automatically pass parameters as references for complex types. Think: "If there is a lot of data, it is a reference"
This documentation will be very helpful for you.
https://docs.oracle.com/cd/E26239_01/pt851h3/eng/psbooks/tpcr/chapter.htm?File=tpcr/htm/tpcr07.htm
Passing Parameters with Object Data Types
Parameters with object data types are always passed by reference:
/* argument passed by reference */
method storeInfo(&f as File);
If you specify the out modifier for a method parameter with an object
data type, it becomes a reference parameter. This means that the
parameter variable is passed by reference instead of the object that
it is pointing at when passed.
For example, if you pass an object parameter with the out modifier:
method myMethod(&arg as MyObjectClass);
Local MyObjectClass &o1 = create MyObjectClass("A");
Local MyOtherObjectClass &o2 = create MyOtherObjectClass();
&o2.myMethod(&o1);
And inside myMethod this occurs:
Method myMethod
&arg = create MyObjectClass("B");
end-method;
Since the method argument is reassigned within the body of myMethod,
&o1 does not point at the new instance of MyObjectClass (initialized
with "B") after the method call completes. This is because &o1 still
references the original instance of MyObjectClass.
However, if &o1 had been passed with the out modifier, after the
method call completes, &o1 points at whatever the parameter was last
assigned to; in this case, the new instance of MyObjectClass. The
parameter, rather than the object, is passed by reference. Using
the Out Specification for a Parameter
In the following example, a class, AddStuff, has a single public
method, DoAdd. This adds two numbers together, then assigns them as
different numbers. In the signature of the method declaration, the
first parameter is not declared with an out statement, while the
second one is.
class AddStuff
​method DoAdd(&P1 as number, &P2 as number out);
​end-class;
method DoAdd
&X = &P1 + &P2;
&P1 = 1;
&P2 = 2;
end-method;
In the following PeopleCode example, an object named &Aref is
instantiated from the class AddStuff. Two parameters, &I and &J are
also defined.
local AddStuff &Aref = Create AddStuff();
local number &I = 10;
local number &J = 20;
The following code example is correct. &J is changed, because of the
outstatement in the method signature, and because the value is being
passed by reference. The value of &I is not updated.
&Aref.DoAdd(&I, &J); /* changes &J but not &I */
The following code example causes a design time error. The second
parameter must be passed by reference, not by value.
&Aref.DoAdd(10, 20); /* error - second argument not variable */

What makes a property a computed property in Swift

Let's started with the code snippet:
St Foo {
var proA: Int = 0 { // needs initialization
willSet {
print("about to set proA to \(newValue) from \(proA)")
}
didSet {
print("already set proA to \(proA) from \(oldValue)")
}
}
var ProB: Int { // do not needs initialization
return 1
}
}
let foo = Foo()
foo.proA = 23
print(foo.ProB)
Here are some of my personal understandings about the the stored and computed property:
a: Property with only the observer (willSet and didSet) is not a computed property but a stored property (ex. the proA property in the code above).
b: Computed property must not has initialization (See the comments of the code above).
c: setter is kind of equal to the property observer, the property observer is just the setter + the observer to of the before and after mutating.
Questions:
1. I wonder what makes a property a computed property? Is it correct that as long as the property has a getter and return it is a computed property?
2. Are all my understandings (a, b & c) correct? If not, would be nice of you to point out.
3. Why is it not allowed to initialize an computed property? (Please see the figure below) And when I do so the compiler gives out the warning Cannot call value of none-function type "int" What's the meaning of this error?
Thanks a lot.
First, this is about variables, not properties. Any variable can be a computed variable. A property is just one way to use a variable.
I think on the whole you are making a big mistake in putting a stored variable with setter observers side by side with a computed variable. They are unrelated!
Think of a computed variable as something that looks and acts like a variable when you use it — you get and (maybe) set it — but is in fact a function (or a pair of functions). It is just a compact way of calling a function. That's all it is.
A stored variable with observers, on the other hand, is just a stored variable that also has some observers.
Okay, on to your questions:
I wonder what makes a property a computed property? Is is correct that as long as the property has a getter and return it is a computed property?
Yes. It's a computed variable because you declared it using the syntax that makes it a computed variable (with the curly braces).
Are all my understandings (a, b & c) correct? If not would be nice of you to point out
Yes. I think your "c" is quite insightful: a computed variable does not need a setter observer because it has (gasp!) a setter!
Why is it not allowed to initialize an computed property? (Please see the figure below) And when I do so the compiler gives out the warning Cannot call value of none-function type "int" What's the meaning of this error?
There is no sense in which a computed variable "has" a value — it is computed! it's just some functions! — so it makes no sense to assign it an "initial" value.
A stored property is a property of which the property value is stored together with the instance of the class or struct. The value may be changed, but the property can also be a constant. Thus a stored property can be as simple as:
var proA: Int
let proB: Int
var proC: Int = 0
Computed properties do not store a value. Thus you cannot assign a value to a computed property. A Computed property should have a getter that returns a value. I a broad term, you can think of a computed property as a property that returns the value of a function.
Example of Computed Property
var proA: Int {
return proB * proC
}
With regards to your questions:
Computed Property is therefor a property that do not store a value, and contains a get to return the 'computed' value of the property.
a is correct, b computed properties should not have initialization, c if you mean willSet and didSet. Yes they are like observers for when the property's value will change and did change respectively
Since the value of a computed property is not stored and will never be used, the compiler forbids it.
Hope this helps a bit.
I wonder what makes a property a computed property? Is is correct that as long as the property has a getter and return it is a computed property?
If you define get { } inside the property declaration, it makes that property to a computed property.
And it cannot have initial value as when you access the property, it will always call get{} function declared in property.
Are all my understandings (a, b & c) correct? If not would be nice of you to point out
a is correct
b is wrong.
You can not set initial value for computed property.
Because as I explained in question 1, it will always return result of get{} when you need access to the property.
c : 50% right
setter , it can also be used as to store newValue into another private variable and you can do some additional observing logic. So to observe value changes on stored property, you use willSet and didSet
You can define observing logic on computed property (which has getter and setter) on set{} declaration. But main purpose of set {} is to store the value to another variable or for example UserDefaults.
Why is it not allowed to initialize an computed property? (Please see the figure below) And when I do so the compiler gives out the warning Cannot call value of none-function type "int" What's the meaning of this error?
Same answer
Your code makes compiler to be confused
When you set initial value on the property on declaration, the compiler tries to understand it as stored property. But you also defined get{} for this property, and it means it is computed property and should always return 22 when you access the property. So you should remove one of two.
a. Yes,a property with only observer is a stored property not a computed property.Beacuase property observer tracks the value of a property whose value has initialised previously & it's now changing ,that's a stored property. It's not applicable for a computed property since it has no predefined value
b. computed property is a property whose value depends on other variables, we should declare only those properties as computed property , who needs to be computed using value of another variables ,so it's value cannot be initialised in advance.
for e.g. - If we have 2 variables a & b. we need their addition value , so a variable named 'sum' is used , then sum will be declared as a computed property & its get{} block will return (a+b) that's sum of a & b & the value of sum variable.Then in this case we can't initialise property 'sum'
in advance because it will be computed using a & b.
c. Setter is not an observer it sets value of another variable or performs some actions related to other variables whereas a property observer tracks changes in value of its associated variable itself. for e.g. it's meaningless to use a property observer for variable 'sum' as described in point b .