On 10/01/2013 01:19 PM, Terence Copestake wrote:
On Fri, Sep 27, 2013 at 11:26 AM, Joe Watkins <krak...@php.net> wrote:
On 09/27/2013 10:42 AM, Terence Copestake wrote:
Just ... Isn't that something, we can simply keep out of _this_ RFC and
create separate RFC(s) for it later? Like it was done with "$this in
Closures"?
Do we want another 5.3/5.4 closures situation? Why not iron it all out to
begin with?
If there's a sound, logical reason not to implement the functionality in
question, that's fine. I don't understand why we keep reiterating "keeping
it simple" as if that is in itself an excuse to, in effect, rush it
through
half-baked.
In the RFC, there are use cases citing languages like Java to support this
- a language in which anonymous classes and the methods in which they're
defined, share scope. Can we then say, let's do it because it's useful in
other languages, but let's not offer the functionality that those
languages
do? Also, my proposed use case being practical in the real world hangs on
resolving the scope issue, as I struggle to look past the difficulties I'd
have trying to use this in my code when it's unable to interact with the
object instance in which it is being used.
That's all I'll say on that now; it's becoming circular.
If you want to update my use case in the RFC, here's an expanded example
of
what I imagine. I've lifted code from the documentation for Sentry* and
below it, written an alternative anonymous class API example.
* I have no affiliation with Sentry / other membership packages are
available.
try
{
// Find the user using the user id
$user = Sentry::findUserById(1);
// Log the user in
Sentry::login($user, false);
}
catch (Cartalyst\Sentry\Users\**LoginRequiredException $e)
{
echo 'Login field is required.';
}
catch (Cartalyst\Sentry\Users\**UserNotActivatedException $e)
{
echo 'User not activated.';
}
catch (Cartalyst\Sentry\Users\**UserNotFoundException $e)
{
echo 'User not found.';
}
// Following is only needed if throttle is enabled
catch (Cartalyst\Sentry\Throttling\**UserSuspendedException $e)
{
$time = $throttle->getSuspensionTime()**;
echo "User is suspended for [$time] minutes.";
}
catch (Cartalyst\Sentry\Throttling\**UserBannedException $e)
{
echo 'User is banned.';
}
becomes:
$user = Sentry::findUserById(
1,
(new class implements Cartalyst\Sentry\**LoginHandlerInterface
{
public function onLoginRequired()
{
echo 'Login field is required.';
}
public function onUserNotActivated()
{
echo 'User not activated.';
}
public function onUserNotFound()
{
echo 'User not found.';
}
// Following is only needed if throttle is enabled
public function onUserSuspended()
{
$time = $throttle->getSuspensionTime()**;
echo "User is suspended for [$time] minutes.";
}
public function onUserBanned()
{
echo 'User is banned.';
}
public function onSuccess()
{
// Log the user in
Sentry::login($user, false);
}
})
);
Because in your rush to get the ironing done, you are burning clothes,
putting big holes in them, and are going to be left with no clothes without
big holes in them ...
What we are introducing here is anonymous classes, not nested classes:
class Outer {
class Inner {
class Again {
class Inner {
}
}
}
}
This requires a way to resolve complex scope issues, these are formally
nested classes, as yet unsupported, formally nested classes might also look
like:
class Outer {
class Inner {
protected class Again {
private class Inner {
}
}
}
}
I appreciate that the only way to do this right now is with anonymous
classes, but if you are doing it with anonymous classes then you, clearly,
do not care about scope.
The solution to the resolution of nested class scope issues does not
belong as part of the RFC introducing anonymous classes but the RFC
introducing nested classes, which is as yet unwritten, but totally doable.
+1000 on keeping this for another RFC, because it's part of another
problem ...
Cheers
Joe
I think you've become confused with my intentions here. My example is not
of the internal workings of an API and I'm certainly not talking about
nested classes. My example is of a third party using an API from the
outside. Currently, the way the package given in my example communicates is
by using exceptions to signal what happened. What I'm demonstrating is that
a more expressive way to do this would be to instead pass a callback
anonymous class to handle those outcomes, rather than having a series of
catch blocks.
I only think it would be good to actually discuss (i.e. _discuss_ i.e. not
dismiss based on personal preference or deflect using obscure metaphors)
the scope implications of this feature which inherently poses questions
about scope. I don't understand the insistence on addressing this in a
separate RFC when it is pertinent to this very feature.
Wires crossed I think ... I wasn't commenting on the updated use case, I
didn't update it simply because there is surely enough information
regarding use cases included in the RFC now, I think everyone gets the
use case thing.
With regard to the scope issues; what anonymous classes allow, in
effect, is for you to nest classes, it just so happens they do not have
a declared name. I agree that issues of scope are relevant, but the
resolution to the problem doesn't belong here, it belongs in the formal
support of nesting classes, and as far as possible it will be addressed
there, grafting a solution to the scope issues onto anonymous classes
could only make it harder to formally nest classes.
If no decent solutions to formally nesting classes can be found or
accepted then the problem of scope in anonymous classes might need a
solution in its own right ... for now the solution belongs with nesting,
which is what anonymous classes actually are (when used inside another
class).
Cheers
Joe
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php