FAQ
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

Search Discussions

  • Nikita Popov at Nov 30, 2011 at 6:51 pm
    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
    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

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Ralph Schindler at Nov 30, 2011 at 7:02 pm
    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


    On 11/30/11 12:51 PM, Nikita Popov wrote:
    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
    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

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Nikita Popov at Nov 30, 2011 at 7:13 pm
    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
    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?" :)
  • Devis at Nov 30, 2011 at 7:45 pm
    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


    On 30 November 2011 19:13, Nikita Popov wrote:

    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
    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?" :)
    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Ralph Schindler at Nov 30, 2011 at 7:51 pm
    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

    On 11/30/11 1:13 PM, Nikita Popov wrote:
    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
    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?" :)
  • Will Fitch at Nov 30, 2011 at 7:58 pm
    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.
    On Nov 30, 2011, at 2:51 PM, Ralph Schindler wrote:

    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

    On 11/30/11 1:13 PM, Nikita Popov wrote:
    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
    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?" :)

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Matthew Weier O'Phinney at Dec 1, 2011 at 4:20 am

    On 2011-11-30, Will Fitch wrote:
    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().

    On Nov 30, 2011, at 2:51 PM, Ralph Schindler wrote:

    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

    On 11/30/11 1:13 PM, Nikita Popov wrote:
    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
    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?" :)

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php

    --
    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
  • Ralph Schindler at Dec 1, 2011 at 5:35 pm
    I'll respond to all at once ;)

    On 11/30/11 1:58 PM, Will Fitch wrote:
    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.

    On 11/30/11 1:13 PM, Nikita Popov wrote:
    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
  • Anthony Ferrara at Dec 1, 2011 at 6:28 pm
    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
    wrote:
    I'll respond to all at once ;)


    On 11/30/11 1:58 PM, Will Fitch wrote:

    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?
    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...
    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?
    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
  • Matthew Weier O'Phinney at Dec 2, 2011 at 4:50 pm

    On 2011-12-01, Anthony Ferrara wrote:
    On Thu, Dec 1, 2011 at 12:34 PM, Ralph Schindler
    wrote:
    <snip>
    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'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
  • Rasmus Lerdorf at Dec 2, 2011 at 4:56 pm

    On 12/02/2011 08:50 AM, Matthew Weier O'Phinney wrote:
    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
  • Matthew Weier O'Phinney at Dec 2, 2011 at 5:07 pm

    On 2011-12-02, Rasmus Lerdorf wrote:
    On 12/02/2011 08:50 AM, Matthew Weier O'Phinney wrote:
    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.
    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
  • Anthony Ferrara at Dec 2, 2011 at 5:30 pm
    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
    wrote:
    On 2011-12-01, Anthony Ferrara wrote:
    On Thu, Dec 1, 2011 at 12:34 PM, Ralph Schindler
    wrote:
    <snip>
    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'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

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Александр Москалёв at Dec 2, 2011 at 6:06 pm
    ($new ? new insert() : new update())->from()->where()->exec();
    (same for array and callable expr)
    And yes, we can write it by many different ways...
    And yes it's not more readable than other ways....
    BUT. As I wrote before many times - if we can add this without bc and php
    slowdown, user can use it or not as he chose.

    With regards, Alexander Moskaliov
    Irker@irker.net


    ///// joke init call
    ($pingFunc =

    function ($pingFunc) {

    pingServer('this is crazy joke function');
    setLibeventTimer(10, $pingFunc);

    } ) ($pingFunc);

    >
  • Александр Москалёв at Dec 2, 2011 at 6:14 pm
    oh. sorry for "where" and "from" ... from hard work brain froze
    With regards, Alexander Moskaliov
    Irker@irker.net


    2011/12/2 Александр Москалёв ($new ? new insert() : new update())->from()->where()->exec();
  • Stas Malyshev at Dec 3, 2011 at 9:42 am
    Hi!
    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.
    Personally, I think the latter code is much better than the former. It
    makes clear what is created, where, and what the condition is doing, and
    doesn't require my internal parser to work too hard :)

    On the other hand, I don't see a real reason why -> shouldn't be able to
    be applied to any expression. Yes, sometimes it would be (or seem to me)
    bad style, so what? It's not like bad style is impossible now ;)
    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Dmitri Snytkine at Dec 2, 2011 at 4:55 pm
    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
    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 2011-12-01, Anthony Ferrara wrote:
    On Thu, Dec 1, 2011 at 12:34 PM, Ralph Schindler
    wrote:
    <snip>
    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'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

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Will Fitch at Dec 2, 2011 at 5:05 pm
    That variable is used for getting error messages.

    Sent from my iPad

    On Dec 2, 2011, at 11:56 AM, Dmitri Snytkine
    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
    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 2011-12-01, Anthony Ferrara wrote:
    On Thu, Dec 1, 2011 at 12:34 PM, Ralph Schindler
    wrote:
    <snip>
    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'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

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php


    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Matthew Weier O'Phinney at Dec 2, 2011 at 5:07 pm

    On 2011-12-02, "Dmitri Snytkine" wrote:
    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
  • Dmitri Snytkine at Nov 30, 2011 at 7:56 pm
    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
    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

    On 11/30/11 1:13 PM, Nikita Popov wrote:
    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
    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?" :)

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Will Fitch at Nov 30, 2011 at 8:07 pm
    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.

    On Nov 30, 2011, at 2:56 PM, Dmitri Snytkine wrote:

    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
    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

    On 11/30/11 1:13 PM, Nikita Popov wrote:
    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
    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?" :)

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php


    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Peter Lind at Nov 30, 2011 at 8:21 pm

    On 30 November 2011 19:59, Will Fitch wrote:
    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>
  • Devis at Nov 30, 2011 at 9:36 pm
    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.

    On 30 November 2011 19:59, Will Fitch wrote:

    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.

    On Nov 30, 2011, at 2:56 PM, Dmitri Snytkine wrote:

    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
    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

    On 11/30/11 1:13 PM, Nikita Popov wrote:
    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
    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?" :)

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php


    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Александр Москалёв at Dec 1, 2011 at 5:45 am
    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
  • Sebastian Bergmann at Nov 30, 2011 at 6:58 pm

    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/
  • Pierre Joye at Nov 30, 2011 at 7:06 pm
    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,
    On Nov 30, 2011 7:58 PM, "Sebastian Bergmann" wrote:

    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/

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Matthew Weier O'Phinney at Dec 1, 2011 at 4:20 am

    On 2011-11-30, Sebastian Bergmann wrote:
    Am 30.11.2011 19:09, schrieb Ralph Schindler:
    $value = ($obj = new Foo)->produceAValue();
    -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

Related Discussions

People

Translate

site design / logo © 2022 Grokbase