Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:64505 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 52951 invoked from network); 3 Jan 2013 16:36:40 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 3 Jan 2013 16:36:40 -0000 Authentication-Results: pb1.pair.com smtp.mail=cpriest@zerocue.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=cpriest@zerocue.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zerocue.com designates 67.200.53.250 as permitted sender) X-PHP-List-Original-Sender: cpriest@zerocue.com X-Host-Fingerprint: 67.200.53.250 mail.zerocue.com Received: from [67.200.53.250] ([67.200.53.250:54077] helo=mail.zerocue.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 7F/DB-35624-793B5E05 for ; Thu, 03 Jan 2013 11:36:39 -0500 Received: from [172.16.10.217] (unknown [97.79.213.78]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by mail.zerocue.com (Postfix) with ESMTPSA id 655D3120340; Thu, 3 Jan 2013 16:36:36 +0000 (UTC) Message-ID: <50E5B39C.9020505@zerocue.com> Date: Thu, 03 Jan 2013 10:36:44 -0600 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: Steve Clay CC: internals@lists.php.net References: <50E41BB6.4030901@zerocue.com> <50E4A43E.6030302@zerocue.com> <50E4B232.5000505@mrclay.org> <50E4BDDE.8050509@zerocue.com> <50E4D0BB.7060701@mrclay.org> <50E4FA09.7030001@zerocue.com> <50E529B6.1050903@sugarcrm.com> <50E593DF.9090004@mrclay.org> In-Reply-To: <50E593DF.9090004@mrclay.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] [PHP-RFC] Property Accessors 1.2 for Final Review before Vote From: cpriest@zerocue.com (Clint Priest) On 1/3/2013 8:21 AM, Steve Clay wrote: > On 1/3/13 1:48 AM, Stas Malyshev wrote: >> class SuperDate { >> private $date { >> get; >> set(DateTime $x) { $this->date = $x; $this->timestamp = >> $x->getTimestamp(); >> } >> private $timestamp { >> get; >> set($t) { $t = (int)$t; $this->timestamp = $t; $this->date = new >> DateTime("@$t"); } >> } >> } >> >> What happens to it? Would it get into infinite loop or will just set the >> value twice? What would be the correct way to write such a code (note > > I think infinite recursion is a potential issue for lots of logging > setups ("let's log when someone calls the logger!") and situations > where you have multiple values to keep in sync. The accessor > implementation shouldn't try to solve these design problems. > __get()/__set() already implement infinite recursion guards, Accessors are just doing the same thing. > >> class UserContext { >> protected $user; >> public $logger; >> public $username { >> get() { $this->logger->log("Getting username"); return >> $user->name; } >> set($n) { $this->user = User::get_by_name($n); } >> } >> } >> >> class Logger { >> protected $ctx; >> public function __construct(UserContext $ctx) { >> $this->ctx = $ctx; >> $this->logfile = fopen("/tmp/log", "a+"); >> } >> public function log($message) { >> fwrite($this->logfile, "[$this->ctx->username] $message\n"); >> } >> } >> >> $u = new UserContext(); >> $u->logger = new Logger($u); >> $u->username = "johndoe"; >> echo $u->username; >> >> What would happen with this code? Will the log be able to log the actual >> user name, and if not, how you protect from such thing? $username is a >> part of public API of UserContext, so whoever is writing Logger has >> right to use it. On the other hand, whoever is using logger->log in >> UserContext has absolutely no way to know that Logger is using >> ctx->username internally, as these components can change completely >> independently and don't know anything about each other besides public >> APIs. >> What I am getting at here is that shadowing seems to create very tricky >> hidden state that can lead to very bad error situations when using >> public APIs without knowledge of internal implementation. > > Again, the problem is not shadowing (not even in use here) but really > general information hiding. You can create these problems anytime you > have hidden information and interdependent objects, and it's an API > design problem. > > Steve Clay -- -Clint