jsonvariablesscopejsonnet

How to access a variable in Jsonnet if it's in a nested dictionary?


My goal is to make values of inner fields accessible to outer fields in a nested dictionary.

Let's say I have the following code

diction: {
  "outer": "part1",
    {
      "inner": "part2"
    }
  "outer and inner": outer + inner 

}

The above code doesn't work since inner is not accessible due to scoping. I want to do something like global

diction: {
  "outer": "part1",
    {
      global "inner": "part2"
    }
  "outer and inner": outer + inner 

}

or find a way to make jsonnet variables mutable so I can still modify a variable to extract the value of inner.

diction: {
  "outer": "part1",
  "outer and inner": "",
    {
      "inner": "part2",
      "outer and inner": outer + inner
    }

}

Is there a way to do something like that?


Solution

  • Note that your jsonnet scriplets are not syntactically correct: you should not think jsonnet as a "standard" imperative language with "inner" scopes, but really as a "programmable JSON" instead, to heavily over-simplify it.

    As such, the structure (/schema) of jsonnet programs is rather close(r) to JSON syntax, nevertheless please do read https://jsonnet.org/learning/tutorial.html and related language material.

    Recrafting your original question to be syntactically correct, you can refer to current object's scope using self, then use dot notation to refer to contained objects' fields:

    code

    {
      diction: {
        outer: 'part1',
        // NB: `in1` is an object (in jsonnet terms), with key:value entries such as `inner`
        in1: {
          inner: 'part2',
        },
        'outer and inner': self.outer + self.in1.inner,
      },
    }
    

    output

    {
       "diction": {
          "in1": {
             "inner": "part2"
          },
          "outer": "part1",
          "outer and inner": "part1part2"
       }
    }
    

    Note that if you want to void outer and in1 fields from manifesting in JSON output, you can use the double-colon notation as outer:: and in1::.