GLib docs say that g_file_has_key() is deprecated because it uses GError, but where is the new, replacement function? - updates

GLib docs say that g_key_file_has_key() is deprecated because it uses GError, but where is the new, replacement function? I cannot spot any reasonable candidate for it… From the documentation, it should use a gboolean * error_out parameter instead of the GError **error_out parameter.

g_key_file_has_key() is not deprecated, and the documentation does not say it is. It does say that the function doesn’t follow all of the GError conventions, but that does not mean it’s deprecated.
It means that to use the function properly you must do:
g_autoptr(GError) local_error = NULL;
gboolean has_key = g_key_file_has_key (kf, group, key, &local_error);
if (local_error != NULL)
/* handle error */
rather than doing:
g_autoptr(GError) local_error = NULL;
if (!g_key_file_has_key (kf, group, key, &local_error))
/* handle error */

Related

How to soft reset Chisel Counter

I'm using a Chisel Counter in my logic, and want to be able to reset it also on clear input signal.
how can i do that ?
I was thinking of something like that:
withReset(reset || io.clr) {val (count,wrap) = Counter(io.valid,512)}
My Issue with this (apart from being ugly) is that the val names are not available out of the scope of the withReset.
Is there a better way to do so ?
How about trying to assign 0.U the inner value of the Counter , how can i do that ?
withReset returns the last expression in the block, so you can just write:
val (count, wrap) = withReset(reset.asBool || io.clr)(Counter(io.valid,512))
Note that I added .asBool to reset because in import chisel3._, val reset has the abstract type Reset. See the Chisel website docs on Reset for more information.
I think the above is the best way to do it, but you can also use the #chiselName macro to allow Chisel to name vals inside scopes:
import chisel3.experimental.chiselName
#chiselName
class MyModule extends Module {
...
withReset(reset || io.clr) {val (count,wrap) = Counter(io.valid,512)}
// ^ these ^ will now get named
}
Note that we're trying to get a better version of #chiselName into the 3.4.0 release in the coming weeks, but #chiselName works for the time being.

Call function when class is deleted/garbage collected

I have a class that opens a sqlite database in its constructor. Is there a way to have it close the database when it is destroyed (whether that be due to the programmer destroying it or being destroyed via Lua's garbage collection)?
The code so far:
local MyClass = {}
local myClass_mt= {__index=MyClass, __gc=__del}
function DBHandler.__init()
-- constructor
local newMyClass = {
db = sqlite3.open(dbPath)
}
return setmetatable(newMyClass , myClass_mt)
end
local function __del()
self.db.close()
end
For your particular case, according to its source code, LuaSQLite already closes its handle when it is destroyed:
/* close method */
static int db_close(lua_State *L) {
sdb *db = lsqlite_checkdb(L, 1);
lua_pushnumber(L, cleanupdb(L, db));
return 1;
}
/* __gc method */
static int db_gc(lua_State *L) {
sdb *db = lsqlite_getdb(L, 1);
if (db->db != NULL) /* ignore closed databases */
cleanupdb(L, db);
return 0;
}
But IMO, freeing such resources on GC should be a backup solution: your object could be GCed after quite some time, so SQLite handle will stay open during this time. Some languages provides mechanism to release unmanaged resources as early as possible such as Python's with or C# using.
Unfortunately Lua does not provide such feature so you should call close yourself when possible, by making a close method on your class too for instance.
You don't mention what Lua version you use, but __gc won't work on tables in Lua 5.1. Something like this may work (it's using newproxy hack for Lua 5.1):
m = newMyClass
if _VERSION >= "Lua 5.2" then
setmetatable(m, {__gc = m.__del})
else
-- keep sentinel alive until 'm' is garbage collected
m.sentinel = newproxy(true)
getmetatable(m.sentinel).__gc = m.__del -- careful with `self` in this case
end
For Lua 5.2 this is not different from the code you have; you don't say what exactly is not working, but Egor's suggestion on self.db:close is worth checking...
look for finalizer in the manual.

Best way to cache results of method with multiple parameters - Object as key in Dictionary?

At the beginning of a method I want to check if the method is called with these exact parameters before, and if so, return the result that was returned back then.
At first, with one parameter, I used a Dictionary, but now I need to check 3 parameters (a String, an Object and a boolean).
I tried making a custom Object like so:
var cacheKey:Object = { identifier:identifier, type:type, someBoolean:someBoolean };
//if key already exists, return it (not working)
if (resultCache[cacheKey]) return resultCache[cacheKey];
//else: create result ...
//and save it in the cache
resultCache[cacheKey] = result;
But this doesn't work, because the seccond time the function is called, the new cacheKey is not the same object as the first, even though it's properties are the same.
So my question is: is there a datatype that will check the properties of the object used as key for a matching key?
And what else is my best option? Create a cache for the keys as well? :/
Note there are two aspects to the technical solution: equality comparison and indexing.
The Cliff Notes version:
It's easy to do custom equality comparison
In order to perform indexing, you need to know more than whether one object is equal to another -- you need to know which is object is "bigger" than the other.
If all of your properties are primitives you should squash them into a single string and use an Object to keep track of them (NOT a Dictionary).
If you need to compare some of the individual properties for reference equality you're going to have a write a function to determine which set of properties is bigger than the other, and then make your own collection class that uses the output of the comparison function to implement its own a binary search tree based indexing.
If the number of unique sets of arguments is in the several hundreds or less AND you do need reference comparison for your Object argument, just use an Array and the some method to do a naive comparison to all cached keys. Only you know how expensive your actual method is, so it's up to you to decide what lookup cost (which depends on the number of unique arguments provided to the function) is acceptable.
Equality comparison
To address equality comparison it is easy enough to write some code to compare objects for the values of their properties, rather than for reference equality. The following function enforces strict set comparison, so that both objects must contain exactly the same properties (no additional properties on either object allowed) with the same values:
public static propsEqual(obj1:Object, obj2:Object):Boolean {
for(key1:* in obj1) {
if(obj2[key1] === undefined)
return false;
if(obj2[key1] != obj2[key1])
return false;
}
for(key2:* in obj2)
if(obj1[key2] === undefined)
return false;
return true;
}
You could speed it up by eliminating the second for loop with the tradeoff that {A:1, B:2} will be deemed equal to {A:1, B:2, C:'An extra property'}.
Indexing
The problem with this in your case is that you lose the indexing that a Dictionary provides for reference equality or that an Object provides for string keys. You would have to compare each new set of function arguments to the entire list of previously seen arguments, such as using Array.some. I use the field currentArgs and the method to avoid generating a new closure every time.
private var cachedArgs:Array = [];
private var currentArgs:Object;
function yourMethod(stringArg:String, objArg:Object, boolArg:Boolean):* {
currentArgs = { stringArg:stringArg, objArg:objArg, boolArg:boolArg };
var iveSeenThisBefore:Boolean = cachedArgs.some(compareToCurrent);
if(!iveSeenThisBefore)
cachedArgs.push(currentArgs);
}
function compareToCurrent(obj:Object):Boolean {
return someUtil.propsEqual(obj, currentArgs);
}
This means comparison will be O(n) time, where n is the ever increasing number of unique sets of function arguments.
If all the arguments to your function are primitive, see the very similar question In AS3, where do you draw the line between Dictionary and ArrayCollection?. The title doesn't sound very similar but the solution in the accepted answer (yes I wrote it) addresses the exact same techinical issue -- using multiple primitive values as a single compound key. The basic gist in your case would be:
private var cachedArgs:Object = {};
function yourMethod(stringArg:String, objArg:Object, boolArg:Boolean):* {
var argKey:String = stringArg + objArg.toString() + (boolArg ? 'T' : 'F');
if(cachedArgs[argKey] === undefined)
cachedArgs[argKey] = _yourMethod(stringArg, objArg, boolArg);
return cachedArgs[argKey];
}
private function _yourMethod(stringArg:String, objArg:Object, boolArg:Boolean):* {
// Do stuff
return something;
}
If you really need to determine which reference is "bigger" than another (as the Dictionary does internally) you're going to have to wade into some ugly stuff, since Adobe has not yet provided any API to retrieve the "value" / "address" of a reference. The best thing I've found so far is this interesting hack: How can I get an instance's "memory location" in ActionScript?. Without doing a bunch of performance tests I don't know if using this hack to compare references will kill the advantages gained by binary search tree indexnig. Naturally it would depend on the number of keys.

MATLAB: Is there a method to better organize functions for experiments?

I will run a set of experiments. The main method evaluated has the following signature:
[Model threshold] = detect(...
TrainNeg, TrainPos, nf, nT, factors, ...
removeEachStage, applyEstEachStage, removeFeatures);
where removeEachStage, applyEstEachStage, and removeFeatures are booleans. You can see that if I reverse the order of any of these boolean parameters I may get wrong results.
Is there a method in MATLAB that allows better organization in order to minimize this kind of error? Or is there any tool I can use to protect me against these errors?
Organization with a struct
You could input a struct that has these parameters as it's fields.
For example a structure with fields
setts.TrainNeg
.TrainPos
.nf
.nT
.factors
.removeEachStage
.applyEstEachStage
.removeFeatures
That way when you set the fields it is clear what the field is, unlike a function call where you have to remember the order of the parameters.
Then your function call becomes
[Model threshold] = detect(setts);
and your function definition would be something like
function [model, threshold] = detect(setts)
Then simply replace the occurrences of e.g. param with setts.param.
Mixed approach
You can also mix this approach with your current one if you prefer, e.g.
[Model threshold] = detect(in1, in2, setts);
if you wanted to still explicitly include in1 and in2, and bundle the rest into setts.
OOP approach
Another option is to turn detect into a class. The benefit to this is that a detect object would then have member variables with fixed names, as opposed to structs where if you make a typo when setting a field you just create a new field with the misspelled name.
For example
classdef detect()
properties
TrainNeg = [];
TrainPos = [];
nf = [];
nT = [];
factors = [];
removeEachStage = [];
applyEstEachStage = [];
removeFeatures =[];
end
methods
function run(self)
% Put the old detect code in here, use e.g. self.TrainNeg to access member variables (aka properties)
end
end

Grails: can I make a validator apply to create only (not update/edit)

I have a domain class that needs to have a date after the day it is created in one of its fields.
class myClass {
Date startDate
String iAmGonnaChangeThisInSeveralDays
static constraints = {
iAmGonnaChangeThisInSeveralDays(nullable:true)
startDate(validator:{
def now = new Date()
def roundedDay = DateUtils.round(now, Calendar.DATE)
def checkAgainst
if(roundedDay>now){
Calendar cal = Calendar.getInstance();
cal.setTime(roundedDay);
cal.add(Calendar.DAY_OF_YEAR, -1); // <--
checkAgainst = cal.getTime();
}
else checkAgainst = roundedDay
return (it >= checkAgainst)
})
}
}
So several days later when I change only the string and call save the save fails because the validator is rechecking the date and it is now in the past. Can I set the validator to fire only on create, or is there some way I can change it to detect if we are creating or editing/updating?
#Rob H
I am not entirely sure how to use your answer. I have the following code causing this error:
myInstance.iAmGonnaChangeThisInSeveralDays = "nachos"
myInstance.save()
if(myInstance.hasErrors()){
println "This keeps happening because of the stupid date problem"
}
You can check if the id is set as an indicator of whether it's a new non-persistent instance or an existing persistent instance:
startDate(validator:{ date, obj ->
if (obj.id) {
// don't check existing instances
return
}
def now = new Date()
...
}
One option might be to specify which properties you want to be validated. From the documentation:
The validate method accepts an
optional List argument which may
contain the names of the properties
that should be validated. When a List
is passed to the validate method, only
the properties defined in the List
will be validated.
Example:
// when saving for the first time:
myInstance.startDate = new Date()
if(myInstance.validate() && myInstance.save()) { ... }
// when updating later
myInstance.iAmGonnaChangeThisInSeveralDays = 'New Value'
myInstance.validate(['iAmGonnaChangeThisInSeveralDays'])
if(myInstance.hasErrors() || !myInstance.save(validate: false)) {
// handle errors
} else {
// handle success
}
This feels a bit hacky, since you're bypassing some built-in Grails goodness. You'll want to be cautious that you aren't bypassing any necessary validation on the domain that would normally happen if you were to just call save(). I'd be interested in seeing others' solutions if there are more elegant ones.
Note: I really don't recommend using save(validate: false) if you can avoid it. It's bound to cause some unforeseen negative consequence down the road unless you're very careful about how you use it. If you can find an alternative, by all means use it instead.