Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checking whether super exists at runtime #305

Closed
hausdorff opened this issue Mar 7, 2017 · 9 comments
Closed

Checking whether super exists at runtime #305

hausdorff opened this issue Mar 7, 2017 · 9 comments

Comments

@hausdorff
Copy link

I would like to customize behavior of some object template based on whether super exists, e.g., something like:

{
  [if super != null then "foo"]: "bar",
}

A quick perusal through the spec seems to indicate that only expressions of the form super.id and super[expr] are part of the syntax, and cursory investigation of the source does not reveal a promising direction to go in.

Is doing something like this possible at all? Or perhaps this is extremely un-Jsonnet-y?

@hausdorff
Copy link
Author

I'm not sure what your appetite is for this sort of change, but I'm happy to implement it myself, if you have no conceptual objection to it.

@sparkprime
Copy link
Contributor

It would be a major change to the language. Are you sure it's not already possible to do what you want to do in a reasonable way?

@hausdorff
Copy link
Author

The original idea was to produce a runtime error if super exists, and without syntax like this, it's not clear to me that this is possible.

I would not say this is a mission-critical blocker, so we can close the issue if you want, but it actually is high-value for our scenario. To put it in non-theoretical terms, consider if you want to tag a base class with some type tag, and then dynamically check that you're +'ing together only two things with the same type. You can do the check, except in the case of the base, which needs to check whether the super class has a different type tag, but may actually not have a type tag.

@hausdorff
Copy link
Author

Let me give you a non-theoretical example. In Kubernetes, there is a concept of some entities having an optional name and labels. It is thus convenient to do something like:

metadata.Name("objectNameHere") + metadata.Labels({ app: "fancyAppLabel" })

In the case of metadata.Labels, it would be nice to append the app label if labels already exist, or simply set it if no labels exist. Currently this is not possible to do in Jsonnet as far as I can tell.

It is obviously possible to work around this, but in my estimation, it is hard to do without cluttering up the API, and when you have a lot of functions like this, I would greatly prefer to handle these transparently, to avoid user error.

@sparkprime
Copy link
Contributor

You used to be be able to do super on its own and get a useful object, but we took it out because it wasn't used and quite complicated to implement.

I ran into a similar problem to what you describe and worked around it by always deriving from a base object, like:

Base { ... } + { labels+: { app: "fancyAppLabel" } }

Base would always have labels: { }

@hausdorff
Copy link
Author

Ok, so it sounds like having super return a useful object is off the table. What do you think about an operator that does an "append to, or set if property does not exist"-type operation? Do you think this would also be too complex to implement for the value provided?

@sparkprime
Copy link
Contributor

You can write it yourself:

local extend_or_set(obj, field, val) =
  if std.objectHas(obj, field) then
    obj {[field]+: val}
  else
    obj {[field]: val}

This could also be generalized to take a secondary object instead of a single field: val pair.

@hausdorff
Copy link
Author

My understanding is that this will not work with super, though, is that correct? What I'm trying to do is check whether super has some field, and append to it if so, or set it if not. Something like:

{foo: "bar"} + {
  f: extend_or_set(super, "foo", "baz"),
}

@sparkprime
Copy link
Contributor

Fixed by #318

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants