How to return an object or struct from a method in MQL? - class

struct Person {
string FirstName;
string LastName;
};
class Builder {
public:
Person Builder::Build() {
Person person;
person.FirstName = "FirstName";
person.LastName = "LastName";
return person;
};
};
When I compile this it gives me the below error:
'return' - structure have objects and cannot be copied.
I just need to create a struct or class object and return it, I don't want to do any copying.
I tried using & and * combinations but didn't work. I tried with a class instead of struct and it didn't work either.
I also tried with class as shown below:
class Person {
public:
string FirstName;
string LastName;
};
class Builder {
public:
Person* Build() {
Person person;
person.FirstName = "FirstName";
person.LastName = "LastName";
return &person;
};
};
int OnInit()
{
Builder builder;
Person* person = builder.Build();
string firstName = person.FirstName;
return(INIT_SUCCEEDED);
}
And it gives me invalid pointer access when accessing person.FirstName in the OnInit() method at runtime.

Found the answer but how to avoid memory leak? how to destruct the object and its pointer after use?
class cPerson {
public:
string FirstName;
string LastName;
};
class cBuilder {
public:
cPerson* Build() {
cPerson* person = new cPerson();
person.FirstName = "firstname";
return person;
};
};
cBuilder builder;
cPerson* person = builder.Build();
string age = person.FirstName;

You can delete the object by delete(person); and if you are unsure the object is not a null, it is better to check if(CheckPointer(object)==POINTER_DYNAMIC)delete(object);
Overall you should have all such objects as variables with corresponding variable names, or keep them all in a collection and destroy the whole collection at end. You may also create global variable of object (before OnInit, not inside any function) and it is to be deleted at end of program.
Regarding the initial question - you cannot have string inside a struct, only primitives

you should NOT delete static objects - you will get "delete invalid pointer"-message from compiler in print area... therefore the check should be done as Daniel Kniaz answered... but as so as you are creating the object inside the wrapper - you'd better have a check for deletion & delete it in the Destructor of its wrapper (though I doubt, that you really should use here another class for CPerson creation - yuo can create its object in its - CPerson's - Constructor)

First you need a default constructor and copy constructor in your code. second you need to initialize the struct to default value, the struct only allocate space in the memory and not initialize it, so you can end up with cases where a long variable has some weird value like -1823834393939, so always set your struct to default values.
then when you return a class or struct from a function. the copy constructor will be called that copy the values. so if you don't want to return the exact object you've created in your class you don't need to return a reference
struct Person
{
string FirstName;
string LastName;
Person()
{
FirstName = "";
LastName = "";
}
Person(Person &that)
{
FirstName = that.FirstName;
LastName = that.LastName;
}
};
class Builder
{
public:
Person Builder::Build(string argFirstname, string argLastName)
{
Person person;
person.FirstName = argFirstname;
person.LastName = argLastName;
return person;
};
};
void OnStart()
{
Builder b;
Person p = b.Build("Mohammad Hossein", "amri");
Print(p.FirstName + " " + p.LastName);
}
the output will be

Related

A value of type 'xxx?' can't be returned from a function with return type 'xxx' because 'xxx?' is nullable and 'xxx' isn't

I am learning factory method in dart. However I encounter a problem, which says
A value of type 'Person?' can't be returned from a function with return type 'Person' because 'Person?' is nullable and 'Person' isn't.
3-1.dart:13
Here is my code:
void main(List<String> args) {
Person a = new Person("zarkli");
a.say("hello");
}
class Person{
final name;
static final Map<String, Person> _cache = new Map<String,Person>();
factory Person(String name){
if (_cache.containsKey(name)){
return _cache[name]; // error
} else {
final person = new Person.newPerson(name);
_cache[name] = person;
return person;
}
}
Person.newPerson(this.name);
void say(String content){
print("$name: $content");
}
}
Some maps allow null as a value. For those maps, a lookup using this operator cannot distinguish between a key not being in the map, and the key being there with a null value.
This is from the get operator documentation for map. When you use containsKey it could be the case that the key exists but its value is null.
You can use a local variable to store _cache[name] and check if it's null or not. Dart then can promote that local variable and not give you any errors. So your factory will look like this:
factory Person(String name) {
final cached = _cache[name];
if (cached != null) {
return cached;
} else {
final person = Person.newPerson(name);
_cache[name] = person;
return person;
}
}

Setting and getting a Global variable in Drools

I have something like this in drl file:
import java.lang.String
global String result;
rule ''Rule 1'' when some condition
then
result = "PASS";
kcontext.getKnowledgeRuntime().setGlobal("Result", result); // I got an "Unexpected global" exception.
System.out.println("result = "+ Result);
Also, I don't know how to access this global variable from my MyService.java class.
I was trying to set a global variable from the drl file not my java class like Service class.
All I had to do was the following and it worked successfully
import java.lang.String
global String result;
rule ''Rule 1''
when
some condition
then
String grade = "PASS";
kcontext.getKnowledgeRuntime().setGlobal("result", grade);
end
Also, the global variable name should match what I pass on the setGlobal("result",...).
And then get the global variable using the session I have in the Service class. like:
session.getGlobal("result");
Your rule should not be touching the 'kcontext'. What in the world are you trying to do? result = "PASS" is sufficient for setting the value of the global.
global String result
rule "Rule 1"
when
// some condition
then
result = "PASS";
end
Of course it's not going to work like you want it to because you need to change the value of the existing object; you can't overwrite it like that. Some options might be a "ResultsHolder" sort of class with a boolean variable you can set; or maybe even an AtomicBoolean that you can call set on.
To fire rules with a global, you need to add the global objects to the KieBase before invoking your rules:
var value = ...; // some OBJECT which you are going to pass in as a global
KieSession session = ruleBase.newStatefulSession();
session.insert(...); // insert data
session.setGlobal( "myGlobalFoo", value ); // sets the global; note the name must match the rule file!
session.fireAllRules();
After the rules are fired, you'll have your reference to value that you can use. This is also why you can't pass strings as globals and expect them to capture changes -- Java is pass-by-value, not pass-by-reference.
Here's an example for passing results out of the rules. This toy app will check the student's score on a test and then decide if they passed or failed.
Classes:
class Student {
private String name;
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
}
class Exam {
private String name;
private Double score;
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
public Double getScore() { return this.score; }
public void setScore(String score) { this.score = score; }
}
class ExamResults {
private List<String> results = new ArrayList<>();
public void logResults( String name, Double score, boolean passed ) {
this.results.add(name + " scored " + score + "%, which is a " + (passed ? "passing": "failing") + " grade.");
}
public List<String> getResults() { return this.results; }
}
Rule:
global ExamResults results;
rule "Evaluate exam"
when
Student( $name: name )
Exam ( $score: score, name == $name )
then
boolean passed = $score > 60.0;
results.logResults( $name, $score, passed );
end
Invocation:
List<Student> students = ...;
List<Exam> exams = ... ;
ExamResults results = new ExamResults();
KieSession session = ruleBase.newStatefulSession();
students.forEach( student -> session.insert(students) );
exams.forEach( exam -> session.insert(exam) );
session.setGlobal( "results", results);
session.fireAllRules();
// Print the results:
results.getResults().forEach(System.out::println);
If all you're trying to do is to get some data out of your rules (eg whether certain conditions match), I've written up answers about how to do that previously here and here. If you just want to know what rules triggered, you should write a listener which logs rule hits ("afterMatchFired").

Creating and using Singleton in flutter dart

I am very new to flutter and dart and trying to use singleton instance for global state(?).
which is company info that gets from backend server.
When flutter app starts, send request to the server and get a response and build a singleton instance based on the response.
So I created class
class Company {
static final Company _instance = new Company._internal();
factory Company() {
return _instance;
}
#protected
String name;
#protected
String intro;
String get companyName => name;
String get companyIntro => intro;
void setCompany(String name, String intro) {
name = name;
intro = intro;
}
Company._internal();
}
in main.dart
// companyResult is the response from server
final String companyName = companyResult["name"];
final String companyIntro = companyResult["intro"];
// create singleton instance
var company = Company();
// set company info
company.setCompany(companyName, companyIntro);
// cheking
print(company.companyName)
prints null
What am I doing wrong?
Singletons are better avoided, I would recommend that you use Provider instead and inject a simple object reference on your widget tree, so you can grab that reference whenever you want.
The reason your example prints null is because you are wrongly referencing your variables on setCompany(), the variables name and intro are all the same variable, you are changing the variables internal to the function, not the class variables, in order to fix it change it to:
void setCompany(String name, String intro) {
this.name = name;
this.intro = intro;
}
Also, I would suggest you name your variables _name and _intro, as there's no sense in having a get for a variable that's no private.

Can I make my own getters and setters and should I?

Should I make my own getters and setters in Swift? Im confused by the built in getters ad setters...is this even needed?
//properties for the resident
private var name: String!
var apartmentNumber: String!
var email : String!
var phoneNumber : String!
public func getName()->String{
return self.name
}
public func setName(name : String){
self.name = name
}
}
I've written an article for exactly this. I'll paste it here.
Stop writing getters and setters in Swift
I see this time and time again, and it's about time I write an article in one place to consolidate all my thoughts. If you find yourself writing code that looks like this, listen up:
public class C {
private var _i: Int = 0
public var i: Int {
get {
return self._i
}
set {
self._i = newValue
}
}
}
This pattern* is completely pointless in Swift, and I'll explain why, but firstly we need to take a short detour through Java land. Why Java? Because most of the people I run into who write Swift like this have some sort of Java background, either
because it was taught in their computer sceince courses, or
because they're coming over to iOS development, from Android
What's the point of getters and setters?
Suppose we have the following class in Java:
public class WeatherReport {
public String cityName;
public double temperatureF;
public WeatherReport(String cityName, double temperatureF) {
this.cityName = cityName;
this.temperatureF = temperatureF;
}
}
If you showed this class to any CS prof, they're surely going to bark at you for breaking encapsulation. But what does that really mean? Well, imagine how a class like this would be used. Someone would write some code that looks something like this:
WeatherReport weatherReport = weatherAPI.fetchWeatherReport();
weatherDisplayUI.updateTemperatureF(weatherReport.temperatureF);
Now suppose you wanted to upgrade your class to store data in a more sensible temperature unit (beating the imperial system dead horse, am I funny yet?) like Celcius or Kelvin. What happens when you update your class to look like this:
public class WeatherReport {
public String cityName;
public double temperatureC;
public WeatherReport(String cityName, double temperatureC) {
this.cityName = cityName;
this.temperatureC = temperatureC;
}
}
You've changed the implementation details of your WeatherReport class, but you've also made an API breaking change. Because temperatureF was public, it was part of this class' API. Now that you've removed it, you're going to cause compilation errors in every consumer that depended on the exitense of the temperatureF instance variable.
Even worse, you've changed the semantics of the second double argument of your constructor, which won't cause compilation errors, but behavioural errors at runtime (as people's old Farenheit based values are attemped to be used as if they were celcius values). However, that's not an issue I'll be discussing in this article.
The issue here is that consumers of this class will be strongly coupled to the implementation details of your class. To fix this, you introduce a layer of seperation between your implementation details and your interface. Suppose the Farenheit version of our class was implemented like so:
public class WeatherReport {
private String cityName;
private double temperatureF;
public WeatherReport(String cityName, double temperatureF) {
this.cityName = cityName;
this.temperatureF = temperatureF;
}
public String getCityName() {
return this.cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public double getTemperatureF() {
return this.temperatureF;
}
public void setTemperatureF(double temperatureF) {
this.temperatureF = temperatureF;
}
}
The getters and setters are really basic methods that access or update our instance variables. Notice how this time, our instance variables are private, and only our getters and setters are public. A consumer would use this code, as so:
WeatherReport weatherReport = weatherAPI.fetchWeatherReport();
weatherDisplayUI.updateTemperatureF(weatherReport.getTemperatureF());
This time, when we make the upgrade to celcius, we have the freedom to change our instance variables, and tweak our class to keep it backwards compatible:
public class WeatherReport {
private String cityName;
private double temperatureC;
public WeatherReport(String cityName, double getTemperatureC) {
this.cityName = cityName;
this.temperatureC = temperatureC;
}
public String getCityName() {
return this.cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
// Updated getTemperatureF is no longer a simple getter, but instead a function that derives
// its Farenheit value from the Celcius value that actuallyed stored in an instance variable.
public double getTemperatureF() {
return this.getTemperatureC() * 9.0/5.0 + 32.0;
}
// Updated getTemperatureF is no longer a simple setter, but instead a function
// that updates the celcius value stored in the instance variable by first converting from Farenheit
public void setTemperatureF(double temperatureF) {
this.setTemperatureC((temperatureF - 32.0) * 5.0/9.0);
}
// Mew getter, for the new temperatureC instance variable
public double getTemperatureC() {
return this.temperatureC;
}
// New setter, for the new temperatureC instance variable
public void setTemperatureC(double temperatureC) {
this.temperatureC = temperatureC;
}
}
We've added new getters and setters so that new consumers can deal with temperatures in Celcius. But importantly, we've re-implemented the methods that used to be getters and setters for temperatureF (which no longer exists), to do the appropraite conversions and forward on to the Celcius getters and setters. Because these methods still exist, and behave identically as before, we've successfully made out implementation change (storing F to storing C), without breaking our API. Consumers of this API won't notice a difference.
So why doesn't this translate into Swift?
It does. But simply put, it's already done for you. You see, stored properties in Swift are not instance variables. In fact, Swift does not provide a way for you to create or directly access instance variables.
To understand this, we need to have a fuller understanding of what properties are. There are two types, stored and computed, and neither of them are "instance variables".
Stored properties: Are a combination of a comiler-synthesized instance variable (which you never get to see, hear, touch, taste, or smell), and the getter and setter that you use to interact with them.
Computed proepties: Are just a getter and setter, without any instance variable to act as backing storage. Really, they just behave as functions with type () -> T, and (T) -> Void, but have a pleasant dot notation syntax:
print(weatherReport.temperatureC)
weatherReport.temperatureC = 100
rather than a function calling synax:
print(weatherReport.getTemperatureC())
weatherReport.setTemperatureC(100)
So in fact, when you write:
class C {
var i: Int
}
i is the name of the getter and setter for an instance variable the compiler created for you. Let's call the instance variable $i (which is not an otherwise legal Swift identifier). There is no way to directly access $i. You can only get its value by calling the getter i, or update its value by calling its setter i.
So lets see how the WeatherReport migration problem looks like in Swift. Our initial type would look like this:
public struct WeatherReport {
public let cityName: String
public let temperatureF: Double
}
Consumers would access the temperature with weatherReport.temperatureF. Now, this looks like a direct access of an isntance variable, but remember, that's simply not possible in Swift. Instead, this code calls the compiler-syntehsized getter temperatureF, which is what accesses the instance variable $temperatureF.
Now let's do our upgrade to Celcius. We will first update our stored property:
public struct WeatherReport {
public let cityName: String
public let temperatureC: Double
}
This has broken our API. New consumers can use temperatureC, but old consumers who depended on temperatureF will no longer work. To support them, we simply add in a new computed property, that does the conversions between Celcius and Fahenheit:
public struct WeatherReport {
public let cityName: String
public let temperatureC: Double
public var temperatureF: Double {
get { return temperatureC * 9/5 + 32 }
set { temperatureC = (newValue - 32) * 5/9 }
}
}
Because our WeatherReport type still has a getter called temperatureF, consumers will behave just as before. They can't tell whether a property that they access is a getter for a stored property, or a computed property that derives its value in some other way.
So lets look at the original "bad" code. What's so bad about it?
public class C {
private var _i: Int = 0
public var i: Int {
get {
return self._i
}
set {
self._i = newValue
}
}
}
When you call c.i, the following happens:
You access the getter i.
The getter i accesses self._i, which is yet another getter
The getter _i access the "hidden" instance variable $i
And it's similar for the setter. You have two layers of "getterness". See what that would look like in Java:
public class C {
private int i;
public C(int i) {
this.i = i;
}
public int getI1() {
return this.i;
}
public void setI1(int i) {
this.i = i;
}
public int getI2() {
return this.getI1();
}
public void setI2(int i) {
this.setI1(i);
}
}
It's silly!
But what if I want a private setter?
Rather than writing this:
public class C {
private var _i: Int = 0
public var i: Int {
get {
return self._i
}
}
}
You can use this nifty syntax, to specify a seperate access level for the setter:
public class C {
public private(set) var i: Int = 0
}
Now isn't that clean?
There is no need to create setters and getters for stored properties in Swift and you shouldn't create them either.
You can control the accessibility of getters/setters separately when you declare a property.
public private(set) var name: String // public getter, private setter
If you want to implement some custom logic in your setter, you should use property observer, i.e. didSet/willSet.
var name: String {
didSet {
// This is called every time `name` is set, so you can do your custom logic here
}
}
You will hardly come across the need to create your own getters and setters.
Swift's computed property lets you use getters and setters in a very simple way.
Eg: below defined is a computed property circleArea that returns area of circle depending on radius.
var radius: Float = 10
var circleArea: Float {
get {
return .pi * powf(radius, 2)
}
set {
radius = sqrtf(newValue / .pi)
}
}
While you can observe a stored value and perform some task using property observers:
var radius: Float = 10 {
willSet {
print("before setting the value: \(value)")
}
didSet {
print("after the value is set: \(value)")
}
}
radius += 1
// before setting the value: 10.0
// after the value is set: 11.0
However if you feel like using getter setter, you can define appropriate functions for that. Below defined is an extension on Integer to get and set properties value.
extension Int {
func getValue() -> Int {
return self
}
mutating func setValue(_ val: Int) {
self = val
}
}
var aInt: Int = 29
aInt.getValue()
aInt.setValue(45)
print(aInt)
// aInt = 45

Writing methods and constructors

OK, i need someone to explain to me where to start on this project.
First I need to overload the constructor by adding a default (no-args) constructor to Person that defines an object to have the name "N/A" and an id of -1.
Then i need to add a setter method named reset that can be used to reset the two private instance variables of this class to two values passed in as parameters.
Then I need to add a getter method named getName and getId that can be used to retrieve these two private variables
Here is the code:
public class Person
{
private String name;
private int id;
private static int personCount = 0;
// constructor
public Person(String pname)
{
name = pname;
personCount++;
id = 100 + personCount;
}
public String toString()
{
return "name: " + name + " id: " + id
+ " (Person count: " + personCount + ")";
}
// static/class method
public static int getCount()
{
return personCount;
}
////////////////////////////////////////////////
public class StaticTest
{
public static void main(String args[])
{
Person tom = new Person("Tom Jones");
System.out.println("Person.getCount(): " + Person.getCount());
System.out.println(tom);
System.out.println();
Person sue = new Person("Susan Top");
System.out.println("Person.getCount(): " + Person.getCount());
System.out.println(sue);
System.out.println("sue.getCount(): " + sue.getCount());
System.out.println();
Person fred = new Person("Fred Shoe");
System.out.println("Person.getCount(): " + Person.getCount());
System.out.println(fred);
System.out.println();
System.out.println("tom.getCount(): " + tom.getCount());
System.out.println("sue.getCount(): " + sue.getCount());
System.out.println("fred.getCount(): " + fred.getCount());
}
}
I'm not exactly sure where to start and I don't want just the answer. I'm looking for someone to explain this clearly.
First I need to overload the constructor by adding a default (no-args) constructor to Person that defines an object to have the name "N/A" and an id of -1.
Read about constructors here.
The Person class already contains a ctor that takes 1 argument. What you need to do is create a "default ctor" which is typically a ctor w/out any parameters.
Example:
class x
{
// ctor w/ parameter
//
x(int a)
{
// logic here
}
// default ctor (contains no parameter)
//
x()
{
// logic here
}
}
Then i need to add a setter method named reset that can be used to reset the two private instance variables of this class to two values passed in as parameters.
Setter methods are used to "encapsulate" member variables by "setting" their value via public function. See here.
Example:
class x
{
private int _number;
// Setter, used to set the value of '_number'
//
public void setNumber(int value)
{
_number = value;
}
}
Then I need to add a getter method named getName and getId that can be used to retrieve these two private variables
Getters do the opposite. Instead of "setting" the value of a private member variable, they are used to "get" the value from the member variable.
Example:
class x
{
private int _number;
// Getter, used to return the value of _number
//
public int getNumber()
{
return _number;
}
}
Hope this helps
I highly recommend consulting the Java Tutorials, which should be very helpful here. For example, there is a section on constructors which details how they work, even giving an example of a no-argument form:
Although Bicycle only has one constructor, it could have others, including a no-argument constructor:
public Bicycle() {
gear = 1;
cadence = 10;
speed = 0;
}
Bicycle yourBike = new Bicycle(); invokes the no-argument constructor to create a new Bicycle object called yourBike.
Similarly, there are sections dedicated to defining methods and passing information to them. There's even a section on returning values from your method.
Read the above and you should be able to complete your homework :-)