Larry Garfield wrote:
> On Saturday 20 September 2008 6:43:41 pm Richard Quadling wrote:
>
>>>> 5) a simply syntax change to namespaces, introducing a new concept:
>>>> namespace element.
>>>>
>>>> A namespace element is a class, function or constant defined within a
>>>> namespace declaration:
>>>>
>>>> <?php
>>>> namespace foo;
>>>> class bar {} // class element bar in namespace foo
>>>> function bar(){} // function element bar in namespace foo
>>>> const bar=1; // const element bar in namespace foo
>>>> ?>
>>>>
>>>> This is similar to class elements:
>>>>
>>>> <?php
>>>> class foo {
>>>> function bar(){} // method element bar in class foo
>>>> const bar=1; // constant element bar in class foo
>>>> public $bar=1; // variable element bar in class foo
>>>> }
>>>> ?>
>>>>
>>>> Currently, this code:
>>>>
>>>> <?php
>>>> namespace foo::bar;
>>>> class buh{}
>>>> ?>
>>>>
>>>> creates a class named "foo::bar::buh", essentially joining the namespace
>>>> "foo::bar" and its class element "buh" with the separator "::". This
>>>> turns out to be the root of the problem with the conflicts between class
>>>> elements and namespace elements. The last patch introduces a new
>>>> namespace element operator to delineate the boundary between namespace
>>>> name and element name. For the patch, I recycled T_OBJECT_OPERATOR (->).
>>>>
>>>> current way:
>>>> <?php
>>>> foo::bar->test(); // namespace foo::bar, call to function element test()
>>>> foo->bar::test(); // namespace foo, call to static method element test()
>>>> in class element bar
>>>> foo->myconst; // namespace foo constant myconst
>>>> foo::myconst; // class foo constant myconst
>>>> ?>
>>>>
>>>> The patch is at:
>>>>
>>>> http://pear.php.net/~greg/ns.element.patch.txt
>>>>
>>>> This is the most extensive change. The patch preserves :: as global
>>>> element accessor (::strlen() calls strlen internal function, for
>>>> instance). I'm happy to answer any other questions.
[snip]
> I agree that #5 seems like the best solution. The problem is caused by the
> double meaning of ::. All of the other solutions feel like bandaids.
>
> Of course, the problem then is finding a symbol that is not already used. I
> don't think reusing -> is any wiser than reusing ::. # would be great if it
Let's be clear. Here is a sample of code with the new syntax:
<?php
namespace name::still::has::double::colon;
const oscopy = 1;
class blow{
const byblow = 1;
static function hard(){}
}
namespace another::name;
use name::still::has::double::colon;
// fully qualified name:
// note that -> is only used once
// to specify the boundary between namespace name and namespace member.
$a = new name::still::has::double::colon->blow;
$a = new colon->blow;
// static method call
colon->blow::hard();
// or
name::still::has::double::colon->blow::hard();
// ns constant
echo colon->oscopy;
namespace blow;
function hard(){}
namespace a::third::name;
// demonstrate importing a class name
// which is different from importing a namespace name
use name::still::has::double::colon->blow;
// class static method
blow::hard();
// namespace function
::blow->hard();
// class constant
echo blow::byblow;
?>
Two important things to note:
- ambiguity between namespace name and class name is eliminated
<?php
namespace foo;
class test{
}
namespace foo::test;
class test{}
namespace third;
use foo::test;
$a = new test; // this is namespace foo, class test
$a = new test::test; // this is namespace foo::test, class test
?>
- this separator is self-documenting. One does not need to grep source
code to determine whether blah->thing is a namespaced function or a
static method of class blah. The same is true of use statements. It is
crystal clear whether we are importing a namespace or a class name.
This will make debugging someone else's code a lot easier than it
otherwise would be.
Jochem has informed me he is taking care of the wiki RFC for this stuff.
I am allergic to wikis, unfortunately.
Thanks,
Greg
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php