Updated: Comment #3

Problem/Motivation

We currently have naming standards for classes:
https://drupal.org/node/608152#naming

Item #10 says:

Classes and interfaces should have names that stand alone to tell what they do without having to refer to the namespace, read well, and are as short as possible without losing functionality information or leading to ambiguity. Notes:

  • If necessary for clarity or to prevent ambiguity, include the last component of the namespace in the name.
  • Exception for Drupal 8.x: due to the way database classes are loaded, do not include the database engine name (MySQL, etc.) in engine-specific database class names.
  • Exception for test classes: Test classes only need to be unambiguous within the context of the module they are testing.

However, many/most of the classes we have in Drupal Core 8.x violate this standard, which was adopted months ago on a separate issue:
#1507828: [policy, no patch] Revised standards for class naming within namespaces

So we either need to change the standard or start following it.

Proposed resolution

There are currently several proposed resolutions. For a summary, see #36.
The currently favored one is this:

Amend the standard to say that the namespace and class name together need to describe what the class does. We'll need to change item #10 on https://drupal.org/node/608152#naming and also the examples.

Proposed wording for item #10:

Class, interface and trait names should be unambigous in the context of their namespace, and not duplicate the information of the namespace as far as possible.

  • Exception for Drupal 8.x: due to the way database classes are loaded, do not include the database engine name (MySQL, etc.) in engine-specific database class names.

Remaining tasks

Adopt the new standard. No code or name changes are expected to be needed, since Drupal 8 is mostly following this principle rather than the standard that was previously adopted.

User interface changes

None.

API changes

None.

#1507828: [policy, no patch] Revised standards for class naming within namespaces
#1809930: [META] Many core class names violate naming standards

CommentFileSizeAuthor
#35 classes.txt258.68 KBdrunken monkey
#23 classes.txt266.76 KBDavid_Rothstein
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fubhy’s picture

I'd say we have to change the standard. Ignoring the namespace would lead to unacceptable long class names.

tim.plunkett’s picture

Please, let's allow namespaces to be used when determining what a class does.

1) We duplicate names when directly subclassing:
Drupal\Core\HttpKernel;
Symfony\Component\HttpKernel\HttpKernel;

2) We have Views field plugins and the Field entity type:
Drupal\field\Plugin\views\field\Field;
Drupal\field\Plugin\Core\Entity\Field;

If we try to enforce the policy as written, we'll quickly end up with http://en.wikipedia.org/wiki/Hungarian_notation

jhodgdon’s picture

Status: Active » Needs review

I've created an issue summary with proposed wording and links to related issues. I'm going to add comments on those two related issues pointing here so we can get reviews of the proposed wording, which is:

Classes and interfaces should have names that, when combined with their full namespace, tell what they do, read well, and are as short as possible without losing functionality information or leading to ambiguity.

(I'm not sure if we need that note in the proposed wording about the database classes, but I thought we should leave it in... is it still accurate?)

(And do we need anything else in the proposed wording?)

David_Rothstein’s picture

I thought the reason for the existing standard is so that when you're looking at code, you can actually understand what it's doing without having to refer to the namespace for context.

Here's an example from user.module.

At the top of the file:

use Drupal\entity\Plugin\Core\Entity\EntityDisplay;

Hundreds of lines further down:

/**
 * Implements hook_user_view().
 */
function user_user_view(UserInterface $account, EntityDisplay $display) {
....
}

Now if we assume that EntityDisplay were to be renamed to Display, the code becomes harder to understand, doesn't it?

David_Rothstein’s picture

By the way, are there really so many examples of code not following the current standard?

While looking for the above example, I definitely found some, but the majority seemed to already be using a class name that was descriptive on its own. I wasn't really looking through the entirety of the D8 codebase, though.

tim.plunkett’s picture

A good example is "DeleteForm".

\Drupal\forum\Form\DeleteForm
\Drupal\path\Form\DeleteForm

The Form\DeleteForm is redundant enough, we don't need Path and Forum tacked on the front.

jhodgdon’s picture

RE #5 - see this issue for a discussion about core classes violating the current standards. The last look through the list of classes was a while back, but the situation, if anything, has gotten worse (in as much as violation of the existing standard is bad).
#1809930: [META] Many core class names violate naming standards

jhodgdon’s picture

Issue summary: View changes

Make an issue summary with proposal

jhodgdon’s picture

We need to revive this issue.

The current standards in
https://drupal.org/node/608152#naming
say:

Classes and interfaces should have names that stand alone to tell what they do without having to refer to the namespace [....] If necessary for clarity or to prevent ambiguity, include the last component of the namespace in the name.

We now have many many many many classes in Core that violate this standard, and I think there is general agreement that Core is right and the standard is wrong.

Can we please update the standards doc? Do we agree?

dawehner’s picture

New proposal:

Classes and interfaces should have names that explain their responsiblities in the context of the namespace, so the namespace information does not have to be repeated.
Notes:
Exception for Drupal 8.x: due to the way database classes are loaded, do not include the database engine name (MySQL, etc.) in engine-specific database class names.
// This rule can be explained by the namespace rule above.
// Not needed anymore: Exception for test classes: Test classes only need to be unambiguous within the context of the module they are testing.
Unit tests should follow the same namespace path so Drupal\name\Example\Foo should have Drupal\Tests\name\Example\FooTest as test class.
jhodgdon’s picture

I don't understand the proposal in #9. It doesn't seem like we need either of the exceptions?

jhodgdon’s picture

Status: Needs review » Needs work
jhodgdon’s picture

Project: Drupal core » Drupal Technical Working Group
Version: 8.0.x-dev »
Component: documentation » Documentation

Coding standards decisions are now supposed to be made by the TWG

drunken monkey’s picture

Status: Needs work » Needs review

I'm very much in favor of this change. Having the same bloated names as in Drupal 7 in addition to namespaces seems insane. If no-one disagrees, it seems we should just be able to implement this?
My proposal for the phrasing (I agree with Jennifer, the exception has become unnecessary now):

Class, interface and trait names should be unambigous in the context of their namespace, and not duplicate the information of the namespace as far as possible.

jhodgdon’s picture

+1 on #13.

Crell’s picture

#13 seems fine to me.

donquixote’s picture

I agree that not everything needs to be repeated in the class name, but I would prefer if the main noun of the class name would describe what the thing is, and not just how it is different from other things in the same namespace.

E.g. Drupal\node\Plugin\Condition\NodeType should rather be Drupal\node\Plugin\Condition\NodeTypeCondition, because it is not in fact a node type, but a condition based on node types.

Drupal\zoo\Animal\Frog\Green should rather be Drupal\zoo\Animal\Frog\GreenFrog, because the object is a frog, not "a green".

jhodgdon’s picture

#16 is basically the standard we currently have in writing, which is not what is being used in practice. So we either need to decide to keep our current standard and patch all of Drupal Core to comply with it, or adopt what we're actually doing to be the new standard (which is what #13 is).

drunken monkey’s picture

OK, then what is needed further to implement this proposed change? Are there any more votes against? Do we need to get more votes?
It seems to me that, with a Beta release now out, a lot of module maintainers will start porting their modules, and it would be great if we had the coding standards up to date for that.

jhodgdon’s picture

As far as I know, the Technical Working Group needs to review this issue, adopt a policy, and edit the documentation. And as far as I know... they haven't addressed any of the many issues about coding standards in their issue queue. :(

David_Rothstein’s picture

If this change is adopted, could someone clarify how the five examples currently given in the table at https://www.drupal.org/node/608152#naming would be changed (if at all?). It is not obvious to me what they would look like under the new standard.

I am also wondering if there is some confusion over what the wording of the current standard actually means and how it should be interpreted. When I asked for an example in #5 above of a class in Drupal 8 that doesn't follow the current standard, #6 suggested "\Drupal\forum\Form\DeleteForm", but to me that looks like it's following the current standard exactly :) Is it possible we just need more clarity in the wording of the current standard, rather than trying to change it? I haven't done an exhaustive examination of the D8 code but my impression is still that there are more places that follow the current standard than places that don't (although there are enough of each that it's a problem either way).

David_Rothstein’s picture

For clarity and posterity, here are the 5 examples from https://www.drupal.org/node/608152#naming as they are currently written:

Namespace Good name Bad names
Drupal\Core\Database\Query\ QueryCondition Condition (ambiguous)
DatabaseQueryCondition (Database doesn't add to understanding)
Drupal\Core\FileTransfer\ LocalFileTransfer Local (ambiguous)
Drupal\Core\Cache\ CacheDatabaseDriver Database (ambiguous/misleading)
DatabaseDriver (ambiguous/misleading)
Drupal\entity\ Entity
EntityInterface
DrupalEntity (unnecessary words)
EntityClass (unnecessary words)
Drupal\comment\Tests\ ThreadingTest CommentThreadingTest (only needs to be unambiguous in comment context)
Threading (not ending in Test)
jhodgdon’s picture

RE #21... Some of these class names have been changed already, in accordance with the de facto standard that is in place: that class names omit parts that echo the namespace (as articulated in the wording in #13).

For instance, in Drupal 8.x core we have:
\Drupal\Core\Database\Query\Condition
\Drupal\Core\FileTransfer\Local
\Drupal\Core\Cache\DatabaseBackend

There is already an exception in the written standard on https://www.drupal.org/node/608152#naming for Test classes.

So there's your answer -- those two class names would change to match what we currently have in Core.

Further evidence... You can search on api.drupal.org for class names... There are currently 5 classes in Core named "Condition", and two named "DatabaseBackend". So we are not following our written standard at all -- those class names are NOT stand-alone -- they definitely are not unambiguous without their namespaces. And there are many many many more examples in Core, like the 6 classes named Select (mostly for select queries, but also for the Render Element called "Select"), and the two named Field (a Views field handler and a migrate class), and the six named Date (views handlers of various types, and a render element, and something in Symfony that's apparently a constraint validator, whatever that is), and the 4 named String (Views filter, Views argument, utility class, and typed data type).

So the question is:
a) We write down the standard that Drupal 8 is actually using. See #13.
b) We enforce our current written standards, which would involve renaming most classes in Drupal 8.
c) We have written standards that Drupal 8 blatantly violates.

I think (b) is unlikely to happen, and although the standard that we adopted and wrote down was discussed properly on an issue and the current state of affairs, as far as I know, wasn't... that is where we are.

(c) is undesirable.

That leaves (a).

David_Rothstein’s picture

FileSize
266.76 KB

Thanks... So, I'm not sure the wording in #13 really makes those examples clear? (When it says "not duplicate the information of the namespace as far as possible" that at least implies that you can use some common sense to duplicate information when you think it makes sense to, and I'd certainly do that myself for some of those examples.)

I'm also really not convinced that #13 is being used in Drupal core currently. I just ran this to list all core classes (excluding tests and non-Drupal code):

grep -RE -e "^(class|interface)" core/ | grep -v vendor\/ | grep -v Test

I attached the results. Skimming through them I see plenty that follow #13 but plenty that follow the current standard instead. I'm not even going to try to venture a guess as to which is more prevalent :) Unfortunately it does not look like this will be consistent in Drupal 8 no matter what.

The best solution I can think of is to distinguish a bit between interfaces and classes, and be more strict about interfaces because those are the ones that are by far the most likely to be used as type hints in function parameters (where #4 is a big problem if they don't have standalone names). Basically I consider #13 to be particularly problematic for interfaces.

Something like:

Classes and interfaces should have names that stand alone to tell what they do without having to refer to the namespace, read well, and are as short as possible without losing functionality information or leading to ambiguity.

If a class is not likely to be used outside of its namespace, it is acceptable to have a shorter name that is unambiguous within the context of the namespace only. Interface names, however, should always be globally unambiguous.

This is not perfect but would at least cut down on the number of violations in the core codebase.

donquixote’s picture

c) We have written standards that Drupal 8 blatantly violates.

We already have plenty of code that violates the standards.
E.g. missing docblocks, etc.
We do want to fix this, but it is taking really long time.

I think it would be desirable to rename the most confusing examples. E.g. the "Select" and "String" classes you mention really would benefit from a rename.

But if some of our code base does not comply, we will survive it.
We could even state in the standards that (currently) not all of core complies.

The main goal here, imo, is to increase readability and DX. If not for all of our code, then at least for the new stuff we write.
Consistency is also a nice goal to pursue, but it is less important than readability.

jhodgdon’s picture

Agreed -- thanks David -- some classes follow the current written standards, and some don't.

We probably need to get the Drupal 8 core maintainers and other key developers to weigh in here on what they think the standards should be. Then I would advocate for consistency, one way or another, although it may unfortunately be too late to do anything until Drupal 9 at this point.

jhodgdon’s picture

And as a note, I brought this up a *long* time before this. No one seems to care...

drunken monkey’s picture

When I asked for an example in #5 above of a class in Drupal 8 that doesn't follow the current standard, #6 suggested "\Drupal\forum\Form\DeleteForm", but to me that looks like it's following the current standard exactly :)

No, it isn't. ForumDeleteForm would be following the current standards – there are many DeleteForm classes in D8 (as #6 explicitly says).

The problem is probably that this also doesn't follow the proposed new standard, since the "Form" part would be redundant. So basically, complying with either standard would need a lot of renaming, which is unlikely to happen now, after the first Beta releases.
But I think the proposed new standard in #13 would still make more of the current class names acceptable, especially since there is a bit of room for interpretation with "as far as possible". At least it would not be as widely violated as the current standard.

Of course, the best would have been if people had just adhered to the coding standards while working on D8, but obviously that didn't happen and cannot be changed now. Now I think it makes sense to ammend the standards to more or less reflect the practice in Core, and thereby give clear guidelines to contrib module maintainers who want their code to conform to the standards, but avoid extraordinarily verbose class names that are also in stark contrast to Core's.

As for type hinting: in most cases, these will have a doc comment a few lines above them, which always has the FQN for reference, which should make this clear. For hooks, it's of course a bit more complicated, but we don't have that many of those anymore anyways, and the extra click probably won't hurt too much either. (Apart from the fact that we probably won't rename anything, or at least not much, anyways, so neither standard is going to make a difference there, at least for Core hooks.)

David_Rothstein’s picture

No, it isn't. ForumDeleteForm would be following the current standards – there are many DeleteForm classes in D8 (as #6 explicitly says).

Where are you seeing anything in the current standards that says a class name can't repeat more than one place in the codebase? All I see is that they are supposed to be understandable and not ambiguous, but that's not the same as saying they can never repeat (identical words aren't always ambigious if the difference is clear from the context). It also says that repeating the last part of the namespace ("DeleteForm") is good to remove ambiguity but the examples imply that repeating more than that ("ForumDeleteForm") is bad.

Anyway, I guess this proves my point above - we might need more clarity in the wording of the current standard first and foremost :)

For hooks, it's of course a bit more complicated, but we don't have that many of those anymore anyways, and the extra click probably won't hurt too much either. (Apart from the fact that we probably won't rename anything, or at least not much, anyways, so neither standard is going to make a difference there, at least for Core hooks.)

There are 265 hooks in Drupal 8 core right now (grep -R function\ hook_ core/ | grep \\.api\\.php | wc). And "extra click" only works if you are reading the documentation in the right place, e.g. api.drupal.org :) But the good news is that most hooks tend to take interfaces as function parameters rather than regular classes (for example the user_user_view() example I gave in #4 now looks different; it's actually EntityViewDisplayInterface) and most interfaces in Drupal core already seem to be pretty un-ambiguously named. I think if we changed the standard to focus on those kinds of situations there is not much that would need to be renamed.

drunken monkey’s picture

Where are you seeing anything in the current standards that says a class name can't repeat more than one place in the codebase? All I see is that they are supposed to be understandable and not ambiguous, but that's not the same as saying they can never repeat (identical words aren't always ambigious if the difference is clear from the context). It also says that repeating the last part of the namespace ("DeleteForm") is good to remove ambiguity but the examples imply that repeating more than that ("ForumDeleteForm") is bad.

Anyway, I guess this proves my point above - we might need more clarity in the wording of the current standard first and foremost :)

OK, I'm not a native speaker, so maybe I really misinterpreted this then – though #6 looks like Tim Plunkett also sees it my way. In my eyes, two classes having the same name is the very definition of "ambiguous". Saying that the context makes them unambiguous could also be used as an argument against the "Form" suffix.

But yes, we can agree that the current standards aren't very clear to begin with – especially the examples.

And "extra click" only works if you are reading the documentation in the right place, e.g. api.drupal.org :)

Or in an IDE. And those two will probably account for 95+% of D8 documentation reading.

most interfaces in Drupal core already seem to be pretty un-ambiguously named. I think if we changed the standard to focus on those kinds of situations there is not much that would need to be renamed.

But then we'd lose the nice correlation between a lot of classes and their interfaces. I'm also thinking of contrib here, and prefixing each and every class (or just interface) there with the module name would just lead to extreme bloat. Especially if you then have to use the FQNs in all comments, which would duplicate nearly the complete name.

donquixote’s picture

In my eyes, two classes having the same name is the very definition of "ambiguous".

I think the difference here is: The class name alone should be "practically unambiguous, one eye blind." or "unambiguous in most of the places where we expect it to be used" whereas class + namespace should be universally unambiguous even if used outside of Drupal.

So it is just a more sloppy interpretation of ambiguous.

tizzo’s picture

Project: Drupal Technical Working Group » Coding Standards
Issue tags: +needs announcement for final discussion

Moving this issue to the Coding Standards queue per the new workflow defined in #2428153: Create and document a process for updating coding standards.

Also marking for final discussion as this active issue received a lot of attention but needs a nudge to get finalized one way or the other.

effulgentsia’s picture

Title: [policy] Probably need to revisit the class naming standards » [policy] Revisit class naming standards
Issue tags: -needs announcement for final discussion

I think there's consensus among the participants here on the problem/motivation part of the issue summary, but I don't think there's enough buy-in on the proposed resolution to warrant wider announcement for "final" discussion yet. I'd like to see a proposed resolution that addresses the concerns raised by David_Rothstein, so untagging for now.

tizzo’s picture

Status: Needs review » Needs work

Good points, Alex.

Marking "Needs work" for a solution that answers @David_Rothstein's issues.

drunken monkey’s picture

Issue summary: View changes

I don't think "addressing David's concerns" is really possible in the context of the proposed resolution, since his proposal goes in an entirely different direction. As far as I understand, he just wants to clarify the current standards, while #13 proposes a completely different one.

As Jennifer explains in #22, there are three options:

a) We write down the standard that Drupal 8 is actually using. See #13.
b) We enforce our current written standards, which would involve renaming most classes in Drupal 8.
c) We have written standards that Drupal 8 blatantly violates.

#13 tries to implement b) – adapting the standards to make most of Core (though by far not all) comply with them.
#23 stays with c) – though you have to say that a lot of Core violates all kinds of coding standards, so this would hardly make it a no-go.

Of course, with just five people weighing in on the proposals, it's hard to decide anything, so I'd say what this issue foremost needs are a few more people stating their opinion. If David is the only one unhappy with #13, I don't think that should keep us from implementing it. (Or donquixote as well, from how it looks, though he proposes yet another solution, something between b) and c) – see #24.)
Also, Sebastian's and Tim's comment from the start of the discussion seem to also support #13 (but an explicit statement might still help).

Maybe just putting this up for "final discussion" would help get those additional voices, but of course I can also understand if you first want more consensus here.

drunken monkey’s picture

FileSize
258.68 KB

I tried to keep the previous comment as opinion-free as possible to make it a good summary for new people coming to this issue to weigh in.

However, looking through the existing classes in Core (new list version attached), I can't really see how it currently conforms to any of the discussed coding standards to any significant degree – there is a complete mixture of "duplicate anything except 'Drupal'", "use just a single word, completely meaningless without the namespace" and anything in between. Forms, controllers and entities, for example, are pretty good at being unambiguous (and, thus, complying to the current standards) while almost all plugin class names are utterly meaningless without their namespace.

So, if we really want Core to more or less comply with coding standards, we'd probably have to look at this in much more detail and draft a new standard that would be pretty complicated (e.g., keeping most of the old, but introducing some more exceptions).

I don't really think that's desirable, either (drafting a complicated standard just to fit the current chaos in Core), and I concurr with donquixote that we will survive Core violating one more coding standard. What I chiefly want to achieve in this issue is to have a meaningful, easily understandable and above all practical standard for contrib.
The current one, if applied as I see it (or even if adapted as suggested by David_Rothstein) would lead to absurdly long class names in contrib, as they (or at the very least the interfaces) would have to always include the module name, and probably a lot of the namespace.

I quite like donquixote's proposal #24 of keeping class names ambiguous and short, but demanding that they "make sense" by ending in a word that really describes what they do (without necessarily making them unambiguous). If we drop the "make the standard to match Core" requirement, the only real downside I'd see here is that this wouldn't be the easiest-to-follow standard and we'd have to take care to phrase it properly. It would make the names slightly longer, but not nearly as long as the current standard in a lot of cases, and it would give us names which probably let developers identify the class in most cases without looking at the FQN.
What I really don't like about my proposal #13 is exactly that: that we end up with minimalistic names which become meaningless without the namespace, and thus probably a bit harder to parse at a glance when coding. (I'd just prefer it a lot to the current standard, and thought until now that it aligned better with what Core does.)
Also, with my proposal, the name of some plugin classes becomes hard to determine. (E.g., Search API defines a single Views cache plugin – what should that be called? The complete information is already in the namespace.)

Maybe some good suggestions/standards regarding import aliases could solve that, though. Might make things more confusing/unstandardized after all, though.

drunken monkey’s picture

So, to summarize all proposed resolutions (I hope):

  1. Keep the current standards: class names should be unambiguous and should describe the class completely without referring to the namespace.
  2. #23: Adapt the current standard to let "primarily internally used" classes be more ambiguous – never interfaces, though. Would probably need a good explanation and/or set of examples.
  3. #13: The opposite: let class names be as short as possible and only be unambiguous (and, sometimes, make sense) in combination with their namespace.
  4. #24 (no proposed phrasing yet): #13 with the addition that, where necessary, a word describing what the class does should be attached, so that the names "make sense".

("Class" always meaning interfaces and traits, too.)
Core doesn't really conform to any of those, but practically uses a mix of "all of the above".

(Sincerest apologies for the wall of text!)

drunken monkey’s picture

Issue summary: View changes
donquixote’s picture

Following up on what I proposed in #16 and #24 and #30, maybe we could add (to be discussed):

  • If we *already know* something is going to have the same class name as something else in core, or in a popular contrib module or library, we try to find a different name. E.g. if I would want to provide an alternative db layer in contrib (for which reason whatsoever) I might try to use different class names than those in core dbtng. E.g. MySelectQuery as opposed to just SelectQuery.
    This is controversial - we could say that the different namespace is sufficient.
  • Naming is not an exact science. There is still human judgement involved, and sometimes there is no "perfect" name.
Indrapatil’s picture

Assigned: Unassigned » Indrapatil
Indrapatil’s picture

Assigned: Indrapatil » Unassigned