RE: [PEAR-DEV] Re: PEAR2 Coding standards, Autoloading and Namespaces
| From: | Baptiste Autin | Date: | Fri, 04 Apr 2008 21:04:23 +0000 |
| Subject: | RE: [PEAR-DEV] Re: PEAR2 Coding standards, Autoloading and Namespaces | ||
| References: | 1 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-49622@lists.php.net to get a copy of this message | ||
Sorry to pop up in that discussion, but I'm finalizing an (I hope PEAR-)
package called PHP_UML (formerly PHP_XMI) and, since this package parses PHP
code and deals with namespaces/packages a lot, I'd like to share my
miserable point of view with you.
IMO, people tend to confuse four different concepts:
- naming convention
- package
- namespace
- filesystem
...even if they are often intricate (e.g in Java, a package is closely
related to the filesystem)
So, according to what Greg said, a PHP namespace is like "a part of the
class name". It means that PHP will not manage a new kind of object called a
"namespace". Namespaces in PHP are just a facility to qualify, to point at,
not a new kind of entity.
But it is not a naming convention either: one can still name in a messy way
with namespaces.
On the other hand, in MOF (Meta Object Facility, an OMG language for
model-driven engineering, involved in my PHP_UML, by the way), there are no
namespaces, but there ARE packages, because names don't matter in MOF.
More generally, in metamodels, a package is defined like a particular object
who can own elements.
By extension, in UML, a package is a container for almost every typed
element. It really stands as itself, it has attributes, may have an ID, and
so on.
Contrariwise, in XML, there are no packages ("what" would package?) but
there are namespaces, a bit like PHP does.
The reason for <xsl:foo> and <fop:foo> is to allow "foo" to appear in
different contexts, and we don't care if xsl or fop map to something
concrete (in the case of xslt and fop, they do).
Now, what about PEAR ?
IMO, along the years, PEAR has maintained two different things
simultaneously:
- a naming standard (prefixing class names with a category)
- a notion of package (which is, in many people's mind, more or less linked
to the file tree organization of PEAR)
So, in spite of what Greg B. said - and I don't quite agree with him on that
point - we are facing two different things.
Have a look at the actual HTTP_Request docblock:
It is:
@package HTTP_Request
It is NOT:
@package HTTP::Request
Nor:
@package HTTP
@subpackage Request
AFAIK, nobody ever mention the need for a PEAR package called "HTTP".
On the other hand, the package "HTTP_Request" really exists, independently
of its name, it is not an abstract concept. There's a leader programmer for
it, there's a cvs fork for it, it has a date of birth, a bug tracker for it,
all the stuff in PEPR, etc. No matter its name, we think of it in term of
"package", not in term of namespace.
So there is ALSO a notion of package management in PEAR, obviously.
And so today, it's just like we are looking for a way to transpose that
particular organization directly into our PHP code, through those famous new
namespace/use instructions.
Now, the question is: how are we (if I'm allowed to write "we" :-))
achieving it? Is it only achievable?
If a PHP namespace is just a naming facility for classes, then one can
(should?) use it for what it is, and rename the class HTTP_Request in
Request, and put it into the HTTP namespace. That makes sense, though it
breaks compatibility. No package stuff here. Only names, only words. That's
the first scenario.
But nothing prevents us of using PHP namespaces for implementing that noble,
concrete, solid as a rock, PEAR concept of @package. That's the second
scenario. If we opt for it, HTTP cannot seriously become a package. Whose
package would it be? What would its purpose be? Shall we invent a new kind
of "white" package, only to satisfy some grammatical abstractions?
So the package would remain HTTP_Request. And then... well, either we rename
its classes, either we don't. But we probably have to be realistic, we
cannot rename everything.
The third scenario is to do nothing :-)
More seriously, probably like others, I am a bit disappointed by PHP
namespaces. They might not be the great packaging system we could have
dreamt for. Maybe we'll have to wait for the next bus.
But whatever the final decision, I think we must be accurate about what we
are talking about: package, or namespace.
On the PHP internal list, too, those two concepts are often confused, and
this is very misleading IMHO.
PS: and for those interested, my package:
https://sourceforge.net/projects/phpuml
I am to propose an initial PEAR version here very soon.
Baptiste Autin
-----Original Message-----
From: Joshua Eichorn [mailto:josh@bluga.net]
Sent: vendredi 4 avril 2008 18:56
To: Greg Beaver
Cc: Travis Swicegood; Jeff Moore; PEAR
Subject: Re: [PEAR-DEV] Re: PEAR2 Coding standards, Autoloading and
Namespaces
Greg Beaver wrote:
> Travis Swicegood wrote:
>> Howdy all;
>>
>> On Apr 4, 2008, at 7:28 AM, Greg Beaver wrote:
>>
>>> Seriously, though, the logic it takes to think in terms of packages
>>> and the classes within a package do not apply here because java
>>> distributes packages as a language feature, and enforces class
>>> naming. This requires a level of WTF that is unnecessary for PEAR.
>>> Packages are an abstract entity that are used only when
>>> downloading. The class names are what will be used on a daily
>>> basis, and I strongly encourage us to think in those terms. Which
>>> are you more likely to find natural to use, PEAR2::HTTP::Request, or
>>> PEAR2::HTTP_Request::Request? If I saw the latter classname, I
>>> would scratch my head at the redundancy, and expect the class to be
>>> in either "PEAR2/HTTP_Request/Request.php" or
>>> "PEAR2/HTTP/Request/Request.php". Both of these are confusing at
>>> best, and obfuscate the actual location at worst.
>>
>> At the risk of encouraging a discussion that could easily devolve
>> into petty argument...
>>
>> As someone who has worked with PEAR style packages, it is not easy to
>> separate off a PEAR package inside a repository (via an svn:externals
>> or other means) as the code exists in two places:
>>
>> /path/to/HTTP/Request.php
>> /path/to/HTTP/Request/*
> This is only if you are using an *installed* version of the package.
> PEAR source repositories contain all code within a single directory.
>> The driving force behind a change such as Jeff is suggesting, as I
>> understand it, would be to completely contain the package within the
>> Request directory. I agree that it would be much more useful. I
>> also agree that there is a momentary "hmm" when you come across it
>> for the first time, but anything other than that will just as easily
>> confuse someone coming from another language. Python followed Java's
>> example, so this isn't just a Java views the world weirdly issue.
>>
>> You also have the issue of how to handle imports (or is it uses
>> now?). With the current recommendations, you possibly run into an
>> issue where you have to do multiple imports.
>>
>> <?php
>> import HTTP
>> import HTTP::Request
> both of these, by the way, are invalid syntax even after replacing
> "import" with "use". PHP's namespace implementation does not allow
> generic import (i.e. use HTTP::*;) as importing is done at
> compile-time, and it isn't possible to know all possible classnames,
> which would slow down the implementation ridiculously (see the
> internals@ archive for many extensive arguments over this
> implementation detail). One can, however, do an alias.
>
> use HTTP as a;
>
> Then both HTTP::Request and HTTP::Request::Request could be referred
> to as a::Request or a::Request::Request.
>> I might be totally off-base, however. If PHP doesn't enforce using
>> an import-styled statement to use namespaced code, then it's a
>> non-issue. At any rate, being able to completely enclose a package
>> in one directory would be extremely useful, in my opinion, from a
>> maintenance standpoint.
> PHP's namespaces are simply classnames with :: in their name. "use"
> is only a convenience per-file (note: *not* per-request) alias so one
> can type less in the file or "rename" a class to avoid naming
> conflicts. Note that __CLASS__ and get_class() never change the
> returned name. In addition, call_user_func() and friends *only* work
> with full name. use is a convenience for static T_STRING classnames
> within a file.
>
> As a side note, because PEAR2 does not contain any internal
> require_once/include_once statements to load code, you can actually do
> what you're talking about with the source repository simply by writing
> your own class loader code for the package, or pre-loading the code.
> This all assumes, of course, that the package has full directory
> structure in its svn repo so that loading of data files actually works.
>
> In other words, maintenance ends up a non-issue for those who are
> bundling PEAR2 code using svn:externals, and does not justify changing
> the behavior every PEAR user is accustomed to already. In addition,
> if you're bundling installed packages, Pyrus can be used to maintain
> this distribution directly without saving the registry files (i.e. it
> can be set to only use an xml registry or simply upgrade from the
> package.xml and assume things are in place there already). All of the
> archaic methods of maintaining bundled PEAR packages are obsoleted by
> Pyrus and remove the need for weird naming conventions by design :).
>
> However, I would not argue with a package that chose not to create a
> top-level class with the same name as the package if the naming is
> clever. For instance, instead of calling the package
> PEAR2::HTTP::Request, one could simply call it PEAR2::HTTP::Client and
> have PEAR2::HTTP::Client::Request and PEAR2::HTTP::Client::Response
> and PEAR2::HTTP::Client::Exception as the classnames. My only
> argument is with a ridiculous name like PEAR2::HTTP::Request::Request
> and the even more ridiculous PEAR2::HTTP::Request::Response (request
> response?!). So, with clever naming, one could actually get what
> you're asking for and satisfy what I am asking for. I'm not sure this
> kind of cleverness can be legislated as a requirement. It could
> certainly be a suggested practice and happen at the point where a
> package moves from alpha to beta status and a name is chosen.
>
> Greg
The current svn setup for externals does have some issues.
You can't overlap directories with svn:externals so there are still
issues. I only ran into problems with autoload which didn't matter
because i put it into a subdir and its just 1 file. But using PEAR2
from svn:externals is not going to work with the current setup, you're
going to need a custom autoloader.
-josh
--
PEAR Development Mailing List (http://pear.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php