-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DI] enable improved syntax for defining method calls in Yaml #33779
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
Conversation
0302846
to
f1dc5ec
Compare
src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
Outdated
Show resolved
Hide resolved
f1dc5ec
to
1ea22fb
Compare
For this kind of renamings/refactorings, we usually ask the new names/syntax to be much better than the original ones (we say "ten times better", but it's not a scientific measure). Why? Because the effort to update our docs, making other community doc resources "obsolete" and forcing developers to learn a new way of doing things must be worth it. Looking at the before/after comparison, I think the new way it's better but I'm not sure it's much better. What do others think? Thanks! services:
App\MyService:
calls:
# Before:
- { method: 'addStuff', arguments: ['@App\Stuff']
# After:
- 'addStuff': ['@App\Stuff']
# Before:
- ['withStuff', ['@App\Stuff'], true]
# After
- 'withStuff': !returns_clone ['@App\Stuff'] |
@javiereguiluz good point, please have look at the example in https://twitter.com/nicolasgrekas/status/1178763141485912064?s=19 With trivial definitions we miss the point I think but once we get into array in arguments, inline services, etc. the difference is significant to me. |
@javiereguiluz About forcing developers to learn a new way, I'm not sure most people remember the current syntax exactly because this feature is not among the most often used. I personnally always look it up in the documentation when I do need it. |
@javiereguiluz here is the complete example (we have 2 existing syntaxes for both cases): services:
App\MyService:
calls:
# Before (2 supported ways):
- { method: 'addStuff', arguments: ['@App\Stuff'] }
- ['withStuff', ['@App\Stuff']]
# After:
- addStuff: ['@App\Stuff']
# Before (2 supported ways):
- { method: 'addStuff', arguments: ['@App\Stuff'], returns_clone: true }
- ['withStuff', ['@App\Stuff'], true]
# After
- withStuff: !returns_clone ['@App\Stuff'] |
Also, on its own: calls:
- withStuff: !returns_clone ['@App\Stuff'] isn't exactly intuitive either. It gives the impression that the "returns clone" is somehow tied to the method arguments, which it of course is not. |
@teohhanhui well, that syntax is precisely using a YAML tag. but I agree that this syntax is quite confusing, by trying |
Yes, but according to the YAML spec, a tag "represents type information". I'm not sure such an interpretation is possible here. Perhaps this might work better: calls:
- withStuff: { arguments: ['@App\Stuff'], returns_clone: true } or in expanded formatting: calls:
- withStuff:
arguments:
- '@App\Stuff'
returns_clone: true In summary, just allow moving |
Yeah, in that case, the usage of a tag is indeed abusing the system (which is also related to the fact that it is confusing). |
My modified proposal, in full: services:
App\MyService:
calls:
# Before (2 supported ways):
- { method: 'addStuff', arguments: ['@App\Stuff'] }
- ['withStuff', ['@App\Stuff']]
# After (2 supported ways):
- addStuff: ['@App\Stuff']
- addStuff: { arguments: ['@App\Stuff'] }
# Before (2 supported ways):
- { method: 'addStuff', arguments: ['@App\Stuff'], returns_clone: true }
- ['withStuff', ['@App\Stuff'], true]
# After
- withStuff: { arguments: ['@App\Stuff'], returns_clone: true } |
@teohhanhui your proposal makes it very hard to avoid ambiguity, given that arguments are not limited to a simple list of strings. |
I don't see any possible ambiguity. Or have I missed something? A list of arguments must always be, well, a list. That's already the case now and my proposal changes nothing about that. Complex arguments are still nested in a list. |
@teohhanhui not true. When using autowiring, we support named arguments to specify some arguments while letting others be autowiring. And when using ChildDefinition, we can also have string keys to override some parent arguments. Both of these cases have a mapping for arguments, not a list. |
@stof Are those applicable to |
yes, autowiring works with call arguments too. |
Taking the autowiring case into account: services:
App\MyService:
calls:
# Before (2 supported ways):
- { method: 'addStuff', arguments: ['@App\Stuff'] }
- ['withStuff', ['@App\Stuff']]
# After (2 supported ways):
- addStuff: ['@App\Stuff']
- addStuff: { arguments: ['@App\Stuff'] }
# Before (2 supported ways):
- { method: 'addStuff', arguments: { $stuff: '@App\Stuff' } }
- ['withStuff', { $stuff: '@App\Stuff' }]
# After (2 supported ways):
- addStuff: { $stuff: '@App\Stuff' }
- addStuff: { arguments: { $stuff: '@App\Stuff' } }
# Before (2 supported ways):
- { method: 'addStuff', arguments: ['@App\Stuff'], returns_clone: true }
- ['withStuff', ['@App\Stuff'], true]
# After
- withStuff: { arguments: ['@App\Stuff'], returns_clone: true } (If the array has |
I was about to move Therefore I'd prefer to stick with the current syntax. Also because to me, the method should be read before the type of return. Yaml doesn't have any inherent semantics past its base parsing rules, so we're not "abusing" anything: we define what a specific yaml tree means. (it'd be great if we could avoid such strong words btw, to keep the discussions open...) Status: needs review (I'm going to submit a separate PR to add a test case as @stof requested in #33779 (comment)) |
/cc @symfony/mergers please review this one, it's an important DX improvement (to me at least, I really really don't like the current |
We would then have three different notations for configuring method calls: services:
App\MyService:
calls:
- addStuff: ['@App\Stuff'] vs. App\MyService:
calls:
method: addStuff
arguments: ['@App\Stuff'] vs. App\MyService:
calls:
- [addStuff, ['@App\Stuff']] IMO that would be too many and I would at least try to get rid of the third one. |
@xabbuh 100% agree, that's why I added this note in the description:
|
@nicolas-grekas works for me 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool :)
1ea22fb
to
2b27fb2
Compare
2b27fb2
to
cdc7446
Compare
Thank you @nicolas-grekas. |
…in Yaml (nicolas-grekas) This PR was merged into the 4.4 branch. Discussion ---------- [DI] enable improved syntax for defining method calls in Yaml | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - I've always found the syntax to write method calls in Yaml cumbersome. This PR allows a new syntax that is way easier to type and get (to me at least): ```yaml services: App\MyService: calls: - addStuff: ['@app\Stuff'] ``` for the case where a wither is to be declared, using the same wording as in XML: ```yaml services: App\MyService: calls: - withStuff: !returns_clone ['@app\Stuff'] ``` That's what this PR provides (+ additional syntax checks to guard against typos). Note that deprecating the current syntax wouldn't be nice for the ecosystem in 4.4, but could be considered starting with 5.1. Commits ------- cdc7446 [DI] enable improved syntax for defining method calls in Yaml
I've always found the syntax to write method calls in Yaml cumbersome. This PR allows a new syntax that is way easier to type and get (to me at least):
for the case where a wither is to be declared, using the same wording as in XML:
That's what this PR provides (+ additional syntax checks to guard against typos).
Note that deprecating the current syntax wouldn't be nice for the ecosystem in 4.4, but could be considered starting with 5.1.