Daniel Convissor wrote:
> On Mon, Sep 22, 2008 at 08:07:10PM +0400, Dmitry Stogov wrote:
> 
>> Yes. Changing :: into any other separator solves the functions/static
>> methods and constants ambiguity, but it also breaks intuitive syntax.
> 
> Which is more important?  Considering there have been threads upon 
> threads filled with myriad messages, it seems resolving the ambiguity is 
> significanly more important than an intuitive syntax.
> 
> Please, let's pick a different operator for namespaces.  This will 
> eliminate the scoping/resolution issues for both the engine and the 
> humans trying to interpret PHP code.
> 
> [/me searching for the vote tally on which operator people preferred]
> [/me alas, can't find it at the moment]
> 
> I recall there being a vote on this.  I'm sure some of you have a saved 
> copy and/or link to it.  Can't we pick the operator on that list that got 
> the second highest vote count?

Hi,

The second highest vote was :::, but there was strong objection to this
as well from some.  The problem, I still believe, is that we are focused
on having the same:::stupid:::operator:::between:::everything.

The truth is that in source files, there is a clear boundary between
namespace definition as in:

<?php
namespace foo::bar;
?>

and the things in the namespace, as in:

<?php
class bar {}
?>

Without context, the above definition of class bar could define
literally any class name:

bar
something::bar
another::long::name::bar

depending on the namespace declaration at the top of the file.  This
means that it is an arbitrary choice in the current implementation to
use "::" to join the two things (namespace name and class name).

In truth, it will be a lot easier to debug code if this is a different
separator, as the boundary between namespace and element will be crystal
clear.  For instance:

(current implementation)
my::framework::someFunction()->aProperty->someMethod();

is my::framework a class or a namespace?

Let's use an arbitrary separator .. to mark the boundary between
namespace and class/function

(new implementation)
my::framework..someFunction()->aProperty->someMethod();

OK, now we know that my::namespace is a namespace, and someFunction is a
function.

my..framework::someFunction()->aProperty->someMethod();

The above is also clear: my is a namespace, framework is a class name,
and someFunction is a static method.

This has the advantage that existing code based on PHP 5.3 alpha 1 and 2
won't require very much modification, it is easy to read, and easy to
understand what a line of code does without needing any context information.

I took my old patch and moved from the -> separator to the .. separator
in about 45 minutes of work, so changing the separator will not be
difficult.  Here's the new patch against PHP_5_3:

http://pear.php.net/~greg/ns.element.2.patch.txt

Unlike the first patch, it introduces a new token, T_NS_MEMBER, instead
of recycling T_OBJECT_OPERATOR.

This is also easy to document.  Here's how I would do it:

Although namespaces can span multiple files, they are similar to static
classes.

Namespaces are used in PHP to link related classes, functions, and
constants much as static classes can be used to link related variables,
methods, and constants.

The classes, functions, and constants defined in a namespace are called
"namespace elements" just as the variables, methods and constants
defined in a static class are "static class members"

A static class example:

<?php
class myclass
{
    const one = 1;
    static public $a;
    static function show()
    {
        echo __METHOD__,"\n";
    }
}

myclass::show();
$variable = myclass::$a;
echo myclass::one;
?>

Static class members can be accessed using the :: operator, as in
"myclass::show()".

Here is a namespace example:

file1.php:
<?php
namespace mynamespace;
const one = 1;
function show()
{
    echo __FUNCTION__,"\n";
}
class myclass
{
    function show()
    {
        echo __METHOD__,"\n";
    }
}
class mystaticclass
{
    static function show()
    {
        echo __METHOD__,"\n";
    }
}
?>

main.php:
<?php
include 'file1.php';

mynamespace..show();
echo mynamespace..one;
$a = new mynamespace..myclass;
$a->show();
?>

Namespace elements can be accessed using the .. operator, as in
"mynamespace..show()".

Another example showing how to access static class members within a
namespace:

<?php
include 'file1.php';
mynamespace..mystaticclass::show();
?>

Namespaces can be nested using the "::" operator as in:

file2.php:
<?php
namespace my::nested::ns;
class mystaticclass
{
    static function show()
    {
        echo __METHOD__,"\n";
    }
}
?>

The "use" statement allows importing both namespace elements and
namespace names into the current scope:

<?php
include 'file1.php';
incldue 'file2.php';

use mynamespace..mystaticclass;
use my::nested::ns;
use my::nested;
use my::nested::ns..mystaticclass as myclass;

mystaticclass::show(); // mynamespace..mystaticclass::show()
myclass::show(); // my::nested::ns..mystaticclass::show()
ns..mystaticclass::show(); // my::nested::ns..mystaticclass::show()
nested::ns..mystaticclass::show(); // my::nested::ns..mystaticclass::show()
?>

Nesting of namespaces occurs like so:

<?php
namespace my::nested;
include 'file2.php';

ns..mystaticclass::show(); // my::nested::ns..mystaticclass

class someclass extends ns..mystaticclass {}
?>

The statement "ns..mystaticclass::show()" is automatically expanded into
"my::nested::ns..mystaticclass::show()".

Thanks,
Greg

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to