RE: [PEAR-DEV] Re: PEAR2 Coding standards, Autoloading and Namespaces

From: 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

« previous php.pear.dev (#49622) next »