Open GoogleCodeExporter opened 9 years ago
does it really need to be more complex than a map[string]string ?
Original comment by am...@geeks.cl
on 29 May 2014 at 12:20
The reason I want to avoid using map[string]string comes from two factors. The
first is the preference for ease of use for users (those editing the config
files) over ease of use for developers. The second is the preference for APIs
that are easier to use correctly than incorrectly.
The first means that variable names should remain case-insensitive (as in other
sections, and as in git config). This provides simplicity for users by reducing
the things they need to pay attention to when editing the files. (Other
formats/packages such as json may be better suited if/when ease of use for the
developer is preferred over ease of editing.)
Based on this, using a map with a string key would make it very easy for
developers to incorrectly look up elements by the key in a case-sensitive
manner. This in turn creates inconsistency with other sections in the same
file, as well as with other programs using the gcfg format/package.
An additional but relatively minor issue with map[string]string is the value
type -- gcfg aims to support arbitrary types in a type-safe manner. (Even
though the first priority is ease of use for users, gcfg still does aim to do
as much as possible to assist the developer as well.) This itself (ignoring the
aforementioned issues for a second) could be solved by just using map[string]T
(as long as it can be distinguished from a subsection map definition), but it
complicates API design when trying to provide case-insensitive lookup with
user-defined value types.
I have a rough idea of an API that could enforce (or at least strongly
encourage) case-insensitive usage; using an opaque interim type gcfg.Idx for
keys, and having the developer embed an extra field that provides the methods
for lookup (and holds any additional data needed for lookup):
var cfg = &struct {
Alias struct {
gcfg.Idxer
Vals map[gcfg.Idx]MyType
}
}{}
var cfgStr = `
[alias]
lg=log`
func ExampleIdxer() {
if err := gcfg.ReadStringInto(cfg, cfgStr); err != nil {
panic(err)
}
alias := &cfg.Alias
// Idx(string): look up variable with known name (case-insensitive)
if val, ok := alias.Vals[alias.Idx("LG")]; ok {
fmt.Println(val)
}
// Names(): iterate over variables with undefined order and case
for _, n := range alias.Names() {
fmt.Println(n, alias.Vals[alias.Idx(n)])
}
}
Suggestions for enhancements or alternative approaches are welcome.
Original comment by speter....@gmail.com
on 1 Jun 2014 at 1:29
sounds good to me. :) but I have no clue how to implent `gcfg.Idxer` ... do you
have a branch somewhere to test?
Original comment by am...@geeks.cl
on 15 Jun 2014 at 1:14
This issue was updated by revision 1390defd5d3d.
Original comment by speter....@gmail.com
on 4 Jul 2014 at 10:21
Original issue reported on code.google.com by
speter....@gmail.com
on 11 May 2014 at 2:47