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
<ra...@ralphschindler.com> 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

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

Reply via email to