Attached is a patch implementing my proposal.
Basically, when inside a namespace, you must reference global classes
using ::globalName or by having a "use ::globalName" statement. This
allows classes inside namespaces to have the same name as internal ones
without the need of explicitly "use"-ing them (and prevents clashes with
new internal classes in the future). This only applies to classes,
functions/constants will still follow the current rules, since
__autoload does not apply to them (meaning you won't have to do things
like ::strlen just because you're inside a namespace).
Also, no errors are generated when using a class with the same name as
an internal class, BUT there is an error if you import/alias a class
with the same name as a global (non-internal) class. The reason for this
is that the user has control of which global classes they're including,
while the same might not be true of internal classes.
Some tests had to be modified to support the patch, and there might be a
need for additional tests to be included, but at least you can all try
out the patch and see how you feel about these new rules.
Please look at the patch, try it out, and let me know what you think
about it or if there's anything that can be improved. Thanks.
Regards,
Jessie Hernandez
Zend Certified Engineer (http://zend.com/zce.php?c=ZEND006359&r=222727282)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
I started a scratch project with this patch and working with it seems
intuitive so far.
My only question at the moment is the following, however I guess it
isn't specific to your NS patch then to Dmitry's:
My current practice to declare an interface and provide concrete
implementation was like this:
file: Foo/Bar/Interface.php
interface: Foo_Bar_Interface
Now this gets problematic:
file: Foo/Bar/Interface.php
namespace: Foo::Bar;
interface: Interface
The last one doesn't work, because the source actually looks like:
interface Interface {
which gives
syntax error, unexpected T_INTERFACE, expecting T_STRING
I tried something like
namespace Foo;
interface Bar::Interface;
but that gives another parser error about the ::
syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting '{'
Is there any chance for Rescue for this, instead of changing the naming
scheme?
thanks,
-
- Markus
Jessie Hernandez wrote:
Attached is a patch implementing my proposal.
Basically, when inside a namespace, you must reference global classes
using ::globalName or by having a "use ::globalName" statement. This
allows classes inside namespaces to have the same name as internal ones
without the need of explicitly "use"-ing them (and prevents clashes with
new internal classes in the future). This only applies to classes,
functions/constants will still follow the current rules, since
__autoload does not apply to them (meaning you won't have to do things
like ::strlen just because you're inside a namespace).Also, no errors are generated when using a class with the same name as
an internal class, BUT there is an error if you import/alias a class
with the same name as a global (non-internal) class. The reason for this
is that the user has control of which global classes they're including,
while the same might not be true of internal classes.Some tests had to be modified to support the patch, and there might be a
need for additional tests to be included, but at least you can all try
out the patch and see how you feel about these new rules.Please look at the patch, try it out, and let me know what you think
about it or if there's anything that can be improved. Thanks.Regards,
Jessie Hernandez
Zend Certified Engineer (http://zend.com/zce.php?c=ZEND006359&r=222727282)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFHeOGK1nS0RcInK9ARAmsFAKC98h2eUH+CusL/h8X4pT5A3EH3SwCg4Jxg
M+S0xyhNEbc/BzLxSY/UO0M=
=jR9j
-----END PGP SIGNATURE
Markus Fischer wrote:
Hi,
I started a scratch project with this patch and working with it seems
intuitive so far.My only question at the moment is the following, however I guess it
isn't specific to your NS patch then to Dmitry's:My current practice to declare an interface and provide concrete
implementation was like this:file: Foo/Bar/Interface.php
interface: Foo_Bar_InterfaceNow this gets problematic:
file: Foo/Bar/Interface.php
namespace: Foo::Bar;
interface: InterfaceThe last one doesn't work, because the source actually looks like:
interface Interface {
which gives
syntax error, unexpected T_INTERFACE, expecting
T_STRING
I tried something like
namespace Foo;
interface Bar::Interface;but that gives another parser error about the ::
syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting '{'
Is there any chance for Rescue for this, instead of changing the naming
scheme?
Hi Markus,
It is technically possible to fix this, on first glance it would involve
having the lexer return a T_STRING
for any non-whitespace following
T_INTERFACE
or between T_IMPLEMENTS
and '{'. It would also need to
return T_STRING
following T_INSTANCEOF.
However, this fix would only apply to interface naming, and would allow
bizarre stuff like "interface class" or even "interface foreach" which
is fine by me, but could be confusing to others (or so I've been told).
Implementation would only touch the zend_language_scanner.l file, but
would make it more complex. I've already gone down this road a few
times, and you would also end up with inconsistent naming, as the
solution could not work for classes because of the need to do
ClassName::. Implementing "ClassName::" requires a lookahead token
returning any whitespace and "::" back, which would slow things down a
bit and complicate the lexer considerably, but it can be done. I'd be
happy to do it but only if I have some reasonable assurance it would be
accepted, it's a fair amount of work to patch the lexer and make sure it
doesn't break crap.
Greg
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi Greg,
Greg Beaver wrote:
It is technically possible to fix this, on first glance it would involve
having the lexer return aT_STRING
for any non-whitespace following
T_INTERFACE
or betweenT_IMPLEMENTS
and '{'. It would also need to
returnT_STRING
following T_INSTANCEOF.
[...]
accepted, it's a fair amount of work to patch the lexer and make sure it
doesn't break crap.
I'm totally with your here. I can live very well with "Iface" instead.
Just wanted to make sure it's not an oversight on my side. Thanks for
the (gory) details ;)
-
- Markus
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
- Markus
iD8DBQFHeWz71nS0RcInK9ARAiSXAJ9QCQ8VZHJW7/ZOaDRfQ/y84hqZygCfXUai
YMHu2WIqLCKsKiqj9GwfKXY=
=twv1
-----END PGP SIGNATURE
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi, second time me ...
Markus Fischer wrote:
Hi Greg,
Greg Beaver wrote:
It is technically possible to fix this, on first glance it would involve
having the lexer return aT_STRING
for any non-whitespace following
T_INTERFACE
or betweenT_IMPLEMENTS
and '{'. It would also need to
returnT_STRING
following T_INSTANCEOF.
[...]
accepted, it's a fair amount of work to patch the lexer and make sure it
doesn't break crap.I'm totally with your here. I can live very well with "Iface" instead.
Just wanted to make sure it's not an oversight on my side. Thanks for
the (gory) details ;)
I think one has really get used to this, if you take for granted that
you named classes/interface this way in the past.
For example, in many projects I use the observer pattern and one of the
first observers implemented in almost any project is the Echo-Observer
to simply echo the messages. So this doesn't work anymore either.
a) You can't make a class Echo and
b) you can't create an interface named Echo ...
I tried using print but that doesn't work either. I'm either bumping
into T_ECHO
or T_PRINT. Stdout finally did it.
-
- Markus
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
- Markus
iD8DBQFHeYK/1nS0RcInK9ARApRiAKC63DhPeLY7i+QwApr/Iv4tyz4ToACgg995
uYHKxO/ToyeKxmqqXnK9RqU=
=JARy
-----END PGP SIGNATURE
Hi Markus,
Thanks for testing out the patch!
Has anyone else had a chance to test it out? I think this is a good
solution to the naming conflict issue that is currently present with
namespaces, but I'd love to hear other's opinions/experiences on this.
--
Jessie Hernandez
Zend Certified Engineer (http://zend.com/zce.php?c=ZEND006359&r=222727282)
Markus Fischer wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1Hi,
I started a scratch project with this patch and working with it seems
intuitive so far.My only question at the moment is the following, however I guess it
isn't specific to your NS patch then to Dmitry's:My current practice to declare an interface and provide concrete
implementation was like this:file: Foo/Bar/Interface.php
interface: Foo_Bar_InterfaceNow this gets problematic:
file: Foo/Bar/Interface.php
namespace: Foo::Bar;
interface: InterfaceThe last one doesn't work, because the source actually looks like:
interface Interface {
which gives
syntax error, unexpected T_INTERFACE, expecting
T_STRING
I tried something like
namespace Foo;
interface Bar::Interface;but that gives another parser error about the ::
syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting '{'
Is there any chance for Rescue for this, instead of changing the naming
scheme?thanks,
- Markus
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.orgiD8DBQFHeOGK1nS0RcInK9ARAmsFAKC98h2eUH+CusL/h8X4pT5A3EH3SwCg4Jxg
M+S0xyhNEbc/BzLxSY/UO0M=
=jR9j
-----END PGP SIGNATURE