Woops,
https://wiki.php.net/rfc/expectations
Cheers
Joe
>
>
> https://wiki.php.net/rfc/expectations
>
I like it!
I'll vote yes for this.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
> https://wiki.php.net/rfc/expectations
>
Current `assert()` may call functions
php > assert(version_compare(PHP_VERSION, '4', '<'));
Warning: `assert()`: Assertion failed in php shell code on line 1
but it seem not closure like this
php > assert(function() {return 2>1;});
php > assert(function() {return 2<1;});
Is it possible write closure like this?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
> Hi Joe,
>
>
>
> > https://wiki.php.net/rfc/expectations
> >
>
> Current `assert()` may call functions
>
> php > assert(version_compare(PHP_VERSION, '4', '<'));
>
Note, that not `assert()` calls the function, but you. You already call
"version_compare()" and pass the return value to "assert()". While this
works it is not really recommended, because it is executed, even if you
disable assertions. Additionally the assertion message after failed
assertions is not really useful
php > assert('version_compare(PHP_VERSION, "4", "<")');
>
> Warning: `assert()`: Assertion failed in php shell code on line 1
>
> but it seem not closure like this
>
> php > assert(function() {return 2>1;});
> php > assert(function() {return 2<1;});
>
assert('2>1');
works
>
> Is it possible write closure like this?
>
> Regards,
>
> --
> Yasuo Ohgaki
> yohgaki@ohgaki.net
>
--
github.com/KingCrunch
Hi Sebastian,
On Tue, Feb 4, 2014 at 10:11 PM, Sebastian Krebs krebs.seb@gmail.comwrote:
but it seem not closure like this
php > assert(function() {return 2>1;});
php > assert(function() {return 2<1;});assert('2>1');
works
It's not the point. Function call works, but not closure does not.
php > function f() {return FALSE;}
php > assert(f());
Warning: assert()
: Assertion failed in php shell code on line 1
It's inconsistent as closure is valid expression.
Allowing callable make behavior consistent. It enables more
complex assertion inline, thus it's possible name space clean.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
It's inconsistent as closure is valid expression.
Allowing callable make behavior consistent. It enables more
complex assertion inline, thus it's possible name space clean.
Might also help assert()
performance, given that I expect executing a
closure to be quicker than eval() (though I may be wrong).
Andrea Faulds
http://ajf.me/
Hi Andrea,
It's inconsistent as closure is valid expression.
Allowing callable make behavior consistent. It enables more
complex assertion inline, thus it's possible name space clean.Might also help
assert()
performance, given that I expect executing a
closure to be quicker than eval() (though I may be wrong).
eval() works.
php > assert(eval('FALSE;'));
Warning: assert()
: Assertion failed in php shell code on line 1
php > assert(eval('return FALSE;'));
Warning: assert()
: Assertion failed in php shell code on line 1
php >
However, it does not solve inconsistency. PHP code has to be string.
Writing PHP code as string is not fun thing to do ;)
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
eval() works.
php > assert(eval('FALSE;'));
Warning:
assert()
: Assertion failed in php shell code on line 1
php > assert(eval('return FALSE;'));Warning:
assert()
: Assertion failed in php shell code on line 1
php >However, it does not solve inconsistency. PHP code has to be string.
Writing PHP code as string is not fun thing to do ;)
That's not what I meant. At present, you do:
assert($string);
And that string is evaluated. A closure would be faster. Though this is
for debugging code, so I'm not sure it matters (though I, unlike some
people, might like to use assertions in production code to make sure
things fail early, fail often).
--
Andrea Faulds
http://ajf.me/
eval() works.
php > assert(eval('FALSE;'));
Warning:
assert()
: Assertion failed in php shell code on line 1
php > assert(eval('return FALSE;'));Warning:
assert()
: Assertion failed in php shell code on line 1
php >However, it does not solve inconsistency. PHP code has to be string.
Writing PHP code as string is not fun thing to do ;)That's not what I meant. At present, you do:
assert($string);
And that string is evaluated. A closure would be faster. Though this is
for debugging code, so I'm not sure it matters (though I, unlike some
people, might like to use assertions in production code to make sure things
fail early, fail often).
I think I understood your comment.
php > assert('function() {return FALSE;}');
php > assert('function() {return TRUE;}');
It does not work, but
php > assert(eval('function() {return FALSE;};'));
Warning: assert()
: Assertion failed in php shell code on line 1
so closure in eval() works. I don't see reason not to allow closure
directly.
It only seems inconsistent to me.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi all,
php > assert('function() {return FALSE;}');
php > assert('function() {return TRUE;}');It does not work, but
php > assert(eval('function() {return FALSE;};'));
Warning:
assert()
: Assertion failed in php shell code on line 1so closure in eval() works. I don't see reason not to allow closure
directly.
It only seems inconsistent to me.
Added this to inconsistent behaviors RFC to track.
https://wiki.php.net/rfc/inconsistent-behaviors#assert
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi all,
php > assert('function() {return FALSE;}');
php > assert('function() {return TRUE;}');It does not work, but
php > assert(eval('function() {return FALSE;};'));
Warning:
assert()
: Assertion failed in php shell code on line 1so closure in eval() works. I don't see reason not to allow closure
directly.
It only seems inconsistent to me.Added this to inconsistent behaviors RFC to track.
There is a difference between f() and 'f'. The former is a function call,
the latter a callback. The eval-behavior non-withstanding assert is
essentially if (!$arg1) { error($arg2); }. So if (!f()) { ... } makes a lot
of sense, but if (!function() {}) {} makes zero sense. Again, function() {}
only creates a callback, but does not run it. To run it, you'd need
something like (function(){})().
There is no inconsistency here. Allowing callables in general is not
compatible with the existing string-eval mode and the expectation that
arrays will assert true if they are non-empty. Adding only closures, that
is inconsistent.
Nikita
exectly :)
Thanks. Dmitry.
Hi all,
php > assert('function() {return FALSE;}');
php > assert('function() {return TRUE;}');It does not work, but
php > assert(eval('function() {return FALSE;};'));
Warning:
assert()
: Assertion failed in php shell code on line 1so closure in eval() works. I don't see reason not to allow closure
directly.
It only seems inconsistent to me.Added this to inconsistent behaviors RFC to track.
There is a difference between f() and 'f'. The former is a function call,
the latter a callback. The eval-behavior non-withstanding assert is
essentially if (!$arg1) { error($arg2); }. So if (!f()) { ... } makes a lot
of sense, but if (!function() {}) {} makes zero sense. Again, function() {}
only creates a callback, but does not run it. To run it, you'd need
something like (function(){})().There is no inconsistency here. Allowing callables in general is not
compatible with the existing string-eval mode and the expectation that
arrays will assert true if they are non-empty. Adding only closures, that
is inconsistent.Nikita
Hi Nikita,
There is a difference between f() and 'f'. The former is a function call,
the latter a callback. The eval-behavior non-withstanding assert is
essentially if (!$arg1) { error($arg2); }. So if (!f()) { ... } makes a lot
of sense, but if (!function() {}) {} makes zero sense. Again, function() {}
only creates a callback, but does not run it. To run it, you'd need
something like (function(){})().
Thank you for the explanation.
Current assert()
is consistent as its spec, since it does not support
callable which is callback function.
I think assert()
may accept closure. As I wrote in another mail,
assert(function() {
// some
// useful
// code
});
looks nicer and more modern.
Users are use to this as this kind of form is extensively used in
JavaScript.
I wish to have this form for new assert()
.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
php > assert('function() {return FALSE;}');
php > assert('function() {return TRUE;}');
This runs function() code, which produces a closure. The closure is not
false, so assert is not fired.
php > assert(eval('function() {return FALSE;};'));
The eval here returns NULL
(http://3v4l.org/cPpgj) so of course assert
will be fired here. From eval's manual:
eval() returns NULL
unless return is called in the evaluated code, in
which case the value passed to return is returned.
Compare:
http://3v4l.org/vhe1p
http://3v4l.org/B79r3
Warning:
assert()
: Assertion failed in php shell code on line 1so closure in eval() works. I don't see reason not to allow closure
Did you try:
assert(eval('function() {return TRUE;};'));
Testing hypothesis usually involves not only testing something that
confirms it, but also something that may refute it. Otherwise you're not
really testing, you are just convincing yourself.
Added this to inconsistent behaviors RFC to track.
There's no inconsistent behaviors here and IMHO this RFC is turning into
"things people misunderstand in PHP". Maybe it should be moved to a blog
or some other space, because it by now has very little to do with what
RFCs are for.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi all,
On Wed, Feb 5, 2014 at 4:17 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
php > assert('function() {return FALSE;}');
php > assert('function() {return TRUE;}');This runs function() code, which produces a closure. The closure is not
false, so assert is not fired.php > assert(eval('function() {return FALSE;};'));
The eval here returns
NULL
(http://3v4l.org/cPpgj) so of course assert
will be fired here. From eval's manual:
eval() returnsNULL
unless return is called in the evaluated code, in
which case the value passed to return is returned.
Compare:
http://3v4l.org/vhe1p
http://3v4l.org/B79r3
Thank you.
It looks I did wrong on my little experiment.
Warning:
assert()
: Assertion failed in php shell code on line 1so closure in eval() works. I don't see reason not to allow closure
Did you try:
assert(eval('function() {return TRUE;};'));Testing hypothesis usually involves not only testing something that
confirms it, but also something that may refute it. Otherwise you're not
really testing, you are just convincing yourself.Added this to inconsistent behaviors RFC to track.
There's no inconsistent behaviors here and IMHO this RFC is turning into
"things people misunderstand in PHP". Maybe it should be moved to a blog
or some other space, because it by now has very little to do with what
RFCs are for.
function func() {}
assert(func());
and
assert(function func() {});
would be better to get the same result. Besides, rather than
$f = function func() {};
assert($f());
This form
assert(function func() {
// some code here
});
is more user friendly and looks more modern language.
I'm sure most users are used to latter form, since this form
is used extensively in JavaScript. It keeps variable scope
clean, too.
I hope new assert()
supports direct closure call :)
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
function func() {}
assert(func());and
assert(function func() {});
would be better to get the same result. Besides, rather than
It won't be the same result, because first is a function call, and the
second one is not even an expression in PHP, it's function definition.
But if it were anonymous function, it would return function and not the
result on the function call.
This form
assert(function func() {
// some code here
});
You probably meant to write a closure (anonymous function) there. So you
actually want assert to support calling closures. This would be a BC
break, but it is very easy to make your own assert that does just that.
I'm sure most users are used to latter form, since this form
is used extensively in JavaScript. It keeps variable scope
clean, too.
No users of PHP are used to this form since this form does not exist in
PHP. As for Javascript users, there's no assert in standards, but many
browsers support console.assert - which works exactly like PHP assert
(without eval stuff) and does not support calling closures either.
See e.g. http://stackoverflow.com/q/15313418/214196
So I wonder how Javascript users would get used to that?
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi Stas,
On Wed, Feb 5, 2014 at 4:58 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
This form
assert(function func() {
// some code here
});You probably meant to write a closure (anonymous function) there. So you
Yes.
actually want assert to support calling closures. This would be a BC
break, but it is very easy to make your own assert that does just that.
If we allow any callable, it's would be BC break since callable could
be string (function name).
I'm sure most users are used to latter form, since this form
is used extensively in JavaScript. It keeps variable scope
clean, too.No users of PHP are used to this form since this form does not exist in
PHP. As for Javascript users, there's no assert in standards, but many
browsers support console.assert - which works exactly like PHP assert
(without eval stuff) and does not support calling closures either.
See e.g. http://stackoverflow.com/q/15313418/214196
So I wonder how Javascript users would get used to that
I meant the form of the code, not assert()
.
JavaScript uses callbacks extensively and users are used to it.
PHP users are also getting used to it since the introduction of closure.
If we are going to support closure only callback, then everything is ok
for assert()
to call closure, I suppose.
Sorry that I wrote the same thing 3 times in this thread, but
assert(function() {
// some code
});
would keep variable scope/name space clean when user would like to
use call back.
$f = function f() {};
assert($f());
OR
function f() {}
assert(f());
I think it's nice to have clean variable scope/name space with assert()
.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
I meant the form of the code, not
assert()
.
JavaScript uses callbacks extensively and users are used to it.
PHP users are also getting used to it since the introduction of closure.
But I mean assert()
. Javascript implementations have assert()
- Chrome
has it, Firefox has it, NodeJS has it. It does not work like you
propose. Doesn't it make you question your assertion that Javascript
users really need this?
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi Stas,
On Wed, Feb 5, 2014 at 5:29 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
I meant the form of the code, not
assert()
.
JavaScript uses callbacks extensively and users are used to it.
PHP users are also getting used to it since the introduction of closure.But I mean
assert()
. Javascript implementations haveassert()
- Chrome
has it, Firefox has it, NodeJS has it. It does not work like you
propose. Doesn't it make you question your assertion that Javascript
users really need this?
I think it's nice to have as it does not use variable scope/name space.
Code related to assert()
is better to hide it's existence as much as
possible. IMO.
JavaScript implementations have different APIs. Node.js has closer API.
assert.throws(
function() {
throw new Error("Wrong value");
},
Error
);
while we may have
assert(
function() {
// Some check here
return FALSE;
},
'Error'
);
I would use at least, since I don't want to assert()
related code to use
variable scope nor namespace.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Stas and all,
On Wed, Feb 5, 2014 at 5:29 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
I meant the form of the code, not
assert()
.
JavaScript uses callbacks extensively and users are used to it.
PHP users are also getting used to it since the introduction of closure.But I mean
assert()
. Javascript implementations haveassert()
- Chrome
has it, Firefox has it, NodeJS has it. It does not work like you
propose. Doesn't it make you question your assertion that Javascript
users really need this?I think it's nice to have as it does not use variable scope/name space.
Code related toassert()
is better to hide it's existence as much as
possible. IMO.JavaScript implementations have different APIs. Node.js has closer API.
assert.throws(
function() {
throw new Error("Wrong value");
},
Error
);while we may have
assert(
function() {
// Some check here
return FALSE;
},
'Error'
);I would use at least, since I don't want to
assert()
related code to use
variable scope nor namespace.
Since I like new assert()
, I thought it may help if I explain why I didn't
use assertion.
I have 2 reasons for not using old assert()
at all until now.
- Performance: couldn't accept run time overheads
- Scope/Namespace: couldn't accept scope/namespace pollution with complex
assert.
1st one is the main reason. 2nd one, I may live with it new assert()
, but I
do
not want to pollute scope/namespace if it can. It does not make sense to use
scope/namespace for assert()
to me. (with complex assertion)
Before the closure introduction, I had to define function. Without
namespace, it's not
a acceptable solution at all. Even with namespace, it's far from
acceptable. Another
option is create_function()
, but it's pain to write PHP code as string.
It's not acceptable
also. Closure would be acceptable, but it's not clean as it should be w/o
closure
callback support.
I cannot wait to use new assert()
. If it supports closure callback, it's
PERFECT!
I'm really excited about new assert()
and I wish desperately it supports
closure
callback. Please add closure callback :)
Thank you!
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Yasuo Ohgaki wrote (on 05/02/2014):
JavaScript implementations have different APIs. Node.js has closer API.
[...]
assert(
function() {
// Some check here
return FALSE;
},
'Error'
);I would use at least, since I don't want to
assert()
related code to use
variable scope nor namespace.
Actually, if you think this through with a real example, this only makes
sense because of JS's scoping rules, which are very different from PHP's.
A JS closure inherits the whole parent scope by default, and adds
private vars to it, so this would be possible:
function foo(arg)
{
assert ( function() {
var assert_private_var = some_function();
return arg == assert_private_var;
}, 'oops' );
}
In PHP, there is no notion of inherited scope, so this would not work:
function foo($arg)
{
assert ( function() {
$assert_private_var = some_function();
return $arg == $assert_private_var;
}, 'oops' );
}
Since an assertion that can't actually check any state is useless for
anything other than assert(false, 'Should never happen'), you'd always
have to have a use() importing things:
function foo($arg)
{
assert ( function() use ($arg) {
$assert_private_var = some_function();
return $arg == $assert_private_var;
}, 'oops' );
}
That's a lot of boilerplate and room for mistakes, IMHO.
Of course, if we could fix the parser to evaluate functions as soon as
they're defined like in JS, you could make the whole thing into an
expression which would work with the current (and proposed) assert:
function foo($arg)
{
assert ( (function() use ($arg) {
$assert_private_var = some_function();
return $arg == $assert_private_var;
})(), 'oops' );
}
Not pretty, but it would give you your local scope.
Regards,
Rowan Collins
[IMSoP]
Hi Rowan,
On Wed, Feb 5, 2014 at 7:08 PM, Rowan Collins rowan.collins@gmail.comwrote:
function foo($arg)
{
assert ( (function() use ($arg) {
$assert_private_var = some_function();
return $arg == $assert_private_var;
})(), 'oops' );
}Not pretty, but it would give you your local scope.
I agree, some thing like this is needed to call closure or pass arguments
to assert()
then call.
It better than using scope. IMO.
BTW, if we would like to write down all of assert()
related code inside
current assert()
,
it seems this works. It still pollutes scope, though.
php > $v = 555;
php > assert(($f = function($v) {var_dump($v);return $v < 0;}) && ($f($v)));
int(555)
Warning: assert()
: Assertion failed in php shell code on line 1
This may be the way to use new assert.
assert(
($f = function($v)
{
var_dump($v);return $v < 0;
})
&&
($f($v)),
'Do not pass bad value'
);
It does not look good, but not too bad.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
I agree, some thing like this is needed to call closure or pass arguments
toassert()
then call.
If we allow to pass arguments, it would be something like
assert(
function($arg1, $arg2) {
return $arg1 > $arg2;
},
'Do not pass bad value',
[$arg1, $arg2]
);
It looks nicer than
assert(
($f = function($arg1, $arg2) {
return $arg1 > $arg2;
})
&&
($f($arg1, $arg2)),
'Do not pass bad value'
);
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
I agree, some thing like this is needed to call closure or pass arguments
toassert()
then call.If we allow to pass arguments, it would be something like
assert(
function($arg1, $arg2) {
return $arg1 > $arg2;
},
'Do not pass bad value',
[$arg1, $arg2]
)
Since we don't have 3 parameters signature for assert()
now
assert(
[$arg1, $arg2],
function($arg1, $arg2) {
return $arg1 > $arg2;
},
'Do not pass bad value'
);
is possible. Could we have this?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi all,
Sorry for multiple posts.
I agree, some thing like this is needed to call closure or pass
arguments toassert()
then call.If we allow to pass arguments, it would be something like
assert(
function($arg1, $arg2) {
return $arg1 > $arg2;
},
'Do not pass bad value',
[$arg1, $arg2]
)Since we don't have 3 parameters signature for
assert()
nowassert(
[$arg1, $arg2],
function($arg1, $arg2) {
return $arg1 > $arg2;
},
'Do not pass bad value'
);is possible. Could we have this?
Or another function for callback?
assert_callback(array $args, callable $callback [, string $description]);
assert_callback(
[$arg1, $arg2],
function($arg1, $arg2) {
return $arg1 > $arg2;
}
);
It seems this is cleanest among feasible options.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net