Newsgroup: comp.lang.c++
Subject: A question of interface
From: Daniel <danielaparker@...>
Date: Tue, 17 Dec 2013 20:07:58 -0800 (PST)
This isn't a question about a language issue, but a question about the design of
an interface, hopefully not entirely off topic as the features of the language and language conventions both constrain design.
Consider a json class, called json, that internally stores an array of values,
or an object of name value pairs, or a bool, string, numeric or null value (the
actual internal representation is unimportant.) Constructors for string, bool,
double and int values can naturally be provided as json(const string& val),
json(bool val), json(double val), and json(int val). Construction of a null
value can use the copy constructor and a json::null prototype.
But what to do about constructing object (collection of name-value pairs) and
array values?
Approach 1:
json obj(json::an_object);
// Constructs a json value of type object from an empty object prototype
// (or equivalently, given an enum type indicator)
obj["first_name"] = "John";
obj["last_name"] = "Smith";
// Any array operations on obj would throw
json arr(json::an_array);
arr.add("John");
// Any object operations on arr would throw
Approach 2:
json obj = json::make_object();
json arr = json::make_array();
Approach 3:
json val;
// Constructs a json object of undefined type (not a valid json state),
// or alternatively a null type (a valid json type), and delay until the first
// operation to fix the type
That is, if the first operation is
val["age"] = 50;
val becomes an object, and subsequent array operations would throw, but if the
first operation is
val.add(50);
val becomes an array, and subsequent object operations would throw.
Approach (3) is I believe the most popular in the open source implementations,
it's probably a little more javascript like, users seem to like its
simplicity, but at the same time the user forums have users who construct
json val;
add no members, and are surprised that
std::cout << val << std::endl;
produces "null" rather than the empty object notation "{}".
Then again, if we take approach (1) or (2), what to do with the default
constructor? Letting it be null type is probably okay, it's desirable to have a
default constructor that's lightweight, but a null default doesn't provide much
useful functionality for the user.
Anyway, if anyone has any thoughts, with consideration to the "principle of
least amazement" and most expected C++ convention, I'd be grateful for feedback.
Thanks,
Daniel
Subject: A question of interface
From: Daniel <danielaparker@...>
Date: Tue, 17 Dec 2013 20:07:58 -0800 (PST)
This isn't a question about a language issue, but a question about the design of
an interface, hopefully not entirely off topic as the features of the language and language conventions both constrain design.
Consider a json class, called json, that internally stores an array of values,
or an object of name value pairs, or a bool, string, numeric or null value (the
actual internal representation is unimportant.) Constructors for string, bool,
double and int values can naturally be provided as json(const string& val),
json(bool val), json(double val), and json(int val). Construction of a null
value can use the copy constructor and a json::null prototype.
But what to do about constructing object (collection of name-value pairs) and
array values?
Approach 1:
json obj(json::an_object);
// Constructs a json value of type object from an empty object prototype
// (or equivalently, given an enum type indicator)
obj["first_name"] = "John";
obj["last_name"] = "Smith";
// Any array operations on obj would throw
json arr(json::an_array);
arr.add("John");
// Any object operations on arr would throw
Approach 2:
json obj = json::make_object();
json arr = json::make_array();
Approach 3:
json val;
// Constructs a json object of undefined type (not a valid json state),
// or alternatively a null type (a valid json type), and delay until the first
// operation to fix the type
That is, if the first operation is
val["age"] = 50;
val becomes an object, and subsequent array operations would throw, but if the
first operation is
val.add(50);
val becomes an array, and subsequent object operations would throw.
Approach (3) is I believe the most popular in the open source implementations,
it's probably a little more javascript like, users seem to like its
simplicity, but at the same time the user forums have users who construct
json val;
add no members, and are surprised that
std::cout << val << std::endl;
produces "null" rather than the empty object notation "{}".
Then again, if we take approach (1) or (2), what to do with the default
constructor? Letting it be null type is probably okay, it's desirable to have a
default constructor that's lightweight, but a null default doesn't provide much
useful functionality for the user.
Anyway, if anyone has any thoughts, with consideration to the "principle of
least amazement" and most expected C++ convention, I'd be grateful for feedback.
Thanks,
Daniel
via Usenet Forums - Usenet Search,Free Usenet - comp.lang.c++ http://www.pocketbinaries.com/usenet-forums/showthread.php?153642-A-question-of-interface&goto=newpost
View all the progranning help forums at:
http://www.pocketbinaries.com/usenet-forums/forumdisplay.php?128-Coding-forums
No comments:
Post a Comment