How do you compare an oxygene class reference to classes? - oxygene

Given the following code:
type
Class1 = public class
end;
Class1Class = class of Class1;
Class2 = public class (Class1)
end;
Class3 = public class (Class1)
end;
Class4 = public class
public
method DoSomething(c: Class1Class): Integer;
end;
implementation
method Class4.DoSomething(c: Class1Class): Integer;
begin
if c = Class2 then
result := 0
else if c = Class3 then
result := 1
else
result := 2;
end;
How should DoSomething actually be written, as the equality comparisons throw the compiler error:
Type mismatch, cannot find operator to evaluate "class of Class1" = "<type>"
Using is compiles, but in actuality the first conditional always evaluates to true no matter if Class2 or Class3 is passed in.
The goal is to write this in a cross-platform ways without using code specific to any one of the platforms Oxygene supports.

You must create class references for each class used in the conditionals and use the is operator.
type
Class1 = public class
end;
Class1Class = class of Class1;
Class2 = public class (Class1)
end;
Class3 = public class (Class1)
end;
Class4 = public class
public
method DoSomething(c: Class1Class): Integer;
end;
Class2Class = class of Class2;
Class3Class = class of Class3;
implementation
method Class4.DoSomething(c: Class1Class): Integer;
begin
if c is Class2Class then
result := 0
else if c is Class3Class then
result := 1
else
result := 2;
end;

I am not sure why you are testing the class type specifically - ths should not be necessary if you are virtualising the behaviours of the class via the class reference, but assuming you have reasons for needing to work with class identity of a class reference...
You do not say which platform you are working on, but on Java the Java class types work quite well for these purposes, without needing to use Oxygene class references:
method Class4.DoSomething(c: &Class<Object>): Integer;
begin
case c of
typeOf(Class2): result := 0;
typeOf(Class3): result := 1;
else
result := 2;
end;
end;
// Examples of usage:
c4.DoSomething(typeOf(Class1));
someC := new Class3;
c4.DoSomething(someC.Class);
If you are not working on Java or need a platform-portable approach, then you could incorporate an alternate class identity in the classes using virtual class methods:
Class1 = public class
class method classID: Integer; virtual;
end;
Implement this to return some constant identifying Class1. Override in descendant classes to return an appropriate ID for each class. Then in your DoSomething method:
method Class4.DoSomething(c: Class1Class): Integer;
begin
case c.classID of
CLASS_2: result := 0;
CLASS_3: result := 1;
else
result := 2;
end;
end;

Related

Initialize a final variable in a constructor in Dart. Two ways but only one of them work? [duplicate]

This question already has an answer here:
Is there a difference in how member variables are initialized in Dart?
(1 answer)
Closed 1 year ago.
I'm trying to understand the following example where I try to initialize a final variable in a constructor.
1st example - works
void main() {
Test example = new Test(1,2);
print(example.a); //print gives 1
}
class Test
{
final int a;
int b;
Test(this.a, this.b);
}
2nd example doesn't work
void main() {
Test example = new Test(1,2);
print(example.a); //compiler throws an error
}
class Test
{
final int a;
int b;
Test(int a, int b){
this.a = a;
this.b = b;
}
}
and when i remove final then it works again
void main() {
Test example = new Test(1,2);
print(example.a); //print gives 1
}
class Test
{
int a;
int b;
Test(int a, int b){
this.a = a;
this.b = b;
}
}
what is the difference between the constructor in the 1st and the 2nd constructor why final initialization works with the first and doesn't with the 2nd.
Can anyone explain that to me please?
THanks
You cannot instantiate final fields in the constructor body.
Instance variables can be final, in which case they must be set exactly once. Initialize final, non-late instance variables at declaration, using a constructor parameter, or using a constructor’s initializer list:
Declare a constructor by creating a function with the same name as
its class (plus, optionally, an additional identifier as described in
Named constructors). The most common form of constructor, the
generative constructor, creates a new instance of a class
syntax in the constructor (described in https://www.dartlang.org/guides/language/language-tour#constructors):

Drool Rules: Arithmetic Operations

I'm trying to write a simple rule. To perform a set of calculations. I understand that the calculations can be handled via functions. But, The business logic involves calculations.
package com.sample.rules
import com.sample.rules.Test
rule "Calculate"
when
Test(calculate == true)
then
finalValue = Test(InitialValue) + 10;
Test.setFinalValue(finalValue)
System.out.println("FinalValue=" + Test.getFinalValue();
end
The Class file with variable
public class Test {
private int finalValue;
private int initialValue;
private boolean calculate;
public int getFinalValue() {
return FinalValue;
}
public void setFinalValue(int FinalValue) {
this.FinalValue = FinalValue;
}
public int getInitialValue() {
return InitialValue;
}
public void setInitialValue(int InitialValue) {
this.InitialValue = InitialValue;
}
public boolean isCalculate() {
return calculate;
}
public void setCalculate(boolean calculate) {
this.calculate = calculate;
}
}
The App file is as shown below
public class CalculationApp {
public static void main(String[] args) {
System.out.println( "Bootstrapping the Rule Engine ..." );
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
Test test = new Test();
test.setInitialValue(20);
test.setCalculate(true);
kSession.insert(test);
int fired = kSession.fireAllRules();
System.out.println( "Number of Rules executed = " + fired );
}
}
The rule file throws an error :
Rule Compilation error finalValue cannot be resolved to a variable
Cannot make a static reference to the non-static method getInitialValue() from the type Test
finalValue cannot be resolved to a variable
Cannot make a static reference to the non-static method getFinalValue() from the type Test
While I found the answer by Trial and Error: I'm trying to understand the logic behind it. I mean, Assigning a variable (I understand variable has a different meaning) /assignment in the when condition is understandable, but the same the how does the Then part work. I mean, the item.setFinalValue(...) part.
Your rule has several problems, as indicated by the error.
Rule Compilation error finalValue cannot be resolved to a variable
finalValue cannot be resolved to a variable
The first problem is that you never declare finalValue, just attempt to assign to it on the right hand side. To fix this, simply declare finalValue. Assuming it's an integer:
int finalValue = ...
This is identical to how it works in Java.
However given what the original rule looks like, I think you're trying to pull the initial value from the Test object. To do that, you would do something like this:
rule "Calculate"
when
Test( calculate == true,
$initialValue: initialValue ) // assign the $initialValue variable
then
int finalValue = $initialValue + 10; // set finalValue by adding 10 to $initialValue
Cannot make a static reference to the non-static method getInitialValue() from the type Test
Cannot make a static reference to the non-static method getFinalValue() from the type Test
Both of these errors indicate that you're trying to call instance methods without an object instance. This is once again the same as in Java, where if you have an instance method you must call it against an instance.
Assuming these are methods on the Test class, you would change your rule to be:
package com.sample.rules
import com.sample.rules.Test
rule "Calculate"
when
$test : Test( calculate == true,
$initialValue: initialValue )
then
int finalValue = $initialValue + 10;
$test.setFinalValue(finalValue); // call against $test instance
System.out.println("FinalValue=" + $test.getFinalValue()); // you were also missing a parenthesis
end
What worked was :
rule "Calculate"
when
item: Test(calculate == true)
then
item.setFinalValue(item.getInitialValue() + 10)
System.out.println("FinalValue=" + item.getFinalValue();
end

What is the purpose of "new" on the function in Systemverilog?

I'm trying to understand systemverilog, So I'm referring this site.
But I'm confused the usage of "new" in the below code.
class packet;
//class properties
bit [31:0] addr;
bit [31:0] data;
bit write;
string pkt_type;
//constructor
function new(bit [31:0] addr,data,bit write,string pkt_type);
addr = addr;
data = data;
write = write;
pkt_type = pkt_type;
endfunction
//method to display class prperties
function void display();
$display("---------------------------------------------------------");
$display("\t addr = %0h",addr);
$display("\t data = %0h",data);
$display("\t write = %0h",write);
$display("\t pkt_type = %0s",pkt_type);
$display("---------------------------------------------------------");
endfunction
endclass
module sv_constructor;
packet pkt;
initial begin
pkt = new(32'h10,32'hFF,1,"GOOD_PKT");
pkt.display();
end
endmodule
Especially, you can see the
function new(bit [31:0] addr,data,bit write,string pkt_type);
addr = addr;
data = data;
write = write;
pkt_type = pkt_type;
endfunction
This code used "new".
I'm confused that what does "new" mean in function ~ endfunction?
What purpose the "new" used in function block?
As you can see that another block in the above code,
function void display();
$display("---------------------------------------------------------");
$display("\t addr = %0h",addr);
$display("\t data = %0h",data);
$display("\t write = %0h",write);
$display("\t pkt_type = %0s",pkt_type);
$display("---------------------------------------------------------");
endfunction
There is no "new" used in function block.
Would you help me let me know what does it mean?
update,
I've seen a duplicate of another question.
But I've one query about Dave's answer.
If you do not declare a function new() inside your class, SystemVerilog defines an implicit one for you. The reason you might want to declare a function new inside your class is if you want to pass in arguments to the constructor, or you have something that requires more complex procedural code to initialize.
Especially,
If you do not declare a function new() inside your class, SystemVerilog defines an implicit one for you.
Would you please help me for understanding what does "an implicit one for you" with any simple example?
I've got one more experiment as the below,
class packet;
//class properties
bit [31:0] addr;
bit [31:0] data;
bit write;
string pkt_type;
//constructor
function temp(bit [31:0] addr1,data1,bit write1,string pkt_type1);
addr = addr1;
data = data1;
write = write1;
pkt_type = pkt_type1;
endfunction
//method to display class prperties
function void display();
$display("---------------------------------------------------------");
$display("\t addr = %0h",addr);
$display("\t data = %0h",data);
$display("\t write = %0h",write);
$display("\t pkt_type = %0s",pkt_type);
$display("---------------------------------------------------------");
endfunction
endclass
module sv_constructor;
initial begin
packet pkt;
packet temp;
pkt = new();//32'h10,32'hFF,1,"GOOD_PKT");
temp = new();
pkt.addr = 1;
pkt.display();
end
endmodule
As you can see that code there is no "new" in temp function. so I'm confused that which case do I need "new" in function?
update
If I want to make a custom function such as the below,
class MyClass;
int number;
function custom_function1();
number = 0;
endfunction
function custom_function2 (int num);
number = num;
endfunction
endclass
Can't I have just a like that?
update 2
class MyClass;
int number;
function new();
number = 0;
endfunction
function new (int num);
number = num;
endfunction
function new (int num);
number = num;
endfunction
function new (int temp);
number = temp;
endfunction
endfunction
endclass
If we make above MyClass, then how do we know which function is called?
System verilog test bench implements Object Oriented Programming model.
A class is the definition of the object.
class MyClass;
members....
function new();
// do something
endfunction
endclass
The new function in the class is a constructor which gets called at the time of the object instantiation.
A class could be instantiated in the following way:
MyClass a_class = new();
The call to the new() function in this case creates an object of type MyClass, calls its member function new and makes a_class a reference to the newly created object.
System verilog does not support function overloading, there fore only a single constructor can be used. However one can use default argument values to add some flexibility
class MyClass;
int number;
function new (int num = 0);
number = num;
endfunction
endclass
In the above case you can use the constructor to create a version of the object you are interested in:
MyClass a_class = new(); // will assign '0' to the 'number'
MyClass b_class = new(3); // will call the second constructor and assign '3'
new() is the special function in SystemVerilog to construct an object, also known as constructor. It does not have any return type.

C++ Accessing variables in a function in one class from a different class

I'm trying to code a program with multiple classes such the one of the class reads the variables from a text file and the other classes use these variables for further processing.
The problem I'm facing is that I'm having trouble passing the variables from one class to another class, I did try "friend" class and also tried to use constructors but failed
to get the desired output.
The best I could do was
suppose I have class 1 and class 2, and I have a variable "A=10" declared and initialised in class 1, with the help of constructor I inherit it in class 2;
when I print it in class 1, it gives a correct output as 10 but when I print it in class 2 it gives an output as 293e30 (address location)
Please guide me on how to this.
Class1
{
public:
membfunc()
{
int A;
A = 10;
}
}
Class2
{
public:
membfunc2()
{
int B;
B = A + 10;
}
membfunc3()
{
int C, D;
C = A + 10;
D = B + C;
}
}
If i print variables, i expect to get
A = 10, B = 20, C = 20, D = 40
But what I get is
A = 10, B=(252e30) + 10
I think your problem was that you were defining local variables in your member functions, instead of creating member variables of a class object.
Here is some code based on your sample to demonstrate how member variables work:
class Class1
{
public:
int A;
void membfunc()
{
A=10;
}
};
class Class2
{
public:
int B;
int C;
int D;
void membfunc2(Class1& class1Object)
{
B = class1Object.A + 10;
}
void membfunc3(Class1& class1Object)
{
C = class1Object.A + 10;
D = B + C;
}
};
(Full code sample here: http://ideone.com/cwZ6DM.)
You can learn more about member variables (properties and fields) here: http://www.cplusplus.com/doc/tutorial/classes/.

Access parent class variables from nested class

I want to access the variables width/height/size from the nested class, putting static infront of them works, but is there another way?
class random_messages;
int max_x;
int max_y;
rand int width;
rand int height;
rand int size;
class rand_x;
randc int loc_x;
constraint sizes {
loc_x < width / 2**(size+3); //accessing here
loc_x > 0;
}
endclass
endlcass
Don't make the confusion of thinking that just because you define class rand_x inside the class random_messages, it automatically means that an object of the nested class gets instantiated inside an object of the wrapper class. Declaring a nested class only changes the scope where it is defined.
In your case, if you want to access variables of the parent object, you'll have to do the following:
(in the nested class) Declare a handle to the parent and take the parent in as a constructor parameter:
class rand_x;
// ...
protected random_messages m_parent;
function new(random_messages parent);
m_parent = parent;
endfunction
endclass
(in the outer class) Declare an instance of the inner class and pass yourself as its parent:
class random_messages;
// ...
rand rand_x x;
function new();
x = new(this);
endfunction
endclass