Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:90352 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 37109 invoked from network); 8 Jan 2016 14:56:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Jan 2016 14:56:09 -0000 Authentication-Results: pb1.pair.com smtp.mail=danack@basereality.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=danack@basereality.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain basereality.com from 209.85.160.179 cause and error) X-PHP-List-Original-Sender: danack@basereality.com X-Host-Fingerprint: 209.85.160.179 mail-yk0-f179.google.com Received: from [209.85.160.179] ([209.85.160.179:35391] helo=mail-yk0-f179.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 07/CB-55593-70ECF865 for ; Fri, 08 Jan 2016 09:56:07 -0500 Received: by mail-yk0-f179.google.com with SMTP id x67so364674801ykd.2 for ; Fri, 08 Jan 2016 06:56:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=basereality-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=qwArn7hoSUcC0P0eOr3wztJGeAdO+JqzdkqQK7fRS3Q=; b=WT4gHfK3doNJt4dLgBY+FrRkwM7iyjuS59h+U/xxcdQq3B9CvONZhcSZFsG3Ui2dBd Q6w4lelyq7IXwHspB7TBaXtNm2uPDcE1LGUR9HBz0D+RH8FDyrum3iTHwyYtG4Et01+W RKBHQ3uKtluwQysAch8Esn2ppf/tCcpPbaMTiX1qGrJ3+dC90nwKDMd7cNiPDaJi9MxE T2OM5a3H18UE6pI18DHBGavLw8+JTpnUWMM8KZnfJ8ASCyRrAH2Nk0oA/BS3AlMXoA+M Jcm1ZpZNIfsf/2TUvdIkdnPNZHFRr96rqaz5ejNTOA2IQpSRxbLacYZubAcLWly8+zoP Jdew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=qwArn7hoSUcC0P0eOr3wztJGeAdO+JqzdkqQK7fRS3Q=; b=aEzzNp+r1LJxyZNb3K4OA6UCDxG/0s4DBiRJrUm6om1WS/qy1o9xSvunRwuUaGxg9F cp5EgUmWCDIz/fxVVRBUp4ok4/PE9Pc8xBAihmxzIEKSXH60Uw8vFTzqtzTlMQo0eNa5 fuRhTyaiZ6oejgKCuwx6ggoAZfBprpd1L4ju1LHzNhQfKhMUGPf6FL7C6Syb5CpNepXG kH8zeU7UgyO9CeXeKl/rHcZWEapVQ/TqTgcQG3JpnClxjS3GM2gHxgDT9iiJTXY1Anmr ZAtZ+4SvU8M0sYrClemO5oWfSpU9nFKVtvWCzsUMVWI91qXBnonSEBn0YRy5CbGXoB/b xnyQ== X-Gm-Message-State: ALoCoQnFKqEvmCv8GnzMxGxeQDQni42rFXKQdnZX4EcXmKjEx+a0HMRccaTlM/GMaYqgXC4HkFAG3UkaULWmiPsuMr5dw1RqgQ== MIME-Version: 1.0 X-Received: by 10.129.81.136 with SMTP id f130mr50247118ywb.252.1452264964231; Fri, 08 Jan 2016 06:56:04 -0800 (PST) Received: by 10.37.83.131 with HTTP; Fri, 8 Jan 2016 06:56:04 -0800 (PST) X-Originating-IP: [2.99.233.57] In-Reply-To: References: Date: Fri, 8 Jan 2016 14:56:04 +0000 Message-ID: To: Dustin Wheeler Cc: PHP internals Content-Type: text/plain; charset=UTF-8 Subject: Re: [PHP-DEV] [RFC] Class Friendship From: danack@basereality.com (Dan Ackroyd) On 7 January 2016 at 20:25, Dustin Wheeler wrote: > Hello everyone, > > I have drafted an RFC that describes a proposal to add this feature to > the language. > > https://wiki.php.net/rfc/friend-classes Hi Dustin, I try to avoid sounding too negative when people come up with ideas that I might not agree with. However....I feel obliged to give honest feedback earlier rather than later; I can't see any circumstances under which I'd vote for this RFC. In my dim and distant youth I was C++ programmer.....and friends relationship between classes are not something I look back on fondly. In fact, they were a source of much sorrow. Although they solve a particular problem, they do so in a way that has too many downsides. From the examples: class Fibonacci { friend FibonacciTest; .... } class Person { friend HumanResourceReport; ... } The classes that are exposing their protected properties have to know about what classes are going to be using them. It means if I want to add a new test similar to the FibonacciTest, I also have to edit the Fibonacci class itself.....this is pretty terrible. That does not scale well - either in just the amount of code typed, or in how difficult it is to reason about the code. What ends up happening is that if a property needs to be exposed to friends once, it ends up being exposed to lots of friends. From the other example: class HumanResourceReport { public function getFullName() { // HumanResourceReport would not have access to protected // members of Person if not explicitly listed as a friend. return $this->person->firstName . ' ' . $this->person->lastName; } } Again, this has a massive downside. The 'domain logic' of how to construct a full name from a first name and last name belongs in the person class. By allowing the individual elements to be accessed, the code is violating the 'separation of concerns'. When middle names are added to the Person object, the HumanResourcesReport will continue to generate full names as it has always done....until someone notices a files a bug report. I agree that we shouldn't put RFCs in a head-to-head fight. But to me the package level protection of properties/methods sounds like a much bette potential solution to the problem that currently visibility is a binary option. But even if that idea wasn't floating around, I would not like to see friendship based visibility in PHP, as the solution it provides is worse than the problem it fixes, while at the same time adding more complexity to the engine. Apologies again for being so negative. cheers Dan p.s. For the FibonacciTest example, if it was required to write a test like that, below is how I would do it in PHP currently. It achieves the aim of testing the class, without having to make the Fibonacci be aware of the classes that are going to be testing it, or having to add any new features to PHP. class Fibonacci { protected $previous; protected $current; public function __construct() { $this->previous = 0; $this->current = 0; } public function next() { $current = $this->current; $next = $this->previous + $this->current; if ($next == 0) { $next = 1; } $this->previous = $this->current; $this->current = $next; return $current; } } class IntrospectableFibonacci extends Fibonacci { function getPrevious() { return $this->previous; } function getCurrent() { return $this->current; } } class FibonacciTest extends PHPUnit_Framework_TestCase { public function testAssignmentAlgoForStateIsCorrect() { $fibo = new IntrospectableFibonacci(); $this->assertEquals(0, $fibo->getPrevious()); $this->assertEquals(0, $fibo->getCurrent()); $n0 = $fibo->next(); $this->assertEquals(0, $n0); $this->assertEquals(0, $fibo->getPrevious()); $this->assertEquals(1, $fibo->getCurrent()); } }