First, thanks everyone for the hard work on the PHP 5.5 alpha. I just ran
the tests and submitted some results, but from the little bit I've used it
so far, things are looking really nice.
Second, and to the main point of this email, I would like to be able to
call closures that are stored as object properties directly without having
to make use of a temporary variable.
For example:
<?php
$o = new stdClass();
$o->func = function(){
return 'Yes!';
};
$o->func();
?>
The above code elicits the error:
Call to undefined method stdClass:test() in...
I realize I could create a class that implements __call() to intercept and
redirect the call to the closure, but this adds much overhead for a simple
approach and also precludes the use of stdClass (I like the option of being
able to cast to an array, and then back with very little overhead.)
It seems as though the parser could be updated to accommodate this
intention, but I understand this could pose a backwards compatibility issue
(current users could have closures stored as object properties and be
expecting the magic method __call() to be invoked instead of the closure
itself.)
Has anyone else wanted this functionality? Has anyone else thought of ideas
of addressing this (or come to the conclusion it really isn't safely
addressable without causing disproportionate amounts of grief?)
Thank you,
Adam
Hi!
Has anyone else wanted this functionality? Has anyone else thought of ideas
of addressing this (or come to the conclusion it really isn't safely
addressable without causing disproportionate amounts of grief?)
Yes, there were people that wanted this functionality, but since having
the same thing ($foo->bar()) mean two different things (call method
named "foo" vs. "fetch property named foo and then call it if it's
callable") is not a good idea this wasn't done.
In some languages, the options above are the same - i.e. methods and
properties are actually the same thing - but in PHP is is not so, and
can be made so without some BC-breaking changes.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Sat, Dec 8, 2012 at 5:05 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
Has anyone else wanted this functionality? Has anyone else thought of
ideas
of addressing this (or come to the conclusion it really isn't safely
addressable without causing disproportionate amounts of grief?)Yes, there were people that wanted this functionality, but since having
the same thing ($foo->bar()) mean two different things (call method
named "foo" vs. "fetch property named foo and then call it if it's
callable") is not a good idea this wasn't done.
In some languages, the options above are the same - i.e. methods and
properties are actually the same thing - but in PHP is is not so, and
can be made so without some BC-breaking changes.
As it stands now, calling a method can mean two different things: calling
the method directly, or handling the method invocation within __call().
Checking for a method first, a closure instance next, and then falling
through to __call() seems like it would have been a reasonable approach.
That said, as you mention BC-breaking is now an issue.
Thanks,
Adam
Hi!
As it stands now, calling a method can mean two different things:
calling the method directly, or handling the method invocation within
__call(). Checking for a method first, a closure instance next, and then
falling through to __call() seems like it would have been a reasonable
approach.
This is the same thing. However, what you mean by "closure instance" is
actually a property access, which is not the same thing as method call.
Think about what happens if you have both __call and __get (or object
implementing both handlers).
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Adam,
call closures that are stored as object properties directly without having
to make use of a temporary variable.
...
$o = new stdClass();
$o->func = function(){
return 'Yes!';
};
$o->func();
The following expression avoids PHP's dilemma of distinguishing prop/method, but fails
because you can't execute an expression:
($o->func)();
Similarly if $a is a Closure, $a() works but ($a)() fails.
If these could be made to work, would it break BC? And should they be made to work?
Steve Clay
call closures that are stored as object properties directly without having
to make use of a temporary variable....
$o = new stdClass();
$o->func = function(){
return 'Yes!';
};
$o->func();The following expression avoids PHP's dilemma of distinguishing
prop/method, but fails because you can't execute an expression:($o->func)();
I actually tried that very technique before remembering the limitation :)
Interesting idea.
Adam
I'm currently working around this problem by assuming that a Closure
implements __invoke
:
$this->someProp->__invoke();
Not really nice, but this works in both 5.3 and 5.4.
If the suggestion above could cover also callable
and not just Closure
then it would be quite interesting to have that.
Marco Pivetta