Quoting Aaron Winborn <winborn@advomatic.com>:
As we don't have public and private scope,
But we do, really. Sure it's global but we do have the ability to create standards that set a private scope using the module name and prefixing the module name with an _ (underscore) character for private module use.
I think that in practice, failing a better method, module_invoke should be the safer way to do this.
As I've stated already, module_invoke is meant to be used to invoke hooks. Using module_invoke for anything else is confusing and can cause issues should module_invoke change its methods.
In my modules, if I have functionality I don't want to expose, I prefix it with an underscore: _module_name_private_api.
This should be the case for all private symbols. This ensures that some new hook isn't going to cause you to have to rename your private functions. Stating this brings another issue with the Drupal hook system in that my naming of my module static function isn't namespace safe. For example mymodule_myfunction becomes invoked when Drupal or some other module adds a hook and invokes all implementations of hook_myfunction which isn't what I meant for mymodule_myfunction. This is most easily avoided by using a static class and defining all functions for the module within the class. However, this should only happen with a new version of Drupal and we have to convert the modules to use the new versions anyway; but, how many of us check our function names as being a new hook?
Thus, in my hypothetical contract, module_name_public_api would be safe to be called using module_invoke, at least within a core version, and would at least guarantee the same arguments and expected result, even if the inner codebase changed. Whereas the private function would have no such guarantee, and modules invoking it do so at the risk that the function's arguments may change, or it may even cease to exist.
No such guarantee for public function can be made and private functions should remain private for the reason you suggest. Another reason to use classes for the module functions; if I mark the function private, it truly is.
Additionally, module_invoke would allow for optional dependence, which is generally where I use that anyway.
Not anymore than using function_exists. Earnie -- http://for-my-kids.com/ -- http://give-me-an-offer.com/