Cannot refer to local variables in keys

1,292 views
Skip to first unread message

mi...@databricks.com

unread,
Feb 2, 2018, 2:43:42 PM2/2/18
to Jsonnet
Hi everyone,

I have a quick question about referring to local variables inside of an object. I expect this Jsonnet template

{
  local a = "test",
  [a]: a
}

to expand to

{
  "test: "test"
}

but when I run Jsonnet, I instead get the error

STATIC ERROR: ../test.jsonnet:3:4: Unknown variable: a

However,

{
  local a = "test",
  tmp: a
}

works the way I expect. Is there some restriction about using bound variables in a key? I'm using version 0.9.4.

Thanks in advance,
Miles

Dave Cunningham

unread,
Feb 2, 2018, 2:47:12 PM2/2/18
to mi...@databricks.com, Jsonnet
Yes, it is not allowed because locals defined inside an object can access self, and you can't access self while computing the names of an object's fields because the object has not been constructed yet.

From an language semantics, point of view, it avoids paradoxes like:

{
  local a = std.objectFields(self)[0],
  [a]: true,
}

If the local does not have self in it, you should just put it outside the object:

local a = "test"; {
  [a]: a
}

Hope that helps

--
You received this message because you are subscribed to the Google Groups "Jsonnet" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsonnet+unsubscribe@googlegroups.com.
To post to this group, send email to jso...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jsonnet/b9c602ea-4da3-48be-9352-22a88a59050d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

mi...@databricks.com

unread,
Feb 2, 2018, 4:42:55 PM2/2/18
to Jsonnet
Wonderful, thank you for getting back so quickly! I don't think I fully understand, though. It seems like that argument would apply to values as well as keys. How is that different from 

{
  local a = $.a,
  a: a
}

This fails with the error:

RUNTIME ERROR: Max stack frames exceeded.

But at least this allows use cases where the template doesn't recurse infinitely.

Best,
Miles
To unsubscribe from this group and stop receiving emails from it, send an email to jsonnet+u...@googlegroups.com.

Dave Cunningham

unread,
Feb 5, 2018, 10:50:42 AM2/5/18
to mi...@databricks.com, Jsonnet
True, there are cases where it is solvable like this one:

{
  local f = self.a;
  a: "b",
  [f]: true,
}

But to make that work, it'd have to recognize that self is being used in a context where only the 'a' field is accessed, and construct a partial object, which is possible, but then you end up with questions about self["a"], (self).a, local s = self; s.a, and any thing else where there is some distance between the self and the field access.  If it wasn't possible to use self by itself then it would be more practical but I think the benefit of using self by itself outweighs the cost of refactoring this to

local f = "b";
{
  a: f,
  [f]: true,
}



To unsubscribe from this group and stop receiving emails from it, send an email to jsonnet+unsubscribe@googlegroups.com.

To post to this group, send email to jso...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages