I have some service definition that looks like this:
MyService:
class: Some\Class\Here
factory:
- SomeFactoryHere
- method
calls:
- [add, ["@=service('AnotherService1').create(service('AnotherService2'), service('AnotherService3'), service('AnotherService3'))"]]
IMHO, this can be more readable if converted to something like this:
MyService:
class: Some\Class\Here
factory:
- SomeFactoryHere
- method
calls:
-
add,
"@=service('AnotherService1').create(
service('AnotherService2'),
service('AnotherService3'),
service('AnotherService3')
)"
But, this is not valid YAML (Symfony parser fails), and my question is how this config can be converted to something like above?
UPD#1
Look at Symfony YAML format conversion: "calls" with string params - important nuances are there.
The best way to break up your string
"@=service('AnotherService1').create(service('AnotherService2'), service('AnotherService3'), service('AnotherService3'))"
is by using a stripped folded block scalar. The limitation for this is that you cannot escape any special characters with backslashes, but those are not in your example (the reason you need ""
around your scalar is because it starts with an @
which is a reserved character).
Then you also have to correctly re-represent the structure that you have, as @flyx already indicated: the value for calls
is a sequence, the first element of which is a list of the scalar add
and sequence consisting of the aforementioned long scalar that you want to break up for readability:
import yaml
yaml_str = """\
MyService:
class: Some\Class\Here
factory:
- SomeFactoryHere
- method
calls:
- - add
- - >-
@=service('AnotherService1').create(
service('AnotherService2'),
service('AnotherService3'),
service('AnotherService3'))
"""
data = yaml.safe_load(yaml_str)
print(data)
gives:
"@=service('AnotherService1').create( service('AnotherService2'), service('AnotherService3'), service('AnotherService3'))"
Please note that this gives an extra space between .create(
and service(
.
The YAML parser that Symphony uses seems not to be able to parse the above (although it is correct). You can alternatively try:
MyService:
class: Some\Class\Here
factory:
- SomeFactoryHere
- method
calls:
-
- add
-
- >-
@=service('AnotherService1').create(
service('AnotherService2'),
service('AnotherService3'),
service('AnotherService3'))
What you wrote is valid YAML. If the Symfony parser fails, it has a bug. But anyway, the second YAML does not represent the same structure as the first YAML.
In the first YAML, calls
is a sequence. The first sequence item of calls
is also a sequence, which contains the scalar add
and yet another sequence. In the second YAML, calls
is also a sequence, but the item it contains is a scalar which contains everything from add,
to )"
. The comma is content here, because you did not start a flow sequence (with [
). Here is block-style YAML which is equivalent to the first YAML:
MyService:
class: Some\Class\Here
factory:
- SomeFactoryHere
- method
calls:
- - add
- - "@=service('AnotherService1').create(\
service('AnotherService2'),
service('AnotherService3'),
service('AnotherService3')\
)"
The backslashes at the end of the string's lines cause no whitespace to be inserted. By default, YAML inserts one space character for each newline in a double-quoted string it encounters. This YAML scalar yield exactly the same string as your first YAML contains.
- -
is compact style, which starts two nested sequence items at once. So now, calls
is a sequence again with a sequence as first item. that nested sequence contains a scalar add
as first item, and another sequence as second item. And that sequence contains the double-quoted scalar.