Hi Stas, I'll comment your PS, since I'm the author of the PR.
On Sun, Aug 14, 2016 at 6:11 PM, Stanislav Malyshev <smalys...@gmail.com> wrote: > Hi! > > > - PHP 7 has private classes through anonymous/inner classes. > > It's not exactly the same, and I suspect the same is true for Ruby. It's > true that anonymous classes can not be instantiated by other code. But > that is not what we were discussing here. This particular effect is > somewhat similar, the purpose of the feature is different. > > Of course, some languages have them. Others don't. The point is saying > "it's not OO unless it implements $favorite_feature_of_mine" is not very > meaningful, at least at this point. > > > abstract class Data { > > protected $id; > > protected $name; > > protected function __construct() {} > > protected function __clone() {} > > } > > > > final class Entity extends Data { > > public function getId() { > > return $this->id; > > } > > public function getName() { > > return $this->name; > > } > > } > > > > final class Builder extends Data { > > private $entity; > > public function build() { > > return clone $this->entity; > > } > > public function setId($id) { > > $this->entity->id = $id; > > } > > public function setName($name) { > > $this->entity->name = $name; > > } > > } > > > > ?> > > I'm afraid I don't understand this code. Why both entity and builder are > Data? It looks like combining factory object with actual data object. > This is why __construct/__clone exists - so the object could take care > of the details and the factory didn't have to know about it in details. > > I presume you want to say that Data object should be private class. I > think - at least from my partial understanding of the code - that it > shouldn't exist at all, especially given you don't want to expose it to > the user. > > > Another example that is not solvable with friend classes would be the > > strategy pattern of hidden strategies as we find it for example in > > Symfony's process component. > > > > https://github.com/symfony/process/tree/master/Pipes > > > > The pipes are purely internal to work around differences between PHP on > > Unix and Windows. They are not meant for consumption through users, they > > Sure, they aren't useful for most, but I see no problem in somebody > using them if necessary. Say, you may want to use Unix pipe on Windows > because you are in unix emulation environment, or you have a weird OS > that is not Unix and now Windows and want to reuse parts of these > classes to deal with it. There could be many cases we can't foresee when > we design it for our ideal use case. > > > At trivago we have hundreds of applications, packages, libraries and > > developers who work in a very fast moving environment. Reading > > documentation is not something most people spend time with. > > I find so many things not right with this statement I don't know where > to start... So I just leave it with a note that having no time to do > things right usually means doing things wrong many times, and *then* > being forced to spend time to do things right because the whole jenga > tower crashes on your head. That is not a criticism of you or your > employer, but rather the result of experience learned the hard way. You > can get away with it from time to time, true, but it's just luck. > > > It's also easy to work around property and method access modifiers. > > However, that is no argument to remove them now. > > Not very easy. The only way to work around private is to use heavy > machinery like reflection. This is why, btw, private should be used very > carefully - when if you're *sure* nobody will need or is advised to > access that thing directly. Overuse of private, especially for methods, > leads to classes that are not extendable without horrendous amounts of > copypaste. > > Also, there's a difference IMO between classes and class' properties. > Class details may be - indeed, need to be - hidden because this is what > the class is, one of it's reasons to exist - a tool to reduce complexity > by hiding irrelevant information and exposing only relevant information > as class' public API. You hide things not because you're afraid evil > users would abuse them - but as a service to the user to not overload > their mental models with irrelevant details and allow to deal with the > class by only considering the important things. > > However, if we're talking about collection of classes sharing a > namespace, there's no such thing as "namespace's API", at least not in > common use. There's a concept of library's API, but it's not derived > from classes alone - it's usually what documentation does, while class > API can be yet figured from it's methods, library API is usually > impossible to figure out just looking at the classes - you need the next > level, documentation. > So in my opinion, if you hide some classes from instantiation from > outside namespace (which by itself carries a lot of assumptions, such as > every class that will ever need it will share the same namespace), > reduction in complexity is almost none, since nobody uses "list of > available classes in package/namespace" as a way to work with the > package anyway. > > P.S. BTW I still don't know why you need to refactor namespaces to have > namespace-private classes anyway. Isn't it just a matter of the match > between current scope and target class name? > I wanted to come up with a solution before writing an RFC. The problem that is not yet solved in that PR is the check of instantiation without being scoped. Example: <?php namespace Foo; $bar = new ThisIsAPrivateClass(); This should work... but this code: <?php $bar = new \Foo\ThisIsAPrivateClass(); Should break. The problem is that opline have no scope context, so at both of them the scope = NULL. We could easily add a scope every time a namespace is declared and remove when ended, but as Nikita highlighted (here: https://github.com/php/php-src/pull/947#issuecomment-224934615 ), this is not the correct solution. I hit a dead end on that PR. Changing opline (or oparray) to support a new struct _zend_namespace is over my internals knowledge. I'd love if someone could take over and complete it. I can write the RFC while someone else finalize the code. > > -- > Stas Malyshev > smalys...@gmail.com > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > -- Guilherme Blanco Lead Architect at E-Block