Re: Proposal: make Glib::KeyFile easier to use



On 12/26/2013 09:05 PM, Aurimas Cernius wrote:
Hi,

The current interface of Glib::KeyFile::get_* functions is quite
inconvenient as exceptions are the only reliable way to receive
error conditions. Consider the following example:

Glib::KeyFile f; <...> int x = f.get_integer("a", "b");  // (1)

There are two possible error conditions that may cause (1) to
fail: * there's no key "b" in group "a" * the value of the key "b"
in group "a" is not an integer

One external thing to consider here is "who edits key files". I don't
expect non-pro guy doing anything there, so key files probably are
unlikely to be broken (low probability).


Yes, but I still don't want stack unwinding to occur. In my use case the
rest of the key file must still be read successfully. If it was possible
to give up on errors I would move error handling somewhere higher up in
the call stack and use exceptions.

Whereas the former condition can be checked for via
KeyFile::has_key, to check for the latter, one has only the
following two options: * catch the thrown exception * get the value
via get_string and use a separate function to parse it

Both of these approaches are not optimal. I think the situation
could be improved.

My proposal is as follows:

* A new class template Glib::Optional<T> is created. The new class
template would be identical to boost::optional[1].

* A new family of functions for reading a keyfile is created (say,
for example, get_*_opt). The new functions would return
Glib::Optional<T> instead of T. All error conditions would be
reported by returning 'empty' optional object. The new functions
would not throw any exceptions on any circumstances.

This would allow much simpler usage of the API. For example:

Glib::KeyFile f; <...> auto opt = f.get_integer_opt("a", "b");  //
let's say we can use C++11 if (opt) { // utilize the value in *opt
int r = *opt; <...> }

Do think that "if" is more convenient that "try-catch"? I'm not sure
about that.
If you think of more convenient getter for key, I'd think of passing
default value as last argument, that would be returned in case key is
missing or not valid. I think that would cover most of the cases, the
remaining few could deal with exceptions.


Yes, I think that a simple conditional is a better approach in this
specific use-case:
 * Using exceptions to rewind the stack by one level is fundamentally
wrong. One can do that, but that's not idiomatic C++.
 * Using a default value is not workable when the range of input data
must not be reduced (which is one of my requirements).

Regards,
Povilas



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]