I have this:
user_dir: /home/user
user_pics: /home/user/pics
How could I use the user_dir
for user_pics? If I have to specify other properties like this, it would not be very DRY.
Concatenating strings and/or variablesThe standard YAML format does not support the notion of string concatenation. Since concatenating string values is a common pattern in easyconfig files, the EasyBuild framework defines the ! join operator to support this.
There are two ways to concatenate strings in Java: By + (String concatenation) operator. By concat() method.
Concatenation is the process of appending one string to the end of another string. You concatenate strings by using the + operator. For string literals and string constants, concatenation occurs at compile time; no run-time concatenation occurs. For string variables, concatenation occurs only at run time.
You can use a repeated node, like this:
user_dir: &user_home /home/user user_pics: *user_home
I don't think you can concatenate though, so this wouldn't work:
user_dir: &user_home /home/user user_pics: *user_home/pics
It's surprising, since the purpose of YAML anchors & references is to factor duplication out of YAML data files, that there isn't a built-in way to concatenate strings using references. Your use case of building up a path name from parts is a good example -- there must be many such uses.
Fortunately there's a simple way to add string concatenation to YAML via custom tags in Python.
import yaml ## define custom tag handler def join(loader, node): seq = loader.construct_sequence(node) return ''.join([str(i) for i in seq]) ## register the tag handler yaml.add_constructor('!join', join) ## using your sample data yaml.load(""" user_dir: &DIR /home/user user_pics: !join [*DIR, /pics] """)
Which results in:
{'user_dir': '/home/user', 'user_pics': '/home/user/pics'}
You can add more items to the array, like " "
or "-"
, if the strings should be delimited.
If you are using python with PyYaml, joining strings is possible within the YAML file. Unfortunately this is only a python solution, not a universal one:
with os.path.join
:
user_dir: &home /home/user
user_pics: !!python/object/apply:os.path.join [*home, pics]
with string.join
(for completeness sake - this method has the flexibility to be used for multiple forms of string joining:
user_dir: &home /home/user
user_pics: !!python/object/apply:string.join [[*home, pics], /]
I would use an array, then join the string together with the current OS Separator Symbol
like this:
default: &default_path "you should not use paths in config"
pictures:
- *default_path
- pics
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With