-
Notifications
You must be signed in to change notification settings - Fork 57
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
Would like to specify that a list of lists should be flattened #339
Comments
Another syntax could follow that for appending maps, like:
|
I'd like to present YAMLScript as a solution for this.
There are many ways to accomplish this in YAMLScript (YS). # File: 339.yaml
!yamlscript/v0:
mammals: &mammals [lion, tiger, elephant]
reptiles: &reptiles [snake, lizard, crocodile]
animals::
apply concat::
- *mammals
- *reptiles Then we load load it from the command line with:
The Let's make it a little better. !yamlscript/v0:
mammals: &mammals [lion, tiger, elephant]
reptiles: &reptiles [snake, lizard, crocodile]
animals: !:concat*
- *mammals
- *reptiles does the same thing. You can put a function call in a tag. The function is applied to the node. The trailing Let's look at how this file compiles:
It's often the case that you have YAML where you want to concat or merge anchored structures like --- !yamlscript/v0:
- &mammals [lion, tiger, elephant]
- &reptiles [snake, lizard, crocodile]
--- !yamlscript/v0:
animals: !:concat*
- *mammals
- *reptiles YS only loads the final doc by default, but can access anchors in other docs. So now you only get animals:
You could also use # 339.yaml
--- !yamlscript/v0:
- &mammals ! load('mammals.yaml')
- &reptiles ! load('reptiles.yaml')
--- !yamlscript/v0:
animals: !:concat*
- *mammals
- *reptiles
# mammals.yaml
[lion, tiger, elephant]
# reptiles.yaml
[snake, lizard, crocodile] We don't need to use anchors and aliases to name things, we can use variables: --- !yamlscript/v0
mammals =: load('mammals.yaml')
reptiles =: load('reptiles.yaml')
--- !yamlscript/v0:
animals: !:concat*
- ! mammals
- ! reptiles Note the first tag changed from Data mode allows you to specify variable assignments inline, so we can go back to a single document: --- !yamlscript/v0:
mammals =: load('mammals.yaml')
reptiles =: load('reptiles.yaml')
animals: !:concat*
- ! mammals
- ! reptiles There are other ways to call --- !yamlscript/v0:
mammals =: load('mammals.yaml')
x =: &R load('reptiles.yaml')
animals:: concat(mammals *R)
animals:: mammals.concat(*R)
animals:: mammals + *R Just to show how flexible YS is... Data mode also has a auto insert functionality for data mode sequences: --- !yamlscript/v0
mammals =: load('mammals.yaml')
x =: &R load('reptiles.yaml')
--- !yamlscript/v0:
animals:
- aardvark
- :: mammals
- mastadon
- :: *R
- zebra which produces: animals:
- aardvark
- lion
- tiger
- elephant
- mastadon
- snake
- lizard
- crocodile
- zebra The cool thing about this is you can put conditional code on these inserts. --- !yamlscript/v0
mammals =: load('mammals.yaml')
x =: &R load('reptiles.yaml')
--- !yamlscript/v0:
animals:
- aardvark
- :when rand(100) > 50: mammals
- mastadon
- :when rand(100) > 50: *R
- zebra This is probably not useful but proves the point. The conditional insert here is shorthand for: - aardvark
- ::
when rand(100) > 50:
mammals The code starting with Let's compile it:
So back to your original. You can also do: --- !yamlscript/v0:
mammals: &mammals
- lion
- tiger
- elephant
reptiles: &reptiles
- snake
- lizard
- crocodile
animals:
- :: *mammals
- :: *reptiles |
See also: https://yamlscript.org/posts/2024-11-29/ |
This is so cool! 😎 |
@UnePierre Thanks. I think so too. tbh, I actually did like your idea for extending << for sequences. Well done. Usually these type of suggestions aren't even close to possible. :) That said I think YS doesn't need it, given the other affordances. If you are keen, I encourage you to try this stuff out and file any issues you have at https://github.com/yaml/yamlscript/issues. Looking forward to what you find... |
Hello @ingydotnet . Thanks for the work you and others in YS have done. I need to go through it carefully as the need arises. Two questions come to my mind though.
--- !yamlscript/v0:
mammals =: load('mammals.yaml')
x =: &R load('reptiles.yaml')
animals:: concat(mammals *R)
animals:: mammals.concat(*R)
animals:: mammals + *R |
@acampove as I said at the start of my long comment, YS can be used as a loader from (currently 10) languages. Adding a language is simple, btw. I don't know what programming language you typically load YAML from but if it is Python there's a full example in https://yamlscript.org/doc/bindings/. You can just replace PyYAML usage in your programs with Python's yamlscript.py modules. Same story for any other language. YS syntax is 100% YAML. YS is a programming language, but also all your existing YAML files are (almost certainly) valid YS "programs". When you "run" a program you are actually "compiling" it and then "evaluating" the result. Since your existing YAML files don't start with The YS compiler is literally a YAML loader that loads to a YS AST. Consider:
you can compile it like:
but if you know how a yaml loader works it has steps parse->compose->resolve->construct
So you can see it literally is a yaml loader. A yaml file that is just data is handled the same way:
Of course I know about Jinja. Various groups have added things to on top of YAML including using Jinja. Jinja is a templating language and YAML doesn't lend itself well to templating. Jinja can do basic looping, conditionals and interpolation, but in a way that is not YAML itself. YS can do anything a language can do. Its interpolation syntax is great. It is intended to make logic in YAML available to all YAML uses, and it concentrates hard on making the use of logic not clutter your YAML. And the files are always 100% YAML, thus can make use of YAML tooling like If you have a specific Jinja'd YAML file you'd like to see as YS for comparison, I'd be happy to show you. FWIW, Kubernetes' Helm uses a templating language that is not Jinja but looks close. Syntax highlighting is not yet done for YS, but its an easy solve. We just need to implement an LSP server for it and that's not particularly hard. If you or anyone reading this has time and is interested I'd be glad to assist you in building one. Otherwise I expect it to happen sometime in 2025. |
@ingydotnet Hi, I tried to use this project, but:
From the user's point of view, the user will want something like: pip install yamlscript import ys
dictionary=ys.load_file('file.yaml') and other small and simple examples. There are already other libraries out there to deal with YAML that most users know how to use. If this tool is not easy to use, people will not use it and you will have wasted years working on a tool that no one cares about. |
In a Python 3 venv like this:
Try:
|
Hi,
I have a file like:
In the example above,
animals
is not a single list, but two and we would have to flatten this in the code. It would be good if we could somehow specify that these lists have to be flattened, e.g. with- **mammals
.The text was updated successfully, but these errors were encountered: