Skip to content

Instantly share code, notes, and snippets.

@p-jackson
Last active March 9, 2016 21:35
Show Gist options
  • Save p-jackson/f96ff7796a91ab289a3b to your computer and use it in GitHub Desktop.
Save p-jackson/f96ff7796a91ab289a3b to your computer and use it in GitHub Desktop.
How I might go about reading from a settings file
#include <string>
#include <unordered_map>
using namespace std;
// I've left the types explicit for clarity, but in real code
// I'd probably use `auto`
// The settings object is a hash table of keys and values. Everythings strings,
// no fighting the type system, no 3rd party libraries, everything is C++ 101.
const unordered_map<string, string> userSettings = parseSettings("path/to/settings.ini");
// Returns a new settings object that has default settings applied.
const auto settings = applyDefaultSettings(userSettings);
// Abort app if there's some issue with the settings file.
if (!validateSettings(settings))
return;
// Get some setting that is supposed to be a string
const string url = settings.at("servicePublicUrl");
// What, convert to `int` every time you want to read the setting?
// Yeah why not? Why create an abstraction if there's no bugs?
// This will throw if the string doesn't represent an integer. But I
// think an exception is appropriate here since we called
// `validateSettings` earlier.
const int port = stoi(settings.at("somePortSetting"));
// `toBool` is your custom function that converts "yes",
// "true", etc. strings to a boolean.
const bool fastMode = toBool(settings.at("doFastMode"));
#include <string>
using namespace std;
// The settings file is now represented by a struct. Awesome type safety
// benefits. Performance benefits because the compiler can inline things.
// It might "feel righter" to because you aren't parsing the non-string
// values over and over.
// Only downside is any change to the settings file format requires a
// change here, which will probably require a re-copmile of your entire
// app.
struct Settings {
string servicePublicUrl;
int somePortSetting;
bool doFastMode;
vector<string> someUserList;
};
// The one and only parse of ints/bools/lists will happen here.
const Settings userSettings = parseSettings("path/to/settings.ini");
// Returns a new settings object that has default settings applied.
const auto settings = applyDefaultSettings(userSettings);
// Abort app if there's some issue with the settings file.
if (!validateSettings(settings))
return;
// Such type safety, wow.
// Mistype the property name? Get a compile error.
// Use the wrong type for a property? Get a compile error.
// Ground breaking stuff!
const string url = settings.servicePublicUrl;
const int port = settings.somePortSetting;
const bool fastMode = settings.doFastMode;
@p-jackson
Copy link
Author

Oh and I think the whole thing hinges on calling validateSettings up front so that exceptions in stoi and toBool would be just that: exceptional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment