> On June 2, 2015, 3:38 p.m., Marco Massenzio wrote:
> > 3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp, line 184
> > <https://reviews.apache.org/r/34943/diff/1/?file=976658#file976658line184>
> >
> > too much choice, IMO - there are (if I counted them right) 8 different
> > `add()` variants to choose from (none of them documented :)
> >
> > It's virtually impossible for folks to figure out which to pick and
> > this leads, I believe, to the current 'code by copying' approach.
> >
> > I would cull it down to no more than 2-3 different options, with some
> > sensible default values.
>
> Benjamin Hindman wrote:
> I completely agree this needs documentation, which I'll take on in a
> different review. But there are really only 4 variants here:
>
> (1) The flag _is_ a class member.
> (A) The flag has a default value (i.e., is _not_ an Option<T>).
> (B) The flag does not have a default value (i.e., _is_ an Option<T>).
>
> (2) The flag is _not_ a class member.
> (A) The flag has a default value (i.e., is _not_ an Option<T>).
> (B) The flag does not have a default value (i.e., _is_ an Option<T>).
>
> All 4 of these options can optionally have a validation function, but
> since we can't capture the default validation function with the existing 4
> functions we have to do the delegating function trick, resulting in 8
> functions. Bottom line, this needs to be documented (and if someone has a
> better suggestion to avoid the delgating function trick I'm all ears).
Why should the callers care if it has a default value, type-wise?
My thinking was, let's always use an `Option<T>` for the flag; a, possibly
`None()`, default value and a `required` bool flag:
```
template<typename T>
void add(Option<T>* option,
const std::string& name,
const std::string& help,
const Option<T>& const default = None(),
bool required = false)
```
and similarly for the class member.
So, all we have are *two* options, and no doubt as to which one to use.
I'm sure I'm missing a ton here, though... especially given that:
```
Option<string> foo;
Option<string> bar;
Option<string> def_foo{"default-foo-val"};
flags.add(&foo, "foo", "this is foo!", def_foo, true);
flags.add1(&bar, "bar", "this is BAR");
```
works as intended, but:
```
flags.add(&foo, "foo", "this is foo!", "default-foo-val", true);
```
causes a compile error (even though, I can totally see an `Option(const T& _t)`
constructor that should "just work" (as it very much does for `def_foo`).
> On June 2, 2015, 3:38 p.m., Marco Massenzio wrote:
> > 3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp, lines 500-504
> > <https://reviews.apache.org/r/34943/diff/1/?file=976659#file976659line500>
> >
> > so, with your approach, everyone, every time that they add a required
> > flag, will have to, essentially, copy & paste this code.
> >
> > what I had envisioned, was a simpler way (eg, by adding a `bool
> > required = false` arg) that, if true would automatically do this validation
> > step in `FlagsBase`
> >
> > (of course, we could add another `add()` method that has that
> > signature, that just internally implements this and calls one of the other
> > `add()` ones - making it the ninth option :) )
>
> Benjamin Hindman wrote:
> I wasn't trying to solve the "required" flag problem, I was just trying
> to show an example of a validation function. But I violently agree that this
> is therefore a horribly bad example that sets a bad precedent, so I've
> replaced this with a different validation function.
>
> I also agree that we should introduce a simplier way, such as a bool as
> you suggested (or better an an enumeration). This doesn't completley solve
> the problem, however, since a flag without a default value will still be an
> Option and still require one to do 'CHECK_SOME(flags.flag)'. Got any other
> ideas?
> horribly bad example
I never said that :)
As mentioned above, a flag should *always* be an `Option<T>` with the
difference that, if we had marked it as `required` then we'd be confident that,
once loaded, it does have a value (so, no need to `CHECK_SOME()`) or it would
have already failed.
For the optional (aka `non-required`) ones (without a default value) obviously
they could be `None()` but that is an "expected outcome" and the caller can
take whatever action they deem appropriate.
>From the 'client' perspective:
1. I told you it was `required` --> there must be a value (or you'd have failed
before getting back to me)
2. I gave you a default value --> there must be a value (possibly the default
one)
3. It's neither required, nor has a default --> its absence (`isNone() ==
true`) has a meaning to me and I'll take appropriate action
4. It's required, and I gave you a default value --> I'm bad at logical
thinking ;-)
I would also propose (similarly to the --help case) to add an
`onMissingRequired()` "hook" with the default implementation
```
void onMissingRequired(const string& name)
{
exit(EXIT_FAILURE) << usage("Missing required flag --" + name);
}
```
so that the caller can also take some alternative action.
- Marco
-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://reviews.apache.org/r/34943/#review86225
-----------------------------------------------------------
On June 5, 2015, 2:48 p.m., Benjamin Hindman wrote:
>
> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> https://reviews.apache.org/r/34943/
> -----------------------------------------------------------
>
> (Updated June 5, 2015, 2:48 p.m.)
>
>
> Review request for mesos.
>
>
> Repository: mesos
>
>
> Description
> -------
>
> Also refactored existing 'lambda::bind' arguments to use C++11 lambdas,
> enabling us to get rid of our "loader" and "stringifier" functors.
>
>
> Diffs
> -----
>
> 3rdparty/libprocess/3rdparty/stout/include/Makefile.am
> 6ac2f04a6a1d8db1725972a3b4b46a0dd734566f
> 3rdparty/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
> 87606d860dea3235ec70d127d3379065d42dc90b
> 3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
> ee855da6128c2d671eb2fc7eaa2c0aab2341aebb
> 3rdparty/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
> 51d3ab020bd2bae1f12b66cac0da5383c813d5d7
> 3rdparty/libprocess/3rdparty/stout/include/stout/flags/stringifier.hpp
> fda5ae1328a23a4371475652f921341dce7448d5
> 3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp
> 80450185f60c5b273face490e0bb9e695b0cb984
>
> Diff: https://reviews.apache.org/r/34943/diff/
>
>
> Testing
> -------
>
> make check
>
>
> Thanks,
>
> Benjamin Hindman
>
>