)]}'
{
  "commit": "0a4a93b685e891150e26386f3be5f505cfd1a6ee",
  "tree": "d29bc6fc0536eaa945f840d5d682fe98f1e48c2c",
  "parents": [
    "3c0ff861e3d9906ecc4ebfb7e41557d44d3e277b"
  ],
  "author": {
    "name": "akutz",
    "email": "sakutz@gmail.com",
    "time": "Sat Aug 29 10:54:20 2015 -0500"
  },
  "committer": {
    "name": "spf13",
    "email": "steve.francia@gmail.com",
    "time": "Tue Sep 08 08:23:06 2015 -0400"
  },
  "message": "[110] Default Values Specify Type\n\nThis patch adds a feature, if enabled, will infer a value\u0027s type from\nits default value no matter from where else the value is set. This is\nparticularly important when working with environment variables. For\nexample:\n\n    package main\n\n    import (\n      \"fmt\"\n      \"os\"\n\n      \"github.com/spf13/viper\"\n    )\n\n    func print(name string, val interface{}) {\n      fmt.Printf(\"%-15[1]s%-15[2]T%[2]v\\n\", name, val)\n    }\n\n    func main() {\n      viper.BindEnv(\"mykey\", \"MYPREFIX_MYKEY\")\n      viper.SetDefault(\"mykey\", []string{})\n      os.Setenv(\"MYPREFIX_MYKEY\", \"a b c\")\n\n      v1 :\u003d viper.GetStringSlice(\"mykey\")\n      v2 :\u003d viper.Get(\"mykey\")\n\n      print(\"v1\", v1)\n      print(\"v2\", v2)\n    }\n\nWhen this program is executed the following is emitted:\n\n    [0]akutz@pax:ex$ ./ex1\n    v1             []string       [a b c]\n    v2             string         a b c\n    [0]akutz@pax:ex$\n\nYou may wonder, why is this important? Just use the GetStringSlice\nfunction. Well, it *becomes* important when dealing with marshaling.\nIf we update the above program to this:\n\n    package main\n\n    import (\n      \"fmt\"\n      \"os\"\n\n      \"github.com/spf13/viper\"\n    )\n\n    type Data struct {\n      MyKey []string\n    }\n\n    func print(name string, val interface{}) {\n      fmt.Printf(\"%-15[1]s%-15[2]T%[2]v\\n\", name, val)\n    }\n\n    func main() {\n      viper.BindEnv(\"mykey\", \"MYPREFIX_MYKEY\")\n      viper.SetDefault(\"mykey\", []string{})\n      os.Setenv(\"MYPREFIX_MYKEY\", \"a b c\")\n\n      v1 :\u003d viper.GetStringSlice(\"mykey\")\n      v2 :\u003d viper.Get(\"mykey\")\n\n      print(\"v1\", v1)\n      print(\"v2\", v2)\n\n      d :\u003d \u0026Data{}\n      viper.Marshal(d)\n      print(\"d.MyKey\", d.MyKey)\n    }\n\nNow we can see the issue when we execute the updated program:\n\n    [0]akutz@pax:ex$ ./ex2\n    v1             []string       [a b c]\n    v2             string         a b c\n    d.MyKey        []string       []\n    [0]akutz@pax:ex$\n\nThe marshalled data structure\u0027s field MyKey is empty when in fact it\nshould have a string slice equal to, in value, []string {\"a\", \"b\",\n\"c\"}.\n\nThe problem is that viper\u0027s Marshal function calls AllSettings which\nultimately uses the Get function. The Get function does try to infer\nthe value\u0027s type, but it does so using the type of the value retrieved\nusing this logic:\n\n    Get has the behavior of returning the value associated with the\n    first place from where it is set. Viper will check in the\n    following order:\n\n      * override\n      * flag\n      * env\n      * config file\n      * key/value store\n      * default\n\nWhile the above order is the one we want when retrieving the values,\nthis patch enables users to decide if it\u0027s the order they want to be\nused when inferring a value\u0027s type. To that end the function\nSetTypeByDefaultValue is introduced. When SetTypeByDefaultValue(true)\nis called, a call to the Get function will now first check a key\u0027s\ndefault value, if set, when inferring a value\u0027s type. This is\ndemonstrated using a modified version of the same program above:\n\n    package main\n\n    import (\n      \"fmt\"\n      \"os\"\n\n      \"github.com/spf13/viper\"\n    )\n\n    type Data struct {\n      MyKey []string\n    }\n\n    func print(name string, val interface{}) {\n      fmt.Printf(\"%-15[1]s%-15[2]T%[2]v\\n\", name, val)\n    }\n\n    func main() {\n      viper.BindEnv(\"mykey\", \"MYPREFIX_MYKEY\")\n      viper.SetDefault(\"mykey\", []string{})\n      os.Setenv(\"MYPREFIX_MYKEY\", \"a b c\")\n\n      v1 :\u003d viper.GetStringSlice(\"mykey\")\n      v2 :\u003d viper.Get(\"mykey\")\n\n      print(\"v1\", v1)\n      print(\"v2\", v2)\n\n      d1 :\u003d \u0026Data{}\n      viper.Marshal(d1)\n      print(\"d1.MyKey\", d1.MyKey)\n\n      viper.SetTypeByDefaultValue(true)\n\n      d2 :\u003d \u0026Data{}\n      viper.Marshal(d2)\n      print(\"d2.MyKey\", d2.MyKey)\n    }\n\nNow the following is emitted:\n\n    [0]akutz@pax:ex$ ./ex3\n    v1             []string       [a b c]\n    v2             string         a b c\n    d1.MyKey       []string       []\n    d2.MyKey       []string       [a b c]\n    [0]akutz@pax:ex$\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "5e01aa5210f4acc9d363f44e6f84e71b2f58ad85",
      "old_mode": 33188,
      "old_path": "viper.go",
      "new_id": "e249430ca6cf0d65160c670a9bcaaf97c6313162",
      "new_mode": 33188,
      "new_path": "viper.go"
    }
  ]
}
