Change the hook separator from '_' to '_hook_'

Damien Tournoud - August 13, 2009 - 17:31
Project:Drupal
Version:8.x-dev
Component:base system
Category:task
Priority:normal
Assigned:Unassigned
Status:needs review
Description

This has been discussed numerous times. It's a good idea for countless reasons (see #451152: Implementing a hook on the behalf of another module and #367355: Module names should not contain an underscore(_) for some of them).

#1

Damien Tournoud - August 13, 2009 - 19:39
Status:active» needs review

Here is a first trial.

AttachmentSizeStatusTest resultOperations
548470-change-hook-separator.patch457.87 KBIdleFailed: 11051 passes, 938 fails, 1635 exceptionsView details | Re-test

#2

System Message - August 13, 2009 - 19:55
Status:needs review» needs work

The last submitted patch failed testing.

#3

Damien Tournoud - August 13, 2009 - 21:11
Status:needs work» needs review

Some progress.

AttachmentSizeStatusTest resultOperations
548470-change-hook-separator.patch507.69 KBIdleFailed: Failed to apply patch.View details | Re-test

#4

System Message - August 13, 2009 - 21:20
Status:needs review» needs work

The last submitted patch failed testing.

#5

Damien Tournoud - August 13, 2009 - 21:21
Status:needs work» needs review

Rerolled.

AttachmentSizeStatusTest resultOperations
548470-change-hook-separator.patch502.88 KBIdleFailed: Failed to apply patch.View details | Re-test

#6

Damien Tournoud - August 13, 2009 - 21:24

And one with the correct path prefix.

AttachmentSizeStatusTest resultOperations
548470-change-hook-separator.patch501.37 KBIdleFailed: 10808 passes, 1370 fails, 1172 exceptionsView details | Re-test

#7

System Message - August 13, 2009 - 21:35
Status:needs review» needs work

The last submitted patch failed testing.

#8

catch - August 13, 2009 - 21:52

subscribing. While this is a bit ugly, and would take some getting used to, I think it's a very good idea for a number of reasons.

#9

Damien Tournoud - August 13, 2009 - 21:53

If someone wants to play with this, here is the patch and the sed script used to generate the big patch above.

AttachmentSizeStatusTest resultOperations
548470-change-hook-separator.patch31.44 KBIdleFailed: Failed to apply patch.View details | Re-test
548470-sed-script.txt4.25 KBIgnoredNoneNone

#10

webchick - August 13, 2009 - 23:27

Could someone please enumerate at least some of the "countless/numerous" reasons that make this patch compelling so close to freeze? We've managed to get 13 releases out without this, and no one has died so far, to my knowledge.

#11

catch - August 14, 2009 - 00:04

The number of contrib modules has doubled every release or something, module namespaces are going to get more crowded.

Whether we keep the registry or remove it, knowing that a hook implementation is some_module_name_hook() instead of some_module_name_hook() is going to get more and more necessary.

#12

cha0s - September 2, 2009 - 22:41

Latest attempt (curious for test bot to tell me what's still broken ;))

AttachmentSizeStatusTest resultOperations
548470.patch441.61 KBIdleFailed: Failed to install HEAD.View details | Re-test

#13

KiamLaLuno - September 2, 2009 - 22:49

Should not the hook name be declared in the comment placed before the function body? Every hook implementation should have Implement hook_hook_name().

#14

catch - September 3, 2009 - 02:23
Status:needs work» needs review

CNR for the bot.

#15

System Message - September 3, 2009 - 02:35
Status:needs review» needs work

The last submitted patch failed testing.

#16

nevets - September 3, 2009 - 02:50

Arg, talk about a painful patch without a real benefit. The current system works, it used alot and all this patch really does is make busy work for module developers.

#17

KiamLaLuno - September 3, 2009 - 03:04

Add also that there could be some module developers who, seeing the hooks being named in this way, will start to name other function so; if that really happens (and I am sure it would happen, as Drupal hooks are simply PHP functions), then it would not be possible to know if a function is a hook by watching its name.

The reason I think some developers would start to name their module functions module__function_name() is that the module functions are named module_function_name() because it is the name convention used for Drupal hooks; once you change the hooks name convention, then also the normal functions could start to follow the same convention.

Nothing have stopped anybody to use two underscores after the module name until now; once they note they can use two underscores also for the normal functions (and they see it works), they will start to use the two underscores for all the functions their modules define.

#18

David_Rothstein - September 3, 2009 - 05:09

Hm... I would tend to agree that a double underscore is confusing and awkward.

If we're going to do this at all, maybe consider the possibility of a more descriptive separator? For example:

<?php
/**
* Implement hook_form_alter().
*/
function mymodule_implement_hook_form_alter() {
...
}
?>

#19

alexanderpas - September 3, 2009 - 05:21

actually... using double underscore between the module name and the actual function name, is in my opinion NOT detrimental, as it still creates more properly namespaced function names.

- views_menu_alter
v.s.
- views__menu_alter
- views_menu__alter

also, views_menu implementing hook_alter, while views implements hook_menu_alter ensures some pretty fatal errors.

in addition, it follows PHP precedent as that already uses the double underscore at the start (and end) of a string (or funtion/method) for magic stuff. (consider PHP as module '')

#20

KiamLaLuno - September 3, 2009 - 05:19

@#18: That would not apply for implementations of hook_form_FORM-ID_alter(); what would the hook name be, in that case?

@#19: The purpose of the change should be to make clearer when a function is the implementation of a hook, not to make more clearly namespaced functions.

As also reported from nevets, it is not worth to change the way the hooks are named, and it doesn't take anything good.

#21

alexanderpas - September 3, 2009 - 05:31

while it might not be the main intention, it does play on the background (see:#367355: Module names should not contain an underscore(_))

#22

KiamLaLuno - September 3, 2009 - 05:32

also, views_menu implementing hook_alter, while views implements hook_menu_alter ensures some pretty fatal errors.

Drupal doesn't define a hook_alter() hook; if there would be a third-party module to define such hook, then the fault would be of that module.
If then view_menu.module would implement hook_alter(), and both view_menu.module and views.module would be installed, the problem would be to have a function defined twice; even using two underscores for the hook functions, the problem would still present for other functions defined from the modules.

#23

David_Rothstein - September 3, 2009 - 05:34

@#18: That would not apply for implementations of hook_form_FORM-ID_alter(); what would the hook name be, in that case?

Wouldn't it just be mymodule_implement_hook_form_FORM-ID_alter()?

#24

alexanderpas - September 3, 2009 - 05:42

@#22
my bad, was thinking of these:
- hook_prepare
- hook_insert
- hook_delete
- hook_update
- hook_validate

conflicting modulename endings, when prefixed with any other module name:
- actions
- comment
- file
- image_style
- node
- node_type
- taxanomy_term
- taxanomy_vocabulary
- user

for example, the module field_actions can not exist due to namespace conflicts.
(field_delete & field_actions_delete vs. field_actions_delete & field_actions_actions_delete)
even if only one module implements the field_actions_delete, wrong hooks get fired at the wrong time.

field_file_delete anyone?

#25

KiamLaLuno - September 3, 2009 - 05:44

@#23: Then, for a function that would alter the content type form, the function name should be mymodule_implement_hook_form_node_type_form_alter(). It seems that the name is getting too long, IMO.

#26

alexanderpas - September 3, 2009 - 05:46

mymodule__form_node_type_form_alter() would be a lot better

#27

KiamLaLuno - September 3, 2009 - 05:51

for example, the module field_actions can not exist due to namespace conflicts.

Which conflict should that be?

EDIT: The conflict would be for field_actions_delete(), which could be interpreted as implementation of hook_delete() made from field_actions.module, or as implementation of hook_actions_delete() made from field.module.
Probably field_actions_delete() would be interpreted as implementation of hook_delete() only if there is another hook implementation; still the conflict could exist for some hooks, and some modules.

#28

cha0s - September 3, 2009 - 10:04

I should have tested the patch better before I submitted, HEAD is totally broken visually with this patch.

However, I do think namespacing hook implementations better IS a win, but I'm not arguing that it will create work for existing module maintainers. This issue was highlighted as one that was desirable to get in at the code sprint in Paris, however it may take a bit to get it in... (too long?)

#29

Damien Tournoud - September 3, 2009 - 12:07

I still would like to get this in. Properly namespacing our hooks will strongly reduce the pain of conflicting module names, and at the same time it will lower the confusion.

I believe that:

<?php
function views__menu() { }
?>

is clearer then:

<?php
function views_menu() { }
?>

#30

nevets - September 3, 2009 - 13:29

Neither one is clearer, it is a matter of convention and changing the convention with so much existing code generates busy work. The hooks are already "properly" namespaced, because it is a convention any choice allows for accidental function naming that conflicts with a hook name. I for one would like to see a stop to changes in Drupal core that have not real benefit but make work for developers.

#31

lilou - September 3, 2009 - 13:39

Personnaly, i prefer :

<?php
function views_hook_menu() { }
?>

than :

<?php
function views__menu() { }
?>

#32

KiamLaLuno - September 3, 2009 - 17:36

I agree with nevets.
It's just a convention, and nothing would stop somebody to call a module views__menu.module; in that case there would still be a conflict between two modules. As Drupal is not forcing a module to not use the underscore in the module name (which is a good thing, IMO), then it will not force a module to not use two underscores in its name.

#33

catch - September 3, 2009 - 18:02

Unless there's a really good reason why not (and modules with 'hook' in name isn'n't one), mymodule_hook_hookname() seems pretty good - since it'd help searching within module code as well and we could possibly drop the 'Implements' from PHPdoc one day.

#34

KiamLaLuno - September 3, 2009 - 18:30

mymodule_hook_hookname() is much better, IMO; it avoids conflict problems, and it allows a module to have a function like mymodule_delete(), which would not be confused with hook_delete().
In this case, it would make sense to not accept modules that have a name ending in _hook; it makes more sense than to not accept a module with a name containing an underscore (which has never been done).

The problem is when to implement this change; maybe it would be better to postpone it for Drupal 8.x. Although, I am not contrary on implementing it on Drupal 7.x.

#35

alexanderpas - September 3, 2009 - 19:48

It's just a convention, and nothing would stop somebody to call a module views__menu.module; in that case there would still be a conflict between two modules.

do you have a usecase for a modulename with two underscores?
single underscores are common replacements of spaces.

In this case, it would make sense to not accept modules that have a name ending in _hook; it makes more sense than to not accept a module with a name containing an underscore (which has never been done).

it would be similar easy to deny modulenames with double underscores.

actually, denying modulenames with double underscores is one of the more easier things to do.

#36

KiamLaLuno - September 3, 2009 - 20:08

actually, denying modulenames with double underscores is one of the more easier things to do.

As module names has never been forced to not have a single underscore, I don't see why modules should be forced to not have two underscores.

do you have a usecase for a modulename with two underscores?

Do you have an example of module containing the word _hook in its name?
I find more logical to explain that a function name should contain _hook_ only when it is a hook implementation, rather than explaining that a function name should not contain two underscores.

#37

alexanderpas - September 3, 2009 - 23:30

Do you have an example of module containing the word _hook in its name?

how about a captain_hook module??? oh wait... that woudn't pass the GNU requirement ;) but seriously, how about a plot_hook module

in addition, I prefer generic solutions over specific solutions.

remember that PHP developpers normally don't use double underscores due to being reserved for PHP when used at the start (or end) of an string (__FILE__, __CLASS__, __construct())

#38

catch - September 4, 2009 - 04:11

Well hooks is a specific system, so using the word 'hook' in a function name doesn't seem any more specific than what we have now. Just a note that _hook_ would also simplify #521838: drupal_get_schema_versions() takes 30% of page execution time on /admin a bit.

#39

alexanderpas - September 5, 2009 - 16:26

#40

chx - September 6, 2009 - 06:28
Status:needs work» needs review

A _hook_ would be awesome. I am going to come up with a script. Surely you do not want a patch -- only at the latest minute, said patch would break all the time. No, a script is what we need here. Set to CNR to attract more opinions esp from Dries/webchick.

#41

chx - September 6, 2009 - 06:29

Note that if you have page_hook module then your menu would be page_hook_hook_menu.

#42

chx - September 6, 2009 - 09:12
AttachmentSizeStatusTest resultOperations
change_php.txt2.27 KBIgnoredNoneNone
hook.patch233.51 KBIdleFailed: Failed to install HEAD.View details | Re-test

#43

chx - September 6, 2009 - 09:12

And a script.

AttachmentSizeStatusTest resultOperations
change_php.txt2.27 KBIgnoredNoneNone

#44

chx - September 6, 2009 - 09:19
Title:Change the hook separator from '_' to '__'» Change the hook separator from '_' to '_hook_'

#45

System Message - September 6, 2009 - 09:26
Status:needs review» needs work

The last submitted patch failed testing.

#46

Crell - September 6, 2009 - 09:29
Status:needs work» needs review

I'm really not fond of changing something this fundamental so close to freeze. However, if we must do so then I think I find modulename_hook_foo() less offensive than modulename__foo(). It is more self-documenting and helps set "real" hooks apart from normal namespaced functions.

#47

Dries - September 13, 2009 - 15:02

I prefer "__" instead of "_hook_". Not everything is a hook, and we have to figure out how to have better namespacing given that many contribute modules use a single underscore in their name. In other words, I don't think "_hook_" solves the actual problem. _hook_ would only solve part of the problem.

"__" is quite nice because it makes me think of "::".

#48

David_Rothstein - September 13, 2009 - 20:04

Using "__" does not solve the complete problem either, because it does not address the issue of a module which accidentally implements another module's hook.

To solve the complete problem would require a mix of both solutions; for example, something like this:

<?php
function mymodule__hook_form_alter()
function
mymodule__some_random_function()
?>

I'd therefore suggest maybe just going with _hook_ for now, since it's necessary either way, and solves the biggest part of the overall problem.

Although it's not clear to me if we're even talking about Drupal 7 anymore at this point, or whether this issue should already be moved to Drupal 8?

#49

Dries - September 13, 2009 - 20:18

To be honest, this does not sit in the top 20 things to in the next 4 weeks of the "Drupal 7 code slush". I think we should be focus on other things, and recommend moving this to Drupal 8.

#50

alexanderpas - September 13, 2009 - 20:23
Version:7.x-dev» 8.x-dev

done.

#51

Crell - September 13, 2009 - 23:58

The real long-term solution is actually to use \, which is the PHP 5.3 namespace separator. Anything else we do here is just a stopgap until we can require PHP 5.3. :-)

#52

mattyoung - September 14, 2009 - 03:16

subscribe

#53

arhak - September 30, 2009 - 23:45

+1 to #35

having double underscores as namespace separator would serve for more than just hooks
for instead:
- hook names (which might have __hook or hook__ as well)
- constant names (like define('MYMODULE__MYSUBNAMESPACE__DEFAULT_VALUE', ...))
- submodules (like cck, cck__nodereference, etc)

#54

alexanderpas - October 4, 2009 - 01:47

@Crell
actually... you would have to use \\ or else... let's just say drupal\node would become

drupal
ode
really... that's the biggest phpWTF of all.

@arhak
sub-modules are also just regular modules, and still need to confirm to the naming convention, so they would be cck_submodule__hookname()

#55

donquixote - October 5, 2009 - 02:43

My opinion:

If we want this in D7:
modulename_[_]hook_[_]hookname
modulename__some_function as a recommendation.
and dedicated conventions for _alter_ and _preprocess_ etc.

If we want to wait for D8:
Use PHP namespaces and require PHP 5.3 (and see what PHP 6 brings).

@alexanderpas (#54):
Totally phpWTF, very disappointing.

#56

pounard - October 16, 2009 - 17:30

I think that prefixing all hooks with _hook_ (implementation hook_nodeapi would be mymodule_hook_nodeapi() seems good; Nobody will never call his module mymodule_hook, plus, it's also really convienent when you use an IDE capable of outlining your code, it means that with a single look you can find the hooks implementations in anybody's code in a really easy way, which sometimes would be really usefull, when you try to understand a non documented module.
I really don't like the double underscore stuff.
Namespacing isn't so great, this is far away from the original template methods pattern (the hook system), which is more like specialization (not quite, but implementations uses specialization) in OOP. A lot of OOP languages use namespacing, but not to solve this kind of problems, it will be a total mess; but this is still my opinion. A lot of OOP discussions says that the right way to deal with conflicts is to have strict naming conventions (even in OOP code!).
All of this was IMHO.

#57

rfay - October 22, 2009 - 17:51

This would be a fundamental improvement to the Drupal environment.

 
 

Drupal is a registered trademark of Dries Buytaert.