rfc:closures:object-extension

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:closures:object-extension [2010/08/11 13:25] – bindTo changes cataphractrfc:closures:object-extension [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== Closures: Object extension ====== ====== Closures: Object extension ======
 +  * Date: 2009-01-22
 +  * Author: Unknown
 +  * Status: Implemented in PHP 5.4
 +
 +===== Introduction =====
  
 Efforts were made to go beyond the scope of the original Closures proposal ([[rfc/closures]]) in order to allow the extension of objects dynamically, take the following example code: Efforts were made to go beyond the scope of the original Closures proposal ([[rfc/closures]]) in order to allow the extension of objects dynamically, take the following example code:
Line 399: Line 404:
 ==== Private/protected members (scope) ==== ==== Private/protected members (scope) ====
  
-The currently implemented handling of scope for class closures is+The currently implemented handling of scope for class closures is:
  
-- They initially inherit the (calling) scope of the class they were created in. +  - They initially inherit the (calling) scope of the class they were created in. 
-- After that, always use the class scope of the object that bindTo() is called for ([[#private_protected_member_access|option 2]]) +  - After that, always use the class scope of the object that bindTo() is called for ([[#private_protected_member_access|option 2]]) 
-- If there's any bound instance, the called scope is set to the class of it, otherwise it's the same as the calling scope.+  - If there's any bound instance, the called scope is set to the class of it, otherwise it's the same as the calling scope.
  
 The implementation of option #2 has serious drawbacks. Consider the following code: The implementation of option #2 has serious drawbacks. Consider the following code:
Line 430: Line 435:
 There's always another problem. The current implementation allows changing the scope of a static closure, but only by attempting to bind it with am object of the desired class. This has two problems: it requires an instance for a solely static operation and it may even not be possible to generate objects of the desired class (e.g. it's abstract). There's always another problem. The current implementation allows changing the scope of a static closure, but only by attempting to bind it with am object of the desired class. This has two problems: it requires an instance for a solely static operation and it may even not be possible to generate objects of the desired class (e.g. it's abstract).
  
-Therefore, I propose an implementation ([[http://nebm.ist.utl.pt/~glopes/misc/closures_scope.patch|patch here]]) of option 4: "Add a parameter to bindTo() to specify this." This option is the most versatile and the implementation in the patch has very little magic – it only changes the scope of the closure if it's requested, otherwise it keeps the previous scope. The order of the current arguments of ''Closure::bind'' was also changed so that its implementation could be unified to that of ''Closure::bindTo'' using ''zend_parse_method_parameters''. The prototype is this:+Therefore, I propose an implementation ([[http://nebm.ist.utl.pt/~glopes/misc/closures_scope.patch|patch here]]) of option #4: "Add a parameter to bindTo() to specify this." This option is the most versatile and the implementation in the patch has very little magic – it only changes the scope of the closure if it's requested, otherwise it keeps the previous scope. The order of the current arguments of ''Closure::bind'' was also changed so that its implementation could be unified to that of ''Closure::bindTo'' using ''zend_parse_method_parameters''. The prototype is this:
  
 <code> <code>
Line 439: Line 444:
  
 The patch preserves these invariants: The patch preserves these invariants:
-- A static closure, being scoped or not, cannot have any bound instance. +  - A static closure, being scoped or not, cannot have any bound instance. 
-- A non static closure has a bound instance iif it is scoped.+  - A non static closure has a bound instance iif it is scoped.
  
 To preserve these invariants, there are these additional rules: To preserve these invariants, there are these additional rules:
-- If a non static closure is given a scope (or it already has a scope, but the scope parameter is not specified) and a NULL instance, it's made static. +  - If a non static closure is given a scope (or it already has a scope, but the scope parameter is not specified) and a NULL instance, it's made static. 
-- If a static closure is given an instance, the instance is ignored and an ''E_WARNING'' notice is emitted. +  - If a static closure is given an instance, the instance is ignored and an ''E_WARNING'' notice is emitted. 
-- If a non static non scoped (and therefore non bound) instance is given no scope and a non NULL instance, it's given a dummy scope (currently the "Closure" scope). **This is the only case where the previous scope, or lack thereof, is changed by the rebinding process**. This is necessary because it's not legal to have ''$this'' with a NULL scope.+  - If a non static non scoped (and therefore non bound) instance is given no scope and a non NULL instance, it's given a dummy scope (currently the "Closure" scope). **This is the only case where the previous scope, or lack thereof, is changed by the rebinding process**. This is necessary because it's not legal to have ''$this'' with a NULL scope.
  
 Example: Example:
rfc/closures/object-extension.1281533155.txt.gz · Last modified: 2017/09/22 13:28 (external edit)