Search code examples
jsonnet

How do I access all the fields of an imported object?


$ cat foo.libsonnet
{
    local foo = 99,
    bar: [ foo, 101 ]
}
$ cat baz.jsonnet
{
    local foo = import 'foo.libsonnet',
    baz: [foo.foo, foo.bar]
}
$ jsonnet baz.jsonnet
RUNTIME ERROR: field does not exist: foo
        baz.jsonnet:3:11-18     thunk <array_element>
        baz.jsonnet:3:10-28     object <anonymous>
        During manifestation

In this example, it is easy to access bar field of foo. Is there any way for baz.jsonnet to access the locals of foo.libsonnet?

If the answer is no, how should I implement foo and baz so that I can access the foo field of foo.libsonnet in both foo.libsonnet and also in baz.jsonnet?


Solution

  • Is there any way for baz.jsonnet to access the locals of foo.libsonnet?

    No. Locals are, well, local. They are just names for values available in some lexical scope. In particular object locals can only be accessed directly in the object definition.

    If you want to access a value from outside the object, it shouldn't be a local - use a field instead. If you don't want it to be shown when you manifest the object, you can use a hidden field like so:

    $ cat foo.libsonnet
    {
        foo:: 99, // double colon indicates that the field is hidden
        bar: [ self.foo, 101 ]
    }
    $ cat baz.jsonnet
    {
        local foo = import 'foo.libsonnet',
        baz: [foo.foo, foo.bar]
    }
    $ jsonnet baz.jsonnet
    {
       "baz": [
          99,
          [
             99,
             101
          ]
       ]
    }
    $ jsonnet foo.libsonnet
    {
       "bar": [
          99,
          101
       ]
    }