Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

User:Eloy Lafuente (stronk7)/Namespaces

From MoodleDocs
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Note: The outcomes of this discussion/voting is now part of Coding style. Thanks for your interest and collaboration!


(voting, commenting here is already closed. Go to MDLSITE-2549 for more information)

Summary

This tries to be a brief summary of all the discussions happening @ MDLSITE-2549 and other places about to rule/unify the way we are going to use autoloading and namespaces. Some of the points below have not produced any controversy and are simply exposed, and others will be voted (nonbinding survey). Finally, integrators will, with all the information gathered, decide. Everything will be numbered for reference.

Terms

  • autoloading: or how the hell a class becomes available without requiring/including it.
  • namespaces: that awesome backslashed syntax invented to make code to look awful.
  • core: all the code bundled with moodle standard distribution. (moodle core + subsystems + plugins).
  • addon: all the code not part of moodle standard distribution (hacks, contrib plugins...)
  • code: any of the above (core + addons).
  • component: frankenstyle name of any subsystem or plugin (core or addon).

(for the sake of health, let's keep 3rd part libs apart)

Autoloading (briefly)

How it works

Every valid component (core or addon) can have a "classes" directory. There you can have some files, each one containing one class that, by following some simple rules, will be autoloaded.

Types

There are 2 types of autoloading supported and allowed in Moodle (since 2.6):

  • NONAUTO: non-namespaced autoloading: for component "xxxx" the class "xxxx_yyyy" will be autoloaded if it's defined in a file named "yyyy.php" under the "classes" directory of the component. Examples: core_text, core_course_management_renderer, mod_lesson_file_info. Usually this type is used for well-isolated classes, not needing much architecture, often being refactors of non-autoloaded stuff.
  • NAUTO: namespaced autoloading: for component "xxxx" the namespaced class "\xxxx\yyyy" will be autoloaded if it's defined in a file named "yyyy.php" under the "classes" directory of the component. Examples: \core_calendar\type_base or, using multilevel namespaces, \core\event\base, \mod_assign\plugininfo\assignfeedback.

Sort of justification

Basically, both autoloading techniques are pretty similar, but namespaces autoloading (NAUTO) comes with all the extra benefits of namespaces (names collision, organization, shorter class names...) and is supported for any depth (NONAUTO provides only 1-level autoloading).

Ultimately, the agreement about to support NAUTO leaded to the first uses and implementations of code using namespaces within Moodle. And, trying to keep everything homogeneous and consistent, while allowing developers to use namespaces, this document summarizes all the points to be considered - until now).

Namespaces, here we go

Preliminary

  • P1: namespaces are not mandatory (level0 is namespaces free and provides autoloading).
  • P2: global-scope code is not forbidden (yet).

Basis

  • B01: These rules apply exclusively to code under the "classes" dir of every component. Again, explicitly, let's ignore 3rd part libraries.
  • B02: Namespaced classes only can be declared within "classes" dirs. In other words, the use of the "namespace" keyword is forbidden out from "classes" dirs.
  • B03: Namespace naming follow code class naming style. If possible, a single english word is preferred.
  • B04: Only one namespace is allowed by file. It must be the very first line of code in the file (after the standard file comments).
  • B05: The bracketed namespace nomenclature is forbidden - namespace {...}.
  • B06: __NAMESPACE__ should not be used ever (unless there is a very-very good reason for that).

Importing (a.k.a "use" keyword)

  • U01: The utilization of imports is allowed (and recommended to avoid \very\long\namespaced\class\name to be used everywhere in code).
  • U02: It's recommended to, always, import individual classes, not namespaces.
  • U03: The utilization of named imports (the "as" keyword) is not recommended (unless there is a very-very good reason/conflict to be solved). Default aliasing should be enough 99.99% of times.
  • U04: Import declarations should happen immediately after the namespace declaration and before anything else.
  • U05: TOVOTE: Allowed syntax of imports:
    • A) (voting winner) One import per line is required. (example)
    • B) Multiple imports (comma separated) per line are required. (example)
    • C) Both A) and B) are ok.

Namespace levels and reserved keywords

  • L01: Level 1 namespace must be always a valid component name.
  • L02: TOVOTE: Level 2 namespace:
    • A) (winner decided in the issue) Must be always a valid Moodle API, with an special "local" subspace available for everything else.
    • B) Can be anything except valid Moodle APIs, that are reserved for classes belonging to such APIs. (non-api example), (api example)
    • C) No, my friend, there is not C) here, lol.
  • L03: (this does not have sense once L2 has been defined) In any case, APIs always get precedence (present and future) over any other level 2 namespace used (that will need to be moved away from the reserved name).

Class association

  • A03) TOVOTE: Always apply for the maximum level of detail deciding the namespace for a class (The "event observers" case, currently in a non-normalized way, look for them in code)
    • A) (voting winner) Yes (a class zzzz known to belong to component xxxx, api yyyyy, should be \xxxx\yyyy\zzzz).
    • B) No (we can put it elsewhere, as far as it's autoloaded, who cares). (non-namespaced observer), (namespaced observer).
    • C) Any other alternative worth considering? Cannot imagine any.

Backslashing

  • S01: The "namespace" and "use" keywords must not use a leading backslash ever. They are, by definition, fully qualified names always.
  • S02: Global scope function backslashing (from namespaced code) is forbidden. Unless there is, at some point, some conflict (keep them reduced).
  • S03: TOVOTE: Global scope class backslashing (from namespaced code):

Some extra tiny details

  • X01: The namespace may have a phpdoc block with brief + long descriptions.
  • X02: For readability, add a blank line after the namespace declaration and after the last use declaration.