PaesslerAG/gval

Guidance; abusing gval to set keys

mikesimons opened this issue · 4 comments

Hey folks; first up thanks for gval... it's a seriously awesome little library. Hard to believe it doesn't have more adoption!

To the point... I'm using gval in a little tool I wrote to smash up kubernetes manifests. https://github.com/mikesimons/kpatch. Please excuse the nasty code; it's prototype grade at the moment.

I've implemented an = infix operator and it works pretty well to overwrite values that already exist.

The problem is that because I can't get the verbatim key from the left expression I'm having to set values based on a walk of the input structure and matching on reflection values. It works but it means that if the key doesn't exist no value matches and the value is not set.

To get around it I implemented a set function but from a user experience perspective I'd really like to be able to do some.key = "value" even if some.key wasn't previously set.

I had a go with an InfixEvalExpression but due to the input being wrapped in an Evaluable func I couldn't get the value out.

Any advice on a way to do this (even if it means patching gval)?

I think I've solved it myself with a patch to gval that does the following:

  • Adds an optional missing var handler callback invoked by Parser.Var
  • Adds EvalInterface to Evaluable
  • Makes missing map keys non-optional when missing var handler set

These changes allowed me to use InfixEvalOperator and a missing var handler to create keys JIT when evaluating the left expression.

Please let me know if you'd be interested in accepting these changes (in some form). If so I'll add tests and address any feedback (otherwise I'll just keep my fork).

Edit: https://github.com/mikesimons/gval/tree/missing-handler-fn

Hi Mike,

thanks :-)

I've just arrived back from vacation. I'll have a look at your issue and your solution and will respond until tomorrow.

Ok. You have a cool project there.
The infix operation is actually not design for assignments but it seems to be fine for kpatch.

I have a few issues with your modification. It's relativly close tied to your issue and a gval.Language should be immutable and combinable via gval.NewLanguage(a, b)

So I added instead a VariableSelector to gval. This enables you to overrride the default the selector which is probably suited for some other project also. Just add this option with your custom variable selector. This should allow you a simpler set / get implementation.

You don't really nead x.EvalInterface(ctx, v). Just call c(ctx, y) directly. Or if you really like it make a pull request with EvalInterface and an example test.

I hope I could help you.

Wow; that's awesome! Practically a drop in solution.

I was hoping you'd have a better way than mine and this works perfectly... better even since now there is a central point to handle JIT filtering of variables which will be useful for some future plans.

Thanks for the help @generikvault. 🙇