Mutable fields of records with multiple files - functional-programming

I'm working with multiple files, and i have a problem with one mutable field.
In file1.ml, i declared:
type mytype = {
mutable numbers : int list;
}
So, in file2.ml, i have elements of type mytype. But, when i'm trying to make:
myElement.numbers
The following error is returned: Error: Unbound record field label numbers.
Thanks, any help is welcome.

Use a fully qualified name from file2: myElement.File1.numbers
or add an open File to your file.
or use local module opens let open File2 in myElement.numbers

Related

Kotlin Bundle.putString not explicitly adding "String" but instead is "String?"

val args = Bundle()
args.putString("type", details.type)
navigator.navigate(context!!, findNavController(), Destination.TYPE, args)
I am quite confused as to why in the receiving fragment when I go to access the arguments I have passed through it is responding with...
val type: String = arguments.getString("type")
The arguments.getString is all underlined red and says "Required String Found String?" But how when I called method "putString"?!?
It is resulting in text not being rendered in the new fragment and I assume this is a nullability issue.
It's a matter of knowledge that is available in the receiving Fragment.
The Fragment is not aware of how its arguments were created (or modified) so it has to assume the "type" key you're looking for might not be in the arguments Bundle. That's why it returns a nullable (String?) result (the null value would mean absent in arguments).
Your fragment might be created in many places in your app and its arguments might have been modified in many places. We have no way of tracking that.
There are different solutions for this problem, depending on your approach in other parts of the code and how "confident" you are in creating of your Fragment.
I would usually choose a solution in which I assume setting the type is mandatory. Therefore if the type is absent - I fail fast. That would mean the Fragment was misused.
val type: String = arguments!!.getString("type")!!
The code above will crash if either:
a) arguments weren't set, or
b) String with type wasn't put in the arguments Bundle.
You are right, that is a : null ability issue.
First you should be sure if you are expecting a value, so try adding "?" or "!!", i would recommend "?", or go with the block of if {} else
To read the string safely you can use:
val type: String = arguments?.getString("type").orEmpty()
The orEmpty call at the end ensures that a valid String is returned even if either arguments or getString() returns null.
The method signature for getString() returns a nullable String. This is because at compile time, the compiler can't know if the value exists in the bundle or not. You will have the same issue when retrieving anything from any Map.
If you know for certain that the value in the bundle or map should exist at the time you call getString(), you can use the !! operator. That's what it's there for. When you know something should always be there, it is appropriate to want an exception to be thrown (in this case KNPE) if it's not there so you can easily find any programming error during testing.
isEmpty() or ?.let aren't helpful in this particular case because they would just be masking a programming error and making it harder to discover or debug.

Adding elements from vector to listBox in c++

Im new programmer, learning C++ nearly 15 weeks so far and I'm doing a small project about student database with GUI ( Windows-forms ). I created GUI with Drag n Drop thing in Visual Studio 2015.
I have class Student with 13 variables including getters and setters (Index, First Name,Last name, etc...). I've successfully opened connection with MySQL database for Adding, Deleting and Update students.
And I also wrote objects String^ to pick text from my TextBoxes and then parse them into normal string with msclr/marshal.
Now, problem is when i create object of Student and after adding it into vector with code below:
vector<Student> vektor;
Student *s = new Student(iIndeks, cIme, cPrezime, cDatumRodjenja, cFakultet, cSmer, cEmail, iBrTelefona, cDrzava, cMesto, cUlicaIBroj, cOpstina, iPostanskibr);
vektor.push_back(*s);
Im unable to add elements of that vector into listBox with:
listBox1->Items->Add(vektor);
It says this error:
Function cannot be called with given argument list,
argument types are:
(std::vector<Student, std::allocator<Student>>) object type is:
System::Windows::Forms::ListBox::ObjectCollection ^.
I guess its pretty self-explaining but I have no idea (should I or not) create my class like the ref class or something like that?
Any suggestion what this newbie can do?
Thanks for help.

How to initialize a struct value fields using reflection?

I got a .ini configuration file that I want to use to initialize a Configuration struct.
I'd like to use the Configuration fields names and loop over them to populate my new instance with the corresponding value in the .ini file.
I thought the best way to achieve this might be reflection API (maybe I'm totally wrong, tell me...)
My problem here is that I cannot figure out how to access field's name (if it is at least possible)
Here is my code:
package test
import(
"reflect"
"gopkg.in/ini.v1"
)
type Config struct {
certPath string
keyPath string
caPath string
}
func InitConfig(iniConf *ini.File) *Config{
config:=new(Config)
var valuePtr reflect.Value = reflect.ValueOf(config)
var value reflect.Value = valuePtr.Elem()
for i := 0; i < value.NumField(); i++ {
field := value.Field(i)
if field.Type() == reflect.TypeOf("") {
//here is my problem, I can't get the field name, this method does not exist... :'(
value:=cfg.GetSection("section").GetKey(field.GetName())
field.SetString(value)
}
}
return config
}
Any help appreciated...
Use the type to get a StructField. The StructField has the name:
name := value.Type().Field(i).Name
Note that the ini package's File.MapTo and Section.MapTo methods implement this functionality.
While #MuffinTop solved your immediate issue, I'd say you may be solving a wrong problem. I personally know of at least two packages, github.com/Thomasdezeeuw/ini and gopkg.in/gcfg.v1, which are able to parse INI-style files (of the various level of "INI-ness", FWIW) and automatically populate your struct-typed values using reflection, so for you it merely amounts to properly setting tags on the fields of your struct (if needed at all).
I used both of these packages in production so am able to immediately recommend them. You might find more packages dedicated to parsing INI files on godoc.org.

How to concatenate QDomDocument::createElement calls?

I do use the QtXML Module providing a "nice" DOM-Model for Qt.
The problem i encounter is, one cannot concatenate the calls making one require to create extra QDomElement variables for appending. Is there a way around this?
QDomDocument doc;
QDomProcessingInstruction xmlVers = doc.createProcessingInstruction("xml","version=\"1.0\" encoding='utf-8'");
doc.appendChild(xmlVers);
QDomElement docTool = doc.createElement("tool");
doc.appendChild(docTool);
QDateTime t = QDateTime::currentDateTime();
QString dateString = t.toString("yyyy-MM-ddTHH:mm:ss");
// 0: Correct implementation requiring extra QDomElement dateElement
QDomElement dateElement = doc.createElement("date");
dateElement.appendChild(doc.createTextNode(dateString));
docTool.appendChild(dateElement);
// 1: Concatenating create* calls without extra variable
docTool.appendChild(doc.createElement("date1").appendChild(doc.createTextNode(dateString)));
// 2: Trying to encapsulate createElement call by brackets
docTool.appendChild((((QDomElement)doc.createElement("date2")).appendChild(doc.createTextNode(dateString))));
// 3: Trying to hit the nail by elementById (Broken per documentation?!)
docTool.appendChild(doc.createElement("date3"));
doc.elementById("date3").appendChild(doc.createTextNode(dateString));
ui->textBrowser->append(doc.toString());
Giving really strange results:
<?xml version="1.0" encoding='utf-8'?>
<tool>
<date>2015-01-21T10:33:56</date>2015-01-21T10:33:562015-01-21T10:33:56<date3/>
</tool>
As we see
0: is correct
1: has no date tag at all
2: same as before
3: has the date tag but no textnode content
Why can one not concatenate these calls?
appendChild() returns the node that was added. So in:
docTool.appendChild(doc.createElement("date1").appendChild(doc.createTextNode(dateString)));
you end up trying to append the text node to both the date1 element and the docTool element. This should work:
docTool.appendChild(doc.createElement("date1")).appendChild(doc.createTextNode(dateString));
I think the key is in the following sentence (Qt docs):
The parsed XML is represented internally by a tree of objects that can
be accessed using the various QDom classes. All QDom classes only
reference objects in the internal tree. The internal objects in the DOM tree will get deleted once the last QDom object referencing them and the QDomDocument itself are deleted.
When you create a local object with
QDomElement dateElement = doc.createElement("date");
the dateElement element is a reference of the internal tree node. Deleting this object will delete the internal object it refer to. It happens in the following call:
docTool.appendChild(doc.createElement("date1").appendChild(doc.createTextNode(dateString)));
where temporary object created by the doc.createElement("date1") call get deleted as soon as the function called, thus the referenced internal element is also get deleted.

Use an QObject found by it's QObjectName

I have a little problem in my program. I have a config file put in settings. I pull from it the names of the object I need to be checked (these are QCheckBox).
I have this piece of code (It compiles and runs but when it's at "cBox->setChecked" it just crash):
void Preproc::on_tBtnManual_toggled(bool checked){
if(checked){
ui->tBtnManual->setText("Systematic");
}else{
ui->tBtnManual->setText("Manual");
settings.beginGroup("Preprocessing");
QStringList keys = settings.childKeys();
foreach(QString configParam,keys){
QCheckBox *cBox = ui->gridLayout->findChild<QCheckBox *>(configParam);
cBox->setChecked(settings.value(configParam).toBool());
}
}
}
I have tried to put ui->cBox->... put it says that cBox is not a child of ui.
If I qDebug(cBox) I have a QObject(0x0) so nothing !
I'm a little new to Qt so maybe it's a simple thing.
Thanks and have a nice day :)
Are you sure that an object is found?
I don't think so (different name? wrong layout?). cBox is 0x0 when nothing is found.
However put a
if (cBox)
before
cBox->setChecked(settings.value(configParam).toBool());
and it will not crash anymore when it doesn't find an object by name.
are you sure the name (content of configParam) is correct?
you can try the search from QApplication
QApplication::instance()->findChild<QCheckBox *>(configParam);
the findChild method performs a recursive search, if the object exists in the hirachie, it will be found. if the object is not found, it could be:
the object does not exist
the object has another name
the object or one of its ancestors has no (NULL) parent
can you post the part of the .ui file with the check box? it would be helpful.

Resources