Re: [RFC] PHP Attributes

From: Date: Sat, 23 Apr 2016 16:21:04 +0000
Subject: Re: [RFC] PHP Attributes
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-92658@lists.php.net to get a copy of this message
On 4/22/2016 4:15 AM, Sara Golemon wrote: > All that said, I love the proposal overall, and I can't wait to > propose builtin annotations like <<__Memoize>>, <<__Mock>>, and > similar. > I'd rather see these two functionalities added as modifiers at the language level instead since they change the code behavior rather dramatically. Not sure if knowledge of them is of interest in stages where annotations might not be readily available; this was a driving factor in Kotlin's decision what becomes a modifier or annotation.[1] <?php final class A { private memoized function f() {} } test class B extends A { // OK, despite final. public function f() {} // Has access to private methods. } test class C extends B {} // OK class D extends B {} // Fatal Error! ?> I know that this is true for @invariant, @require, and @ensure as well, they are fully-fledged assertions after all. Especially the @invariant could be easily added as a magic method. [assert] assert.invariants = 1 <?php final class Object { public function __invariant() {} } ?> Both @require and @ensure are a bit harder to implement at language level. The following is the best I can come up with and is inspired by the Eiffel syntax.[2] [assert] assert.preconditions = 1 assert.postconditions = 1 <?php class PreconditionError extends AssertionError {} class PostconditionError extends AssertionError {} final class Account { public function withdraw(int $sum): void { $this->balance -= $this->balance - $sum; } require { $sum >= 0; $sum <= ($this->balance - self::MIN_BALANCE); } ensure { $this->balance === (old::$balance - $sum); } } $account = new Account; $account->withdraw(-10); /* Uncaught PreconditionError: $sum >= 0 */ $account->withdraw(10); /* Uncaught PreconditionError: $sum <= ($this->balance - self::MIN_BALANCE) */ $account->deposit(10); $account->withdraw(5); /* Uncaught PostconditionError: $this->balance === (old::$balance - $sum) */ ?> I actually think now that it would be better to go for this than for annotations. [1] http://blog.jetbrains.com/kotlin/2015/08/modifiers-vs-annotations/ [2] https://archive.eiffel.com/doc/online/eiffel50/intro/language/invitation-07.html -- Richard "Fleshgrinder" Fussenegger

Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc
« previous php.internals (#92658) next »