Problem/Motivation
Constructors usually have a one-line description of the format Constructs a ... object.. Besides the fact that this is stating the obvious (it technically cannot really do anything else), it also breaks {@inheritdoc}
for constructors of child classes, as the documentation of those constructors will display that of their parents, which include the parent class name. Whereas a child class is also an instance of its parent class, this is quite odd and possibly confusing.
Additionally, most constructor parameters are type hinted and self-documenting, so we should omit @param documentation for those too, to save boilerplate and duplication.
The combination of these means that constructors should be allowed to have no phpdoc at all. Obviously there may be cases where phpdoc is desired and that should still be allowed.
Proposed resolution
No longer require phpdoc for magic methods.
Documentation changes
1. Documentation Gate: Minimum requirements for in-code documentation
Current text
Documentation blocks for all files, interfaces, classes, methods, class members, functions, hooks, and constants, which must contain:
A one-line summary (80 characters or fewer).
Typed @param, @return, @var, and @throws (with descriptions on param/return) where required by the API documentation standards.
Longer explanations for anything complicated.
Proposed text
Documentation blocks for all files, interfaces, classes, methods (except constructor methods), class members, functions, hooks, and constants, which must contain:
A one-line summary (80 characters or fewer).
Typed @param, @return, @var, and @throws (with descriptions on param/return) where required by the API documentation standards.
Longer explanations for anything complicated.
2. Drupal API documentation standards for classes and namespaces
Current text
All classes and all of their methods (including private methods) must be documented.
Proposed text
Current text
All classes and all of their methods (including private methods but excluding constructors) must be documented.
Remaining tasks
1. Agree on standards.
2. Agree on documentation changes
3. Decide if the documentation in #44 should be changed and, if so, agree on the changes
4. After the consultation period (in upcoming announcement) discuss at the next CS meeting.
User interface changes
None.
API changes
None for core. Maybe support default summaries in the API module.
Comment | File | Size | Author |
---|---|---|---|
#57 | core-11.x-2140961-remove-magic-method-docs.diff | 85.82 KB | donquixote |
#31 | 2140961.diff | 1.39 KB | catch |
Comments
Comment #1
jhodgdonOK. What alternative would you suggest?
Comment #2
XanoIn most cases, we need a docblock to document the arguments. Do we want to enforce the one-line description requirement for magic methods? This issue applies to all of them and not just
__construct()
, I guess.Comment #3
jhodgdonAre you saying you don't want a one-line description at all, or that you want to modify what it says?
Comment #4
XanoI'm saying we might want to drop it altogether for magic methods, as their purpose is defined by the language and not the developer.
Comment #5
jhodgdonUpdating title and tags according to the actual proposal here, which is a coding standards change proposal.
Xano: if you want this to get proper consideration, perhaps you could make a real issue summary (using the template) outlining your reasoning, and then set this to "needs review"? Since you are the one who is passionate about it, you will need to be the one to push it forward. I am generally not in favor of adding more exceptions to our standards, which are already very complicated to understand.
Comment #6
XanoComment #7
longwaveTo avoid exceptions in the coding standards while avoiding the inheritance problem, we could just use a generic "Constructs the object." summary for all constructors?
Comment #8
jhodgdonThere is nothing preventing people from using #7.
Comment #9
XanoI have been using
Constructs a new class instance.
since I started this issue and that hasn't seemed to offend people.Regardless of he preferred solution, do we agree that
Contructs a new $classname.
causes documentation errors because of inheritance?Comment #10
hanoiiI just worked in the sprint at DrupalCon on #1924818: Things that are not really factories should not be documented as factories and I raised my opinion there about not having constructor documentation at all, except of parameters descriptions unless the constructor actually includes a logic that needs documenting, which is not normally the case. I think that not having that one line comment helps at least in terms on not having to maintain unnecessary documentation, a practical example would be that the mentioned issue would not have been there in the first place.
Comment #11
jhodgdonI have just updated the issue summary here with the two basic proposals (adopting Xano's I think preferable wording for (b)). So basically the options are (this is in the summary now):
-----------
a) Do not require the one-line summary for magic methods.
b) Encourage people to use a generic one-line summary like "Constructs a new class instance." to avoid most of the problems.
Both ideas fix the problems with inheritance, when the class name changes, copy/paste problems, etc.
The advantage of (a) is that it doesn't require restating the obvious.
The advantages of (b) are code sniffers etc. will not flag the doc block as non-compliant, and it doesn't require us to have yet another exception in our already-extensive coding/documentation standards.
---------
I vote for (b). Any other thoughts?
Comment #12
jhodgdonAs we have a proposal...
Comment #13
jhodgdonCoding standards changes are now part of the TWG
Comment #14
tizzo CreditAttribution: tizzo commentedMoving this issue to the Coding Standards queue per the new workflow defined in #2428153: Create and document a process for updating coding standards.
Comment #15
dawehnerI'll sponsor this change.
Comment #16
drunken monkeyProposal a) or b)?
I vote for b) myself.
We should then maybe also provide pre-defined first lines for other magic methods in some central place.
Comment #17
dawehnera)
Comment #18
tizzo CreditAttribution: tizzo commentedThe Technical Working Group reviewed this issue and before this can be tagged for final discussion we feel that we should attempt to come to a specific recommendation to propose to the Drupal community as a whole. If we can’t come to a consensus the TWG is happy to mediate but we feel that this issue's participants should try to come to more of a quorum than a 2/1 split.
As additional data points, the Zend framework appears to go with proposal B with respect to the __construct() method and Symfony and PHPUnit appear to go with proposal A with respect to the __sleep() method.
Comment #19
bojanz CreditAttribution: bojanz at Centarro commenteda)
Let's try to be a bit less redundant in our standards. The first line adds 0 value.
Comment #20
hussainwebI vote for a) as well.
Comment #21
donquixote CreditAttribution: donquixote as a volunteer commentedThe only concern I have with (a) is that it looks visually incomplete if some methods don't have a docblock. (-> scannability)
Also, this makes it harder to spot methods where the docblock was forgotten by the developer.
If a magic method already has a docblock with @param and/or @return, we don't need additional human-language description. Unless there is something relevant to say.
If the docblock would otherwise be empty, I would like to see something in there that justifies the docblock's existence, but makes it immediately obvious to readers that it does not contain any relevant information.
But seeing that this is really awkward, I think I could live with having no docblock at all in these cases.
@drunken monkey (#16)
The problem with (b) is that we really would have to come up with pre-defined text for all the magic methods, which developers need to look up, and reviewers need to verify. Sounds like yet another waste of time.
@tizzo (#18):
Interesting! So we could have one predefined first line for __construct(), but not do anything for the other methods.
I am not really convinced this is a good idea, but it is interesting.
Btw,
__sleep()
actually has a return type (array). But__wakeup()
has neither parameter nor return value, so it is a better example.Comment #22
slootjes CreditAttribution: slootjes commentedTotally agree with this. Would be great if someone could explain why someone would need the "Constructs the object." comment in the first place. I'm also addressing this more broader in this issue.
Comment #23
drunken monkeyComing up with the pre-defined text doesn't seem like that big a deal. I'll do that in ten minutes, if that's the issue, and we can then just iterate if things aren't clear enough.
Anyways: The proposal says nothing about forcing people to use this, it says "encourage": i.e., we provide these default doc blocks for the developers' comfort, so that they don't have to think about them, but it's nothing a reviewer is expected to check. If someone wants to provide their own doc block for a magic method (or doesn't know about the pre-made ones) that's totally fine, too. (As I see the proposal – I might be mistaken.) We just want to make it as easy as possible to follow the standard of documenting even those magic methods. (And encourage "Constructs a new class instance." instead of something that mentions the actual class name and would be inaccurate when inherited in a child class. Unless I'm mistaken the docs actually suggested such a wording ("Constructs a CLASS object."), but I can't find it anymore, so either I'm mistaken or it got removed already.)
@ #22: It's explained multiple times here already: less exceptions are generally better, it looks "cleaner" if it's not allowed to skip the doc block for some methods (everything else has them) and easier to spot methods that "illegally" miss the doc block, plus some developers might actually not be 100% familiar with all magic methods.
Comment #24
slootjes CreditAttribution: slootjes commented@ #23 What is the advantage of having standard dock block descriptions if they don't add anything useful like "Constructs a CLASS object."? Any developer should be able to see this because the name of the method is "__construct". I don't see a reason to provide all these useless comments at all. This can easily be solved by simply not requiring a description for every method and there are no exceptions anymore too.
Comment #25
mondrake+1 on a), would be DRY.
Go look at what Symfony does as of late.
Comment #26
claudiu.cristea+1 for a)... please!
Comment #27
Wim Leers💯 🙏
Comment #28
Chi CreditAttribution: Chi commentedWhy is this limited to constructors and magic methods? Most of useless comments belong to getters and setters.
Comment #29
Chi CreditAttribution: Chi commentedThere is one thing that may stop developers from omitting docblocks. Consistency. A class may look weird if some of its methods are documented while others are not. That's why I typically put dummy doc like "The object constructor" to methods.
Wondering, if it's a good idea to put something like
{@selfdoc}
there for cases when you want a docblock but don't have any useful documentation to put in it.Comment #30
catchConstructors specifically makes adopting #3278431: Use PHP 8 constructor property promotion for existing code in existing code harder than it should be. Adding getters and setters here makes this a bit more complicated - not every method with get or set in it is a getter or setter, and not every getter or setter has the word get or set in it.
Given constructor property promotion though, I think we should widen this a bit to include elements of #2209735: [policy] Remove DI verbosity by removing unnecessary doc lines.
Updating issue summary with a proposed resolution - based on option a.
Comment #31
catchphpcs already allows this:
So we only need a documentation change here.
Comment #32
donquixote CreditAttribution: donquixote as a volunteer commented@catch
What if I want to add a docblock, but I want to omit the first line?
This would be relevant if one of the parameters needs further explanation.
The original proposal would allow me to omit just the first line, but with the new title it is not fully clear. One possible interpretation is that if a docblock is added, it must contain all the required elements, including the first line description.
Comment #33
catchhttps://www.drupal.org/docs/develop/standards/php/api-documentation-and-... doesn't explicitly say that every method/function needs documentation, it is more about standards for documentation for ones that do.
So... actually there is no coding standards change here at all.
I think the end result is we need to add 'with the exception of magic methods like __construct()' to https://www.drupal.org/about/core/policies/core-change-policies/core-gat...
Comment #34
claudiu.cristeaThe documentation has been updated https://www.drupal.org/about/core/policies/core-change-policies/core-gat.... I think we can safely mark this as fixed.
Comment #35
xjmUnder:
https://www.drupal.org/docs/develop/standards/php/api-documentation-and-...
Comment #36
catchI couldn't find that sentence anywhere despite scanning that page three times.
I think we should have a draft change record here with the proposed change.
Comment #37
donquixote CreditAttribution: donquixote as a volunteer commentedAs xjm wrote.
Also this:
https://www.drupal.org/docs/develop/standards/php/api-documentation-and-...
Not much else is said about methods, especially the first line description requirement is not explicitly mentioned for methods. But one could assume that most of the rules for functions and for general docblocks also apply to methods.
I did not find a rule in the page that explicitly requires every doc comment to have a summary. Maybe I missed something. Still I think one can end up assuming that it is required.
Comment #38
claudiu.cristeaCreated the change notice https://www.drupal.org/node/3365111
Comment #39
claudiu.cristeaI agree with @donquixote but let's clarify also in https://www.drupal.org/docs/develop/standards/php/api-documentation-and-... as in the community there was the impression of summary being mandatory.
I've added "On PHP magic methods the summary is optional." at the end of bullet point next to the one cited by @xjm:
Changed from
To
Comment #40
donquixote CreditAttribution: donquixote as a volunteer commentedStill this does not explicitly say that it is required in other cases.
The reader can assume that it is required by default, if there is a rule that makes it optional under specific conditions. But we should not rely on that.
Comment #41
claudiu.cristeaFirst we need to understand if it's only missing from documentation that is required or it was always optional. Probably we'll never find that. There's a deep belief in the community that the summary is mandatory. Is it mandatory or not?
I will stop here because I feel we're losing time with an issue aiming to reduce the time lost in other places. There are also other coding standards like this opened for years with common sense proposals. Just coding standards orthodoxy which slows productivity and creativity,
Comment #42
catchUpdated the change record to match the new issue summary a bit closer.
If we're just saying the entire docblock for magic methods can be omitted, then whether the summary is optional or not doesn't affect this issue at all (fwiw I think if the function has documentation, the summary is required, the only exception to that would be {@inheritdoc} + extra docs, which unfortunately API module doesn't support, where the + extra would be an addendum to what's already there).
Comment #43
donquixote CreditAttribution: donquixote as a volunteer commentedI would be ok with the change.
However, this does not fully solve the problem stated in the original issue:
There are still constructors where we do have interesting things to say about the parameters, so we do want a docblock.
And for these constructors, the first line still has the same problems as stated in the issue summary:
The most natural and clean way would have been to open a separate issue where we make the entire doc comment optional.
But we can also leave this one in its modified version, and open a follow-up to either standardize the summary line, or make it optional.
Comment #44
quietone CreditAttribution: quietone at PreviousNext commentedI am working on announcement for this issue. As part of that I am updating the IS to have a section that clearly shows the proposed documentation changes. Currently, that has the doc pages that refer to 'methods'.
There are two docs that state the requirement for a docblock for 'functions', show below for reference. Does anyone think a change is needed to these as well?
Drupal API documentation standards (general)
Every function, constant, class, interface, class member (function, property, constant), and file must be documented, even private class members.
In-code API documentation is added or updated
All functions, classes, files, constants, etc. that are added or updated must be documented. (minimum requirements)
I did a wee test. I removed the doc block for an _constructor, enabled the
Drupal.Commenting.FunctionComment.Missing
andDrupal.Commenting.DocComment.MissingShort
and ran the commit code checks. There was no error on the changed file. This confirms what catch said earlier in #31.Comment #45
quietone CreditAttribution: quietone at PreviousNext commentedAdded proposed text changes to the IS.
Comment #46
quietone CreditAttribution: quietone at PreviousNext commentedAccording to the current process, step 6, this should be tagged final discussion.
Comment #47
quietone CreditAttribution: quietone at PreviousNext commentedSomehow my changes to the IS were lost. I had to revert to the previous version. Adding tag back.
Comment #48
catchI think it's worth updating the two places in #44 too. The IS changes look good!
Comment #49
apadernoIs it mandatory that magic methods do not have documentation comments? If magic methods must not have documentation comments, what quoted in comment #44 should be probably changed to say that documentation comments should be removed from the magic methods that are updated.
Comment #50
catch@apaderno I think we're just making it optional here. Sometimes we might want to document what we're doing in a magic method at a high level, I guess we might want to keep docs for constructors of value objects too.
I do think we should go through and remove all the constructor documentation from services, controllers etc. in core, but that's likely to happen at the same time as introducing property promotion to existing code.
Comment #51
apadernoI guess I misunderstood what comment #44 said. (Please disregard my previous comment.)
Comment #52
bbrala+1 on this. Less useless docs is great
Although out of scope I'm a bit confused why private methods are explicitly mentioned.
Comment #53
quietone CreditAttribution: quietone at PreviousNext commentedThere was no further discussion of this change in the latest coding standard meeting. #48 and #50 support the change. I am adding tags per step 8 of the CS process on the project page.
Comment #54
donquixote CreditAttribution: donquixote as a volunteer commentedActually now I am no longer so sure about this change.
I think our main motivation here is redundant docs on __construct().
But for other magic methods, are the docs really redundant?
Some things I want to know when I see a magic method:
A good exercise would be a MR that removes docs on a number of magic methods in core, to evaluate the impact.
Not something we would merge (or not here at least), but as a proof of concept.
Ideally with separate commits to see separate good examples from bad examples.
And I don't think we should look at symfony. They have far too few docs overall.
Comment #55
catch@donquixote we're only making the documentation optional, not forbidden, so we'll still be able to ask for docs on magic methods if there's some explanation to do (the same way that we ask for inline comments a lot).
Comment #56
donquixote CreditAttribution: donquixote as a volunteer commented@catch That's right.
But I don't understand how magic methods (besides constructors) are special, compared to other methods.
We should find at least some examples (in core) where a doc on a magic method could or should have been omitted.
The audience for these requirements is not only core development, but also the contrib ecosystem and custom code developed for corporations or institutions that like to comply with official standards, but are not so easily convinced by subjective code quality arguments.
The formal requirements often result in redundant comments, but half the time they actually result in useful explanations that would otherwise be missing.
But, if we can find a significant number of magic methods where we don't need the doc comment, then I change my mind :)
Btw the search regex is
function __([^c]|c[^o])
, to get magic methods that are not constructors.Comment #57
donquixote CreditAttribution: donquixote as a volunteer commentedI assume naming it .diff instead of .patch evades the testbot.
I used a regex to remove all the docs on magic methods.
Now we should find at least some of them that are redundant.
Comment #58
catchI think this is a good candidate - magic method that's a direct wrapper of another method, and it's always going to produce a string at the end.
Comment #59
catchThis is also a bit redundant, although you could argue it should be replaced with the inline comment at the top of the function body.
Comment #60
donquixote CreditAttribution: donquixote as a volunteer commentedI think there are 3 cases:
To me this seems like an example of case 2.
What I really want to know when I see this method:
Perhaps this is clear if we know what the PoItem class does.
I would want to know:
Comment #61
donquixote CreditAttribution: donquixote as a volunteer commentedActually, the "why" or "when" question is more important on magic methods, because you cannot use "find usages" to see when it is called.
Comment #62
andypostI recall dated debate about docblocks for overriden methods, specifically about rare need to add something after @inheritdoc - mostly why override required
Comment #63
quietone CreditAttribution: quietone at PreviousNext commentedcatch and I discussed the points raised by @donquixote. The points raised are valid but it is enough to enforce the doc blocks, especially after this proposal has gone through community approval. We decided that we should change this to be specific to constructors only. While that is a change to this decision it is narrowing the scope. Discussion on expanding the scope can be done in a separate issue.
I have updated the issue summary to specify constructors.
Comment #64
quietone CreditAttribution: quietone at PreviousNext commentedComment #65
bbralaReducing scope if fine. +1
Comment #66
donquixote CreditAttribution: donquixote as a volunteer commentedI am ok with the new scope, and the change proposed here.
The issue summary needs to be updated, some of the "Current text" and "Proposed text" parts look confusing.
(Can we use a diff format or is this not possible / practical?)
Also, can we give advice on when a constructor should have a doc comment?
E.g. a constructor doc comment can be omitted, if:
On the other hand: "If a doc comment is added, it must be complete according to the requirements on this page."
(see below, we should create follow-up to relax this)
----------
To honor the original request, we should open follow-up issue(s) to discuss some questions:
Given a constructor where _some_ parameters need a doc comment, can we relax the requirements for that doc comment?
(See #1512338: Revisit Coding Standard about parameters documentation or maybe other issues)
(To me it would feel awkward to omit any, but I could be spoiled by Drupal)
-----
I only now realized there is a dedicated channel for coding standards in slack :)
Comment #67
catchI think this is good advice, but I'm not sure if we should put that level of detail on this page, it would be too complex for a coder rule for example. We could add it to the change record though?
On the follow-up suggestions:
This would be an improvement, we'd have to modify the 'starts with a verb' rule, but that is over-applied. We could also consider omitting it altogether since it still won't add anything, but that would look weird maybe.
I think #1512338: Revisit Coding Standard about parameters documentation is probably the right place for that discussion if we wanted to apply it in general, but if not it'd probably need a new issue for constructors. Also I wonder if whether a single string/int/bool/array type hint that's not self-documenting might be better documented as a class property (if it is one) - that becomes optional already due to property promotion but it can still be explicitly defined.
Comment #68
quietone CreditAttribution: quietone at PreviousNext commented@catch, thanks for following up.
I have updated the coding standard pages and confirmed the change using the 'compare' option in the history.
Per step 10, I have removed the tag and set the issue to "Fixed".
Thanks everyone!
Comment #69
quietone CreditAttribution: quietone at PreviousNext commentedformatting fix
Comment #70
quietone CreditAttribution: quietone at PreviousNext commentedComment #71
xjmI'm not sure this change to "only constructors can be omitted" is what we want. In #3278431: Use PHP 8 constructor property promotion for existing code and the proposals related to it, we want the constructor to become the canonical documentation for promoted properties. The change from this issue is at odds with that.
Furthermore, I also don't see the required coding standards rule updates issues attached to this before the d.o documentation got updated.
Comment #72
donquixote CreditAttribution: donquixote as a volunteer commentedI think the idea is that a lot of the dependencies don't need a documentation at all, neither as constructor parameters nor on the property.
Personally I would prefer something where we start with separate conditional requirements for different parts of a doc comment (param, firstline description, return, other), and then say "If none of the individual parts of a doc comment are required, the entire doc comment becomes optional.". Similar to what I proposed for properties in #3376518-16: Allow omitting doxygen when type and variable name is enough.
Comment #73
catch@xjm much of the discussion on #3278431: Use PHP 8 constructor property promotion for existing code is about dropping the constructor docblock, that is why we held up making the change on this issue, so that we could remove the constructor docs at the same time as applying constructor property promotion across core.
Comment #75
catchOpened #3400560: Allow _construct() method to omit docblock.
Comment #76
jonathan1055 CreditAttribution: jonathan1055 as a volunteer commentedThis issue was finished before we had the new 9 step Coding Standards process finalised.
Coder issue #3400560: Allow _construct() method to omit docblock to modify the sniff is ready for review.