Last active
March 9, 2016 21:35
-
-
Save p-jackson/f96ff7796a91ab289a3b to your computer and use it in GitHub Desktop.
How I might go about reading from a settings file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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")); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Oh and I think the whole thing hinges on calling
validateSettings
up front so that exceptions instoi
andtoBool
would be just that: exceptional.