On Thu, Apr 25, 2013 at 2:47 PM, Rasmus Schultz <ras...@mindplay.dk> wrote:
> Okay, > > No one seemed extremely interested in my notes about static > type-references<http://marc.info/?t=136327849600002&r=1&w=2>- 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 "<input type='text' name='{$name}' value='{$value}' />"; > } > > .... > } > > > 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