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

Reply via email to