# 5.4's New De-referencing plus assignment

- Thread: https://externals.io/message/56683
- Original archive: https://news-web.php.net/php.internals/56683
- Started by Ralph Schindler on 2011-11-30T18:09:01+00:00
- Messages: 28
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/56683.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #56683 — Ralph Schindler — 2011-11-30T18:09:01+00:00

URL: https://externals.io/message/56683#56683

Hey all (Filipe),

This was brought up in the thread "New dereferencing syntaxes in 5.4".

I too think this would be beneficial:

   $value = ($obj = new Foo)->produceAValue();

but the current parser (branch 5.4) doesn't have a rule for this.  I've 
attached a quick/working patch, but I don't fully understand the 
ramifications of such a patch.

Can someone explain the drawbacks of increasing the "%expect n" for me?

Would this many s/r require/benefit from a new expression grouping?

More to the point, can we have this small change for 5.4?

Thanks in advance.
-ralph

---

## #56684 — Nikita Popov — 2011-11-30T18:51:46+00:00

URL: https://externals.io/message/56683#56684 · In reply to: #56683

Hi Ralph!

This (in it's current form) doesn't look like a good idea to me. You
are only handling yet another edge case. ($foo = $bar = new A)->bar()
would again not work.

If we really want this kind of (expr)-> syntax, then it should really
accept *any* expr. But I am not quite sure whether this will work out
easily because in this case we can't be sue that expr is an object
(but maybe it'll be simple, I just don't know).

Nikita

On Wed, Nov 30, 2011 at 7:09 PM, Ralph Schindler
<ralph@ralphschindler.com> wrote:
> Hey all (Filipe),
>
> This was brought up in the thread "New dereferencing syntaxes in 5.4".
>
> I too think this would be beneficial:
>
>  $value = ($obj = new Foo)->produceAValue();
>
> but the current parser (branch 5.4) doesn't have a rule for this.  I've
> attached a quick/working patch, but I don't fully understand the
> ramifications of such a patch.
>
> Can someone explain the drawbacks of increasing the "%expect n" for me?
>
> Would this many s/r require/benefit from a new expression grouping?
>
> More to the point, can we have this small change for 5.4?
>
> Thanks in advance.
> -ralph

---

## #56686 — Sebastian Bergmann — 2011-11-30T18:57:58+00:00

URL: https://externals.io/message/56683#56686 · In reply to: #56683

Am 30.11.2011 19:09, schrieb Ralph Schindler:
> $value = ($obj = new Foo)->produceAValue();

 -1

-- 
Sebastian Bergmann                    Co-Founder and Principal Consultant
http://sebastian-bergmann.de/                           http://thePHP.cc/

---

## #56687 — Ralph Schindler — 2011-11-30T19:02:35+00:00

URL: https://externals.io/message/56683#56687 · In reply to: #56684

Nikita,

You're completely right about the expanded expressions, but I'm not sure 
its an edge-case per-se.

The problem with the current syntax is that the resultant of the 'new' 
operation is lost UNLESS your chained method returns $this - which IMO 
makes it about as 1/2 as useful as it really could be.

In the case of "new" though, the resultant is always an object, it seems 
like it should be permissible to change the parser to allow for variable 
assignment of the target object.

I think for people just trying out this new behavior (by seeing it in 
the release notes as (new Foo)->bar()), the next logical thing is to try 
this syntax:

   ($foo = new Foo)->bar()

   // OR in bison
   '(' variable '=' new_expr ')'

I did it, and I see other people doing it too. So I guess the question 
is... "how edge case is this edge case?" :)

Unfortunately, this new feature was not in any preview release, it was 
only in a release candidate.

-ralph




> Hi Ralph!
>
> This (in it's current form) doesn't look like a good idea to me. You
> are only handling yet another edge case. ($foo = $bar = new A)->bar()
> would again not work.
>
> If we really want this kind of (expr)->  syntax, then it should really
> accept *any* expr. But I am not quite sure whether this will work out
> easily because in this case we can't be sue that expr is an object
> (but maybe it'll be simple, I just don't know).
>
> Nikita
>
> On Wed, Nov 30, 2011 at 7:09 PM, Ralph Schindler
> <ralph@ralphschindler.com>  wrote:
> > […]

---

## #56688 — Pierre Joye — 2011-11-30T19:06:36+00:00

URL: https://externals.io/message/56683#56688 · In reply to: #56686

Hi Sebastian

As I agree with your position, there is no vote anymore on the list but
discussions.

About this addition, yes it should accept any expression. However I fail to
see the gain then but to get a perlish line.

Cheers,


> Am 30.11.2011 19:09, schrieb Ralph Schindler:
> > […]
>
>  -1
>
> --
> Sebastian Bergmann                    Co-Founder and Principal Consultant
> http://sebastian-bergmann.de/                           http://thePHP.cc/

---

## #56689 — Nikita Popov — 2011-11-30T19:13:21+00:00

URL: https://externals.io/message/56683#56689 · In reply to: #56687

To me the main problem here is that $bar = ($foo = new Foo)->bar()
simply doesn't make much sense. It is equivalent to:
$foo = new Foo;
$bar = $foo->bar();
Which is much cleaner and easier to understand.

The plain (new Foo)->bar() syntax *is* useful for cases like (new
ReflectionClass($class))->implementsInterface('Foo'), where you need
only one single bit of information from a class.

Nikita

On Wed, Nov 30, 2011 at 8:02 PM, Ralph Schindler
<ralph@ralphschindler.com> wrote:
> Nikita,
>
> You're completely right about the expanded expressions, but I'm not sure its
> an edge-case per-se.
>
> The problem with the current syntax is that the resultant of the 'new'
> operation is lost UNLESS your chained method returns $this - which IMO makes
> it about as 1/2 as useful as it really could be.
>
> In the case of "new" though, the resultant is always an object, it seems
> like it should be permissible to change the parser to allow for variable
> assignment of the target object.
>
> I think for people just trying out this new behavior (by seeing it in the
> release notes as (new Foo)->bar()), the next logical thing is to try this
> syntax:
>
>  ($foo = new Foo)->bar()
>
>  // OR in bison
>  '(' variable '=' new_expr ')'
>
> I did it, and I see other people doing it too. So I guess the question is...
> "how edge case is this edge case?" :)

---

## #56690 — devis@lucato.it — 2011-11-30T19:45:12+00:00

URL: https://externals.io/message/56683#56690 · In reply to: #56689

Hi,

personally I would find the proposed syntax very useful, similarly to the
following one that is already implemented:

if ($value = foo()) return $value

instead of

$value = foo();
if ($value) return $value;


Regards,
Devis





> To me the main problem here is that $bar = ($foo = new Foo)->bar()
> simply doesn't make much sense. It is equivalent to:
> $foo = new Foo;
> $bar = $foo->bar();
> Which is much cleaner and easier to understand.
>
> The plain (new Foo)->bar() syntax *is* useful for cases like (new
> ReflectionClass($class))->implementsInterface('Foo'), where you need
> only one single bit of information from a class.
>
> Nikita
>
> On Wed, Nov 30, 2011 at 8:02 PM, Ralph Schindler
> <ralph@ralphschindler.com> wrote:
> > […]
> its
> > […]
> makes
> > […]
> is...
> > […]

---

## #56691 — Ralph Schindler — 2011-11-30T19:51:28+00:00

URL: https://externals.io/message/56683#56691 · In reply to: #56689

Ironically, quite the opposite is something I find useful:

($foo = new MyComponent($bar))->configure($options);

In a single line, instantiate and configure (via an API call) an object. 
  The return of configure() is not important to me, but the brevity of 
that workflow, and the result of "new" is.

-ralph



> To me the main problem here is that $bar = ($foo = new Foo)->bar()
> simply doesn't make much sense. It is equivalent to:
> $foo = new Foo;
> $bar = $foo->bar();
> Which is much cleaner and easier to understand.
>
> The plain (new Foo)->bar() syntax *is* useful for cases like (new
> ReflectionClass($class))->implementsInterface('Foo'), where you need
> only one single bit of information from a class.
>
> Nikita
>
> On Wed, Nov 30, 2011 at 8:02 PM, Ralph Schindler
> <ralph@ralphschindler.com>  wrote:
> > […]

---

## #56692 — Dmitri Snytkine — 2011-11-30T19:56:36+00:00

URL: https://externals.io/message/56683#56692

Just for such case I use factory methods in a class, so I can do this:
MyComponent::factory($bar)->configure($option)

A clean one-liner.

The static factory method just returns the object of class, your standard
factory pattern.
 Plus you may gain extra flexibility from using factory instead of directly
calling new()

Dmitri Snytkine
Web Developer
Ultra Logistics, Inc.
Phone: (888) 220-4640 x 2097
Fax: (888) 795-6642
E-Mail: dsnytkine@ultralogistics.com
Web: www.ultralogistics.com

"A Top 100 Logistics I.T. Provider in 2011"


-----Original Message-----
From: Ralph Schindler [mailto:ralph@ralphschindler.com] 
Sent: Wednesday, November 30, 2011 2:51 PM
To: Nikita Popov
Cc: internals
Subject: Re: [PHP-DEV] 5.4's New De-referencing plus assignment

Ironically, quite the opposite is something I find useful:

($foo = new MyComponent($bar))->configure($options);

In a single line, instantiate and configure (via an API call) an object. 
  The return of configure() is not important to me, but the brevity of 
that workflow, and the result of "new" is.

-ralph



> To me the main problem here is that $bar = ($foo = new Foo)->bar()
> simply doesn't make much sense. It is equivalent to:
> $foo = new Foo;
> $bar = $foo->bar();
> Which is much cleaner and easier to understand.
>
> The plain (new Foo)->bar() syntax *is* useful for cases like (new
> ReflectionClass($class))->implementsInterface('Foo'), where you need
> only one single bit of information from a class.
>
> Nikita
>
> On Wed, Nov 30, 2011 at 8:02 PM, Ralph Schindler
> <ralph@ralphschindler.com>  wrote:
> > […]
its
> > […]
makes
> > […]
is...
> > […]

---

## #56693 — Will Fitch — 2011-11-30T19:58:17+00:00

URL: https://externals.io/message/56683#56693 · In reply to: #56691

If that's the case, then why not just add whatever $options is as a parameter to your constructor.  I'm not totally against this concept, but this use is moot.



> Ironically, quite the opposite is something I find useful:
> 
> ($foo = new MyComponent($bar))->configure($options);
> 
> In a single line, instantiate and configure (via an API call) an object.  The return of configure() is not important to me, but the brevity of that workflow, and the result of "new" is.
> 
> -ralph
> 
> 
> 
> > […]

---

## #56694 — Will Fitch — 2011-11-30T19:59:57+00:00

URL: https://externals.io/message/56683#56694 · In reply to: #56692

Again, back to my question of why not use:

MyComponent::factory($bar, $option);  

Depending on what ::factory does, it could then pass $option(s) to the constructor or method getting your instance needed.




> Just for such case I use factory methods in a class, so I can do this:
> MyComponent::factory($bar)->configure($option)
> 
> A clean one-liner.
> 
> The static factory method just returns the object of class, your standard
> factory pattern.
> Plus you may gain extra flexibility from using factory instead of directly
> calling new()
> 
> Dmitri Snytkine
> Web Developer
> Ultra Logistics, Inc.
> Phone: (888) 220-4640 x 2097
> Fax: (888) 795-6642
> E-Mail: dsnytkine@ultralogistics.com
> Web: www.ultralogistics.com
> 
> "A Top 100 Logistics I.T. Provider in 2011"
> 
> 
> -----Original Message-----
> From: Ralph Schindler [mailto:ralph@ralphschindler.com] 
> Sent: Wednesday, November 30, 2011 2:51 PM
> To: Nikita Popov
> Cc: internals
> Subject: Re: [PHP-DEV] 5.4's New De-referencing plus assignment
> 
> Ironically, quite the opposite is something I find useful:
> 
> ($foo = new MyComponent($bar))->configure($options);
> 
> In a single line, instantiate and configure (via an API call) an object. 
>  The return of configure() is not important to me, but the brevity of 
> that workflow, and the result of "new" is.
> 
> -ralph
> 
> 
> 
> > […]
> its
> > […]
> makes
> > […]
> is...
> > […]

---

## #56695 — Peter Lind — 2011-11-30T20:20:48+00:00

URL: https://externals.io/message/56683#56695 · In reply to: #56694

> Again, back to my question of why not use:
>
> MyComponent::factory($bar, $option);
>
> Depending on what ::factory does, it could then pass $option(s) to the constructor or method getting your instance needed.
>

It brings to mind a review of Dart by a perl-guy
(http://blogs.perl.org/users/rafael_garcia-suarez/2011/10/why-dart-is-not-the-language-of-the-future.html).
Specifically:

"I should note that the integration of popular design patterns at the
syntax level is disappointing: design patterns tend to emerge to work
around a language design's weaknesses. Embracing them is a bit like
admitting a design failure up front."

The proposed change has the same feel to it.

Regards
Peter

-- 
<hype>
WWW: plphp.dk / plind.dk
LinkedIn: plind
BeWelcome/Couchsurfing: Fake51
Twitter: kafe15
</hype

---

## #56696 — devis@lucato.it — 2011-11-30T21:35:52+00:00

URL: https://externals.io/message/56683#56696 · In reply to: #56694

You surely could add a factory to every class in your project, perhaps with
a trait, but you wouldn't have it for core and third party classes.




> Again, back to my question of why not use:
>
> MyComponent::factory($bar, $option);
>
> Depending on what ::factory does, it could then pass $option(s) to the
> constructor or method getting your instance needed.
>
>
> 
>
> > […]
> directly
> > […]
> sure
> > […]
> seems
> > […]
> variable
> > […]
> the
> > […]
> this
> > […]

---

## #56697 — Matthew Weier O'Phinney — 2011-12-01T04:20:48+00:00

URL: https://externals.io/message/56683#56697 · In reply to: #56693

> If that's the case, then why not just add whatever $options is as a
> parameter to your constructor.  I'm not totally against this concept,
> but this use is moot.

No, it's not.

Consider the case of using a variable for the class name -- i.e.,
dynamic classloading. It's typically bad OOP to have interfaces define
the constructor, so you'll identify a method used for configuration.
That ends up looking like this:

    $classname = discover_class_name();
    ($foo = new $classname())->configure($options);

This would work, as you expect the class to conform to an interface that
defines configure().


> 
>
> > […]
>


-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #56698 — Matthew Weier O'Phinney — 2011-12-01T04:20:51+00:00

URL: https://externals.io/message/56683#56698 · In reply to: #56686

> Am 30.11.2011 19:09, schrieb Ralph Schindler:
> > […]
>
>  -1

Just curious: why?

(Not that I'm 100% sure I agree with it myself, but curious why you
would vote against it...)

-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #56699 — irker@irker.net — 2011-12-01T05:44:39+00:00

URL: https://externals.io/message/56683#56699 · In reply to: #56684

2011/11/30 Nikita Popov <nikita.ppv@googlemail.com>

> If we really want this kind of (expr)-> syntax, then it should really
> accept *any* expr. But I am not quite sure whether this will work out
> easily because in this case we can't be sue that expr is an object
> (but maybe it'll be simple, I just don't know).
>

Same as now worked:  func()->something;  or    $a = 123;  $a->makeMagic();
If $a or result of func not objects its throw error.

To all:
I think we can adding (expr)->methodOrNot , (expr)[expr] , (expr)(params)
and it combinations: (expr)[expr](params)->method etc.
Is it good or bad user chooses himself.

Maybe will be something like JQueryPHP :D

I think the only thing that can in principle prevent us - slowdown PHP.



With regards, Alexander Moskaliov
Irker@irker.net

---

## #56704 — Ralph Schindler — 2011-12-01T17:34:58+00:00

URL: https://externals.io/message/56683#56704 · In reply to: #56693

I'll respond to all at once ;)



> If that's the case, then why not just add whatever $options is as a
> parameter to your constructor.  I'm not totally against this concept,
> but this use is moot.


I'm simply trying to find usefulness in the new feature of

     $x = (new Foo)->bar();

That's not useful to me.  Mainly b/c if you don't get a handle on the 
object, what was the point in the first place?

PHP already has a place for this in functions, static methods, AND if 
you're idea of OO programming is wrapping stateless functions in classes 
for "grouping" - in namespaces.



> The plain (new Foo)->bar() syntax*is*  useful for cases like (new
> ReflectionClass($class))->implementsInterface('Foo'), where you need
> only one single bit of information from a class.


Sure that is useful.. Although that looks more to me like an edge case 
than my idea of how expression-dereferencing would work.  Like I said 
above, if your object doesn't do much more than what a function would 
do, why not just file a feature request for Reflection to have a factory 
method on every class?

   ReflectionClass::factory($class)->implementsInterface('Foo');
   // or fix is_subclass_of($classname, $interfacename) ;)

Do we really want to encourage people to create objects for the purpose 
of calling a single method and tossing away the original object? You'd 
be better off using a function or a static method if that is what you 
want.  Furthermore, if you want to chain methods, that is also dangerous 
since PHP cannot do type enforcement on return values.  So,

   $instanceOfFooOrCoolResult = (new $foo)->do()->something()->cool();

needs to somehow guarantee that all methods of the type $foo will return 
$this.  (BTW, this is not an argument for my feature as much as its an 
argument as much as its one for "if we're going to do something, why not 
do it correctly in the first place".)  The correct path here, IMO, would 
be to simply carry the expression result (since we're using '(' expr ')' 
out and allow dereferencing on whatever comes out of it.




Here is a more contextual use case for my argument though:

   $rows = ($sql = new Sql)->from($table)->execute();
   // i can interact with both $sql and $rows at this point.


-ralph

---

## #56705 — Anthony Ferrara — 2011-12-01T18:28:29+00:00

URL: https://externals.io/message/56683#56705 · In reply to: #56704

To be honest, I'm not a fan of the proposal as written since it can't
accept arbitrary expressions inside the parenthesis.  Now, if you
could do any expression inside, then I would +1 for completeness.  But
since that's not really possible with the current parser (or language
specification), I'm not sure...

Read my comments inline

On Thu, Dec 1, 2011 at 12:34 PM, Ralph Schindler
<ralph@ralphschindler.com> wrote:
> I'll respond to all at once ;)
>
>
>
> 
> > […]
>
>
>
> I'm simply trying to find usefulness in the new feature of
>
>    $x = (new Foo)->bar();
>
> That's not useful to me.  Mainly b/c if you don't get a handle on the
> object, what was the point in the first place?

An example that was given before is to check to see if a class
(string) implements an interface:

if ((new ReflectionClass($class))->implementsInterface($interface)) {}

Where you don't *need* the object afterwards, all you need is to call
a single method on it...

> PHP already has a place for this in functions, static methods, AND if you're
> idea of OO programming is wrapping stateless functions in classes for
> "grouping" - in namespaces.

Well, perhaps.  However not all use-cases for this are stateless.  The
reflection example is one where you need to initialize a state prior
to calling that method.

Additionally, this lends itself perfectly to one particular OOP design
pattern: Value objects.  It would let you do:

$value = (new Value(1))->addTo(new Value(2)).

Since each value object is completely immutable, there's no reason to
persist it longer than you actually need it (unless you're using a
flyweight design pattern as well, and caching objects to reduce
instantiation overhead)...

A good use-case for this is interacting with dates.

$age = (new DateTime($birthday))->diff(new DateTime())->format('%R%a days');

Right now, the docs have it as separate lines, even though each object
is only used exactly once...

> > […]
>
> Sure that is useful.. Although that looks more to me like an edge case than
> my idea of how expression-dereferencing would work.  Like I said above, if
> your object doesn't do much more than what a function would do, why not just
> file a feature request for Reflection to have a factory method on every
> class?

I would argue that adding a factory method for this purpose is
actually *less* readable and worse.  The rationale is simple.  If you
don't know how the method works internally, can you tell me what is
happening here (just form method names):

ReflectionMethod::factory($class, $method)->setAccessable(true);
ReflectionMethod::factory($class, $method)->invoke($obj);

Wherease with the explicit inline new, it's absoltuely clear both are
happening on distinct objects:

(new ReflectionMethod($class, $method))->setAccessable(true); //
pointless, I know
(new ReflectionMethod($class, $method))->invoke($obj);

> Do we really want to encourage people to create objects for the purpose of
> calling a single method and tossing away the original object? You'd be
> better off using a function or a static method if that is what you want.
>  Furthermore, if you want to chain methods, that is also dangerous since PHP
> cannot do type enforcement on return values.  So,

Honestly, yes I would encourage that.  If you're *really* never going
to use the object again after that one call, why add an entry to store
it in a variable when you could just throw it away as soon as you're
done (saving a GC cycle)...

Now, you could argue (as I think you did) that most times people do
that they shouldn't be using a class, but a function (I consider
static methods all but identical to a function).  And that's a fair
point to make.  But it doesn't mean that there aren't valid use cases.
 Heck, PHP implemented goto...

>  $instanceOfFooOrCoolResult = (new $foo)->do()->something()->cool();
>
> needs to somehow guarantee that all methods of the type $foo will return
> $this.  (BTW, this is not an argument for my feature as much as its an
> argument as much as its one for "if we're going to do something, why not do
> it correctly in the first place".)  The correct path here, IMO, would be to
> simply carry the expression result (since we're using '(' expr ')' out and
> allow dereferencing on whatever comes out of it.
>

I would argue though that your syntax is completely possible today:

$foo = new Foo;
$foo->bar();

What's the reason to put that in a single line?  Aside from terseness,
is there any other benefit?  With the new dereference, one benefit is
that no variable is populated when none is needed.  But in your case,
you need both variables...

>
> Here is a more contextual use case for my argument though:
>
>  $rows = ($sql = new Sql)->from($table)->execute();
>  // i can interact with both $sql and $rows at this point.

Honestly, I find that very hard to read.  At a glance, I don't know
what's going on.  Even looking closer at it, it takes a few seconds to
comprehend what's happening.

>
> -ralph

---

## #56723 — Matthew Weier O'Phinney — 2011-12-02T16:50:06+00:00

URL: https://externals.io/message/56683#56723 · In reply to: #56705

> On Thu, Dec 1, 2011 at 12:34 PM, Ralph Schindler
><ralph@ralphschindler.com> wrote:
<snip>
> > […]
>
> I would argue though that your syntax is completely possible today:
>
> $foo = new Foo;
> $foo->bar();
>
> What's the reason to put that in a single line?  Aside from terseness,
> is there any other benefit?  With the new dereference, one benefit is
> that no variable is populated when none is needed.  But in your case,
> you need both variables...

Here's another example.

We have validator classes. Typically, you call isValid() to see if a
value validates. If it does, you have no more use for the validator. If
it _doesn't_, however, you'll want to get the error messages. I could
see the following as being a nice, succinct way to use validators:

    if (!(($validator = new SomeValidator())->isValid($value))) {
        // Validation failed, get messages...
        $view->assign('errors' => $validator->getMessages());
        return $view->render('error');
    }
    // validation passed, do something...

Yes, this could be written as follows:

    $validator = new SomeValidator();
    if (!$validator->isValid($value)) {
        // ...
    }
    // ...

However, I can see some folks not really wanting that variable
declaration if they won't be using it outside the conditional.

-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #56724 — Dmitri Snytkine — 2011-12-02T16:55:18+00:00

URL: https://externals.io/message/56683#56724

IT would probably be even more convenient to just say
if( (new `Validator()`)->isValid($value) ){

}

No reason to just temporaraly assign $validator.



Dmitri Snytkine
Web Developer
Ultra Logistics, Inc.
Phone: (888) 220-4640 x 2097
Fax: (888) 795-6642
E-Mail: dsnytkine@ultralogistics.com
Web: www.ultralogistics.com

"A Top 100 Logistics I.T. Provider in 2011"


-----Original Message-----
From: Matthew Weier O'Phinney [mailto:weierophinney@php.net] 
Sent: Friday, December 02, 2011 11:50 AM
To: internals@lists.php.net
Subject: Re: [PHP-DEV] 5.4's New De-referencing plus assignment


> On Thu, Dec 1, 2011 at 12:34 PM, Ralph Schindler
><ralph@ralphschindler.com> wrote:
<snip>
> > […]
do
> > […]
be to
> > […]
and
> > […]
>
> I would argue though that your syntax is completely possible today:
>
> $foo = new Foo;
> $foo->bar();
>
> What's the reason to put that in a single line?  Aside from terseness,
> is there any other benefit?  With the new dereference, one benefit is
> that no variable is populated when none is needed.  But in your case,
> you need both variables...

Here's another example.

We have validator classes. Typically, you call isValid() to see if a
value validates. If it does, you have no more use for the validator. If
it _doesn't_, however, you'll want to get the error messages. I could
see the following as being a nice, succinct way to use validators:

    if (!(($validator = new SomeValidator())->isValid($value))) {
        // Validation failed, get messages...
        $view->assign('errors' => $validator->getMessages());
        return $view->render('error');
    }
    // validation passed, do something...

Yes, this could be written as follows:

    $validator = new SomeValidator();
    if (!$validator->isValid($value)) {
        // ...
    }
    // ...

However, I can see some folks not really wanting that variable
declaration if they won't be using it outside the conditional.

-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #56725 — Rasmus Lerdorf — 2011-12-02T16:56:41+00:00

URL: https://externals.io/message/56683#56725 · In reply to: #56723

>     if (!(($validator = new SomeValidator())->isValid($value))) {
>         // Validation failed, get messages...
>         $view->assign('errors' => $validator->getMessages());
>         return $view->render('error');
>     }
>     // validation passed, do something...
> 
> Yes, this could be written as follows:
> 
>     $validator = new SomeValidator();
>     if (!$validator->isValid($value)) {
>         // ...
>     }
>     // ...
> 
> However, I can see some folks not really wanting that variable
> declaration if they won't be using it outside the conditional.

But $validator is still going to be defined regardless of the return
value of isValid() so it is going to be set outside the conditional.

-Rasmus

---

## #56726 — Will Fitch — 2011-12-02T17:05:07+00:00

URL: https://externals.io/message/56683#56726 · In reply to: #56724

That variable is used for getting error messages.

Sent from my iPad

On Dec 2, 2011, at 11:56 AM, Dmitri Snytkine
<dsnytkine@ultralogistics.com> wrote:

> IT would probably be even more convenient to just say
> if( (new `Validator()`)->isValid($value) ){
>
> }
>
> No reason to just temporaraly assign $validator.
>
>
>
> Dmitri Snytkine
> Web Developer
> Ultra Logistics, Inc.
> Phone: (888) 220-4640 x 2097
> Fax: (888) 795-6642
> E-Mail: dsnytkine@ultralogistics.com
> Web: www.ultralogistics.com
>
> "A Top 100 Logistics I.T. Provider in 2011"
>
>
> -----Original Message-----
> From: Matthew Weier O'Phinney [mailto:weierophinney@php.net]
> Sent: Friday, December 02, 2011 11:50 AM
> To: internals@lists.php.net
> Subject: Re: [PHP-DEV] 5.4's New De-referencing plus assignment
>
> 
> > […]
> <snip>
> > […]
> do
> > […]
> be to
> > […]
> and
> > […]
>
> Here's another example.
>
> We have validator classes. Typically, you call isValid() to see if a
> value validates. If it does, you have no more use for the validator. If
> it _doesn't_, however, you'll want to get the error messages. I could
> see the following as being a nice, succinct way to use validators:
>
>    if (!(($validator = new SomeValidator())->isValid($value))) {
>        // Validation failed, get messages...
>        $view->assign('errors' => $validator->getMessages());
>        return $view->render('error');
>    }
>    // validation passed, do something...
>
> Yes, this could be written as follows:
>
>    $validator = new SomeValidator();
>    if (!$validator->isValid($value)) {
>        // ...
>    }
>    // ...
>
> However, I can see some folks not really wanting that variable
> declaration if they won't be using it outside the conditional.
>
> --
> Matthew Weier O'Phinney
> Project Lead            | matthew@zend.com
> Zend Framework          | http://framework.zend.com/
> PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #56727 — Matthew Weier O'Phinney — 2011-12-02T17:07:42+00:00

URL: https://externals.io/message/56683#56727 · In reply to: #56725

> 
> > […]
>
> But $validator is still going to be defined regardless of the return
> value of isValid() so it is going to be set outside the conditional.

True. My point was that _semantically_ it looks like it's contained by
the conditional. _Technically_, it's not.

My main point is that this looks like a pattern folks will try
immediately, and wonder why it doesn't work. Whether or not it _should_
work, I'm ambivalent about. I'm more likely to declare and then invoke.

-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #56728 — Matthew Weier O'Phinney — 2011-12-02T17:07:46+00:00

URL: https://externals.io/message/56683#56728 · In reply to: #56724

> IT would probably be even more convenient to just say
> if( (new `Validator()`)->isValid($value) ){
>
> }
>
> No reason to just temporaraly assign $validator.

Except that you can't get the validation error messages if validation
fails.  That was the point of assigning -- error messages are stateful
properties of the validator.


-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #56729 — Anthony Ferrara — 2011-12-02T17:30:21+00:00

URL: https://externals.io/message/56683#56729 · In reply to: #56723

>    if (!(($validator = new SomeValidator())->isValid($value))) {

If you wanted to get into the whole "readable code" thoughts, that's a
fubar mess.

However, I can see your point and your usecase.  Then again, if we're
talking about OO design, that's bad in general since it creates a
tight coupling to the validator class and is not polymorphic.

I guess my thought is that I would be fine with it as long as it can
accept reasonably arbitrary expressions...

On Fri, Dec 2, 2011 at 11:50 AM, Matthew Weier O'Phinney
<weierophinney@php.net> wrote:
> 
> > […]
> <snip>
> > […]
>
> Here's another example.
>
> We have validator classes. Typically, you call isValid() to see if a
> value validates. If it does, you have no more use for the validator. If
> it _doesn't_, however, you'll want to get the error messages. I could
> see the following as being a nice, succinct way to use validators:
>
>    if (!(($validator = new SomeValidator())->isValid($value))) {
>        // Validation failed, get messages...
>        $view->assign('errors' => $validator->getMessages());
>        return $view->render('error');
>    }
>    // validation passed, do something...
>
> Yes, this could be written as follows:
>
>    $validator = new SomeValidator();
>    if (!$validator->isValid($value)) {
>        // ...
>    }
>    // ...
>
> However, I can see some folks not really wanting that variable
> declaration if they won't be using it outside the conditional.
>
> --
> Matthew Weier O'Phinney
> Project Lead            | matthew@zend.com
> Zend Framework          | http://framework.zend.com/
> PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

Next page: https://externals.io/message/56683.md?page=2
