Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:67149 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 92741 invoked from network); 25 Apr 2013 13:22:23 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 25 Apr 2013 13:22:23 -0000 Authentication-Results: pb1.pair.com header.from=nikita.ppv@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=nikita.ppv@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.219.52 as permitted sender) X-PHP-List-Original-Sender: nikita.ppv@gmail.com X-Host-Fingerprint: 209.85.219.52 mail-oa0-f52.google.com Received: from [209.85.219.52] ([209.85.219.52:50196] helo=mail-oa0-f52.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id F1/F6-50361-E0E29715 for ; Thu, 25 Apr 2013 09:22:22 -0400 Received: by mail-oa0-f52.google.com with SMTP id n12so2731796oag.25 for ; Thu, 25 Apr 2013 06:22:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; bh=PPxV7j4iz5NiD6PTEpr/v+9QeiKMGyA1lm61vtRapRg=; b=fz84VzWwONWCHopk3itGhEPXLTjbO+lE5huNxIIaB0FFhQ+8QnLz4QDMD5fGrBxbYj MKQ9KLc6+iMGJiWvXyxdtnSFPbDB+OG+CrZtJHmThWrDzTPQnyMV7eyV5N+2OhvfQMa9 tWHMgHR7ScI/U59sumDc6/19hJY8RLf3g4vs7jaoDJfvIzXyShGpwQimVyxM/sOIQqqV j+AGxQbuJhdI2sQ4r91NMhJEmawjadEk02nJTIiL364gNltqy22cuYD6xxXyPN9GcKbH G9DIgq+l2Jl2nFb7qF1sghp/UiF58s2MUPDF7yR1Pi8t0E60B+ocArrqO+Cs+qVpBzs+ YWFg== MIME-Version: 1.0 X-Received: by 10.60.54.100 with SMTP id i4mr20176663oep.42.1366896139236; Thu, 25 Apr 2013 06:22:19 -0700 (PDT) Received: by 10.182.49.136 with HTTP; Thu, 25 Apr 2013 06:22:19 -0700 (PDT) In-Reply-To: References: Date: Thu, 25 Apr 2013 15:22:19 +0200 Message-ID: To: Rasmus Schultz Cc: PHP internals Content-Type: multipart/alternative; boundary=089e0112cf26d302bd04db2f4e45 Subject: Re: [PHP-DEV] property de-referencing From: nikita.ppv@gmail.com (Nikita Popov) --089e0112cf26d302bd04db2f4e45 Content-Type: text/plain; charset=ISO-8859-1 On Thu, Apr 25, 2013 at 2:47 PM, Rasmus Schultz wrote: > Okay, > > No one seemed extremely interested in my notes about static > type-references- I want > to bring up something closely related that could possibly be even > more useful, in particular for things like form-helpers, which remains as > one of the things that just can't be done in PHP as elegantly as it can in > some other languages. > > I'm not sure if de-referencing is the correct term? I'm talking about the > ability to use a property-reference indirectly - meaning, don't read the > property, don't write the property, but reference the property in a way > that permits you to read/write the property later on. > > In this example, I'm using ^ as the de-reference operator: > > class User > { > public $email; > } > > $user = new User(); > > $form = new FormHelper($user); > > echo $form->textInput(^$user->email); > > Note the ^ operator in the last line - we're not passing the value of > $user->email to FormHelper::textInput() but a reference to it... assuming a > new internal PropertyReference class, it's declaration might look like > this: > > class FormHelper > { > public function textInput(PropertyReference $prop) > { > $name = $prop->className . '[' . $prop->propertyName . ']'; > $value = $prop->getValue(); > > return ""; > } > > .... > } > > > The new PropertyReference class might have an interface like the following: > > class PropertyReference > { > public readonly object $object; // the object that was referenced > public readonly string $className; // the type of object that was > referenced > public readonly string $propertyName; // the name of the property that > was referenced > > public function getValue(); // read and return the property-value > public function setValue($value); // write the property-value > } > > > For a statement like this: > > $prop = ^$user->email; > > The ^ operator does something equivalent to: > > $prop = new PropertyReference(); > > $prop->object = $user; > $prop->className = get_class($user); > $prop->propertyName = 'email'; > > $prop->getValue = function () use ($user) { > return $user->email; > }; > > $prop->setValue = function ($value) use ($user) { > $user->email = $value; > }; > > > So essentially, you get all the information about the object and property, > and a way to read/write that property, with one character - something that > would enable hugely convenient APIs for things like form-helpers, > data-mappers and object/relational-mappers. > > When the object-type is known in IDEs (as it is in properly documented > code) this also addresses the same issue as static type-references, > allowing for static analysis and automated refactoring, but with a much > shorter and more convenient syntax - not needing to explicitly reference > the class-name, and with the added benefit of knowing the instance, both of > which are hugely important for form-helpers and mappers. > > Note that the getValue() and setValue() closures resolve properties the > usual way - that is, you can de-reference magic properties too, since no > attempt is made to read or write the property until getValue() or > setValue() is made. > > Most use-cases for referencing class and property-names are situations like > these, so this kind of kills two birds with one stone - a static way to > reference properties, but with the addition of providing the actual > object-context. And the shortest possible syntax. > > What do you think? > > - Rasmus Schultz > Maybe I didn't understand what you mean, but if you want property references, why not just use, well, property references? function foo(&$ref) { $ref = 'a'; } $a = new Obj; foo($a->prop); var_dump($a->prop) // string(1) "a" Also works for magic properties, assuming your correctly declared them using &__get. If you want more than just get/set, but also info on the property, why not pass a ReflectionProperty or a modification thereof which has a pre-bound object? Why do you need a new operator for this? Nikita --089e0112cf26d302bd04db2f4e45--