I'm sure this question has been discussed before, so if anyone can point to me to links or
briefly recap I'd appreciate it.
Why can't we make $someCallable() always work? E.g. http://3v4l.org/FLpAq
I understand the problem of $obj->foo() where ->foo is a callable property. The workaround
could be:
($obj->foo)();
call_user_func()
just seems so ugly now that we have nicer syntax in so many other areas.
Steve Clay
2013/3/15 Steve Clay steve@mrclay.org
I'm sure this question has been discussed before, so if anyone can point
to me to links or briefly recap I'd appreciate it.Why can't we make $someCallable() always work? E.g. http://3v4l.org/FLpAq
I understand the problem of $obj->foo() where ->foo is a callable
property. The workaround could be:($obj->foo)();
call_user_func()
just seems so ugly now that we have nicer syntax in so
many other areas.
You don't need to use it, if you don't like it.
Steve Clay
--
My subject was misleading. I didn't mean to suggest call_user_func()
be removed, just be
made unnecessary by direct call syntax.
This should make the inconsistency clearer: http://3v4l.org/L8Yvq
You don't need to use it, if you don't like it.
I do need to use in case my $callable is an object callback.
Steve Clay
My subject was misleading. I didn't mean to suggest
call_user_func()
be
removed, just be made unnecessary by direct call syntax.This should make the inconsistency clearer: http://3v4l.org/L8Yvq
You don't need to use it, if you don't like it.
I do need to use in case my $callable is an object callback.
I think you missed something. We already support that in 5.4. You can do
$foo = ['class', 'method']; $foo() and $foo = [$obj, 'method']; $foo(). I
don't know why 'class::method' isn't supported, but I guess it's just a
legacy syntax that was superseded by the array notation and as such not
supported.
Nikita
I don't know why 'class::method' isn't supported, but I guess it's just a
legacy syntax that was superseded by the array notation
'class::method' was added significantly later, so I think it's fair for devs to assume
that it would be supported like other callables...
Anyway, file under Would Be Nice Someday.
Steve Clay
2013/3/15 Steve Clay steve@mrclay.org
My subject was misleading. I didn't mean to suggest
call_user_func()
be
removed, just be made unnecessary by direct call syntax.This should make the inconsistency clearer: http://3v4l.org/L8Yvq
You don't need to use it, if you don't like it.
I do need to use in case my $callable is an object callback.
Well, I would agree, if it is wouldn't be already possible :) You simply
defined your static method "wrong"
I am unsure, if it useful to support "Foo::bar" too, because it doesn't
give any further benefit compared to ["Foo","bar"]
Steve Clay
--
I'm sure this question has been discussed before, so if anyone can
point to me to links or briefly recap I'd appreciate it.Why can't we make $someCallable() always work? E.g. http://3v4l.org/FLpAq
I understand the problem of $obj->foo() where ->foo is a callable
property. The workaround could be:($obj->foo)();
call_user_func()
just seems so ugly now that we have nicer syntax in
so many other areas.Steve Clay
No.
What if I want to call functions with a variable number of arguments?
For instance, the common piece of a hook system implementation, where
the arguments of the functions called vary depending on the hook.
Am 15.3.2013 um 15:50 schrieb Ángel González keisial@gmail.com:
I'm sure this question has been discussed before, so if anyone can
point to me to links or briefly recap I'd appreciate it.Why can't we make $someCallable() always work? E.g. http://3v4l.org/FLpAq
I understand the problem of $obj->foo() where ->foo is a callable
property. The workaround could be:($obj->foo)();
call_user_func()
just seems so ugly now that we have nicer syntax in
so many other areas.Steve Clay
No.What if I want to call functions with a variable number of arguments?
For instance, the common piece of a hook system implementation, where
the arguments of the functions called vary depending on the hook.
call_user_func is not call_user_func_array
call_user_func($func) is the same as $func(). In any way.
Bob Weinand
Bob,
call_user_func is not call_user_func_array
call_user_func($func) is the same as $func(). In any way.
Not in any way. call_user_func accepts any expression for the function to
call. $func()
only accepts callables.
Example:
call_user_func(getCallback());
getCallback()(); // <-- syntax error.
You could solve it with variable foo:
${''.!$=getCallback()}();
But I'd stick to call_user_func()
...
Am 15.3.2013 um 16:59 schrieb Anthony Ferrara ircmaxell@gmail.com:
Bob,
call_user_func is not call_user_func_array
call_user_func($func) is the same as $func(). In any way.
Not in any way. call_user_func accepts any expression for the function to call.
$func()
only accepts callables.Example:
call_user_func(getCallback());
getCallback()(); // <-- syntax error.You could solve it with variable foo:
${''.!$=getCallback()}();
But I'd stick to
call_user_func()
...
Hey,
why not enable then this "getCallback()();"?
but yes, call_user_func should remain there alone in the combination with call_user_func_array.
Bob Weinand
Hi!
why not enable then this "getCallback()();"?
There's an RFC for that: https://wiki.php.net/rfc/fcallfcall
but it has some edge cases which I didn't have time to figure out yet.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
2013/3/15 Stas Malyshev smalyshev@sugarcrm.com
Hi!
why not enable then this "getCallback()();"?
There's an RFC for that: https://wiki.php.net/rfc/fcallfcall
but it has some edge cases which I didn't have time to figure out yet.
In the long run I think it would be great :) Earlier I also realized, that
doesn't work either.
Regards,
Sebastian
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227--
Am 15.3.2013 um 18:57 schrieb Stas Malyshev smalyshev@sugarcrm.com:
Hi!
why not enable then this "getCallback()();"?
There's an RFC for that: https://wiki.php.net/rfc/fcallfcall
but it has some edge cases which I didn't have time to figure out yet.
Is it possible to add this alternative rule for function_call in zend_language_parser.y:
parenthesis_expr { zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$3, 0, $2.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
So that you can write ($this->closure)(); (for invoking Closures instead of first assigning it, then calling the Closure or writing $this->closure->invoke())
Or write (getCallback())(). There should be then no edge cases as it is properly delimited by the parenthesis.
I've shortly tested this with no new bugs.
Short example:
function a () { return "b"; }
function b () { return "c"; }
print (a())()."\n"; // prints c
function a () { return function () { print "a\n"; }; }
(a())(); // prints a
I also think this with parenthesis around it it is clearer what's being done: the first part evaluated and then the second executed. (If I would have to choose I would prefer the parenthesis...)
Bob Weinand
p.s.: I'm wondering why, with this little patch, (function () { print "a"; })(); is throwing a fatal error telling me a function name must be a string while ($temp = function () { print "a"; })(); is working perfectly?! (I think this is the condition which fails: http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_vm_def.h#2676, but I'm not 100% sure and now I'm too tired to investigate further into it...)
${''.!$=getCallback()}();
Well now, that's an... interesting abuse of resolution order and type juggling.
${''.!$=getCallback()}();
Well now, that's an... interesting abuse of resolution order and type
juggling.
Really crazy, yeah
Also, AFAIR, call_user_func()
doesn't work with functions using references
in args.
Julien.Pauli
Also, AFAIR,
call_user_func()
doesn't work with functions using
references in args. Julien.Pauli
AFAIK it does.
Do you have an example where it doesn't?
Angel,
Also, AFAIR,
call_user_func()
doesn't work with functions using
references in args. Julien.Pauli
AFAIK it does.
Do you have an example where it doesn't?
It definitely does not:
And if you try call-time-pass-by-reference, it gets worse:
Anthony
On Mon, Mar 18, 2013 at 3:33 PM, Anthony Ferrara ircmaxell@gmail.comwrote:
Angel,
Also, AFAIR,
call_user_func()
doesn't work with functions using
references in args. Julien.Pauli
AFAIK it does.
Do you have an example where it doesn't?It definitely does not:
And if you try call-time-pass-by-reference, it gets worse:
Yeah, that's what I remembered. call_user_func()
is not exactly the same as
calling the function, when references come to scene, it just wont work.
Same with _array() implementation.
Julien.Pauli
On Mon, Mar 18, 2013 at 3:33 PM, Anthony Ferrara
ircmaxell@gmail.comwrote:Angel,
Also, AFAIR,
call_user_func()
doesn't work with functions using
references in args. Julien.Pauli
AFAIK it does.
Do you have an example where it doesn't?It definitely does not:
And if you try call-time-pass-by-reference, it gets worse:
Yeah, that's what I remembered.
call_user_func()
is not exactly the same
as
calling the function, when references come to scene, it just wont work.Same with _array() implementation.
Julien.Pauli
call_user_func_array will work ok. This is the only call_user_func problem.
Angel,
Also, AFAIR,
call_user_func()
doesn't work with functions using
references in args. Julien.Pauli
AFAIK it does.
Do you have an example where it doesn't?It definitely does not:
And if you try call-time-pass-by-reference, it gets worse:
Anthony
Although it does not work withcall_user_func()
it does work with
call_user_func_array()
see:
http://3v4l.org/GdUmM
Hi!
Also, AFAIR,
call_user_func()
doesn't work with functions using references
in args.
Use call_user_func_array()
for that, it supports refs.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Tue, Mar 19, 2013 at 12:42 AM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
Also, AFAIR,
call_user_func()
doesn't work with functions using
references
in args.Use
call_user_func_array()
for that, it supports refs.
Isn't it since 5.3 or so ?
Julien.Pauli
Hi!
Use `call_user_func_array()` for that, it supports refs.
Isn't it since 5.3 or so ?
I think it always has been this way. See: http://3v4l.org/CGCLS
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Julien Pauli jpauli@php.net wrote:
On Tue, Mar 19, 2013 at 12:42 AM, Stas Malyshev
smalyshev@sugarcrm.comwrote:Hi!
Also, AFAIR,
call_user_func()
doesn't work with functions using
references
in args.Use
call_user_func_array()
for that, it supports refs.Isn't it since 5.3 or so ?
Before 5.3 call_uer_func_array() could convert copied values in the array to references, something like
<?php
$v = 42;
$a = array($v);
func f(&$param) { $param = 0; }
call_user_func_array('f', $a);
echo $v; // prints 0
?>
"worked", while obviously being wrong. This was fixed.
Anyways, both call_user_func()
and call_user_func_array()
have their place, one for doing dynamic stuff, secondly for compatibility, no need to get rid of those. Adding syntactical sugar for calling things is a different question, but a key element of the PHP language design is to have verbosity, so that even people who don't know all constructs have a chance to search for it. We're getting rid of this slowly (i.e. due to things like $a = [ ] ) but we houldn't loose this idea completely.
johannes
call_user_func()
just seems so ugly now that we have nicer syntax in
so many other areas.
That doesn't mean we should just be ripping out functionality that works
perfectly fine.
cheers,
Derick
--
http://derickrethans.nl | http://xdebug.org
Like Xdebug? Consider a donation: http://xdebug.org/donate.php
twitter: @derickr and @xdebug
Posted with an email client that doesn't mangle email: alpine
call_user_func()
just seems so ugly now that we have nicer syntax in
so many other areas.That doesn't mean we should just be ripping out functionality that works
perfectly fine.
I was not clear in my initial post. I don't want call_user_func removed, just made
unnecessary. To reiterate why:
-
call_user_func fails reference args. (It's not a full substitute for a direct call)
-
Most callable values are already directly callable:
✓ func as string
✓ dynamic method as array
✓ static method as array
static method as string
✓ Closure
✓ object with __invoke
Closure in object property (I understand why this is off the table)
expression containing Closure in object property
If always store the callable in a var, the situation is much better:
✓ func as string
✓ dynamic method as array
✓ static method as array
static method as string
✓ Closure
✓ object with __invoke
✓ Closure in object property
How difficult would it be to support making this work?
$c = "Foo::bar";
$c();