Groovy 3 semantics and new MOP
Jochen "blackdrag" Theodorou
|Last update by:|
For quite long we are thinking about a new MOP for Groovy, without finding the right way to do it better this time. It is difficult to find the right path between being user-friendly and efficient. Thus the new MOP will contain some features the old did not, but will also remove some old features for the sake of a more straight and more easy to understand MOP.
|Table of Contents|
Removing default null argument
Given those two definitions a method call in A will select the set of method to decide from based on this:
A call m() with the SSC A and done on an instance of B (extends A) will be using the methods defined in A, if A has a private m, otherwise the call is done using B.
Calls to Super:
A call to super in B extends A will have the SSC B, but for the method selection process the super class of SSC (super(SSC)) will be used. In super calls mutimethods are not visible. Thus we can directly use the meta class super(SSC), but we will dispatch only on the public methods of that meta class.
Module Extension Methods Shadowing Rules
Module Extensions Methods are in the old and new MOP defined by the DefaultGroovyMethods related classes and module extension, like groovy-swing. In the definition here we will use the terms of from "inside" and from "outside" to define a callsite, that lies in the same class as the target method (inside) or not (outside). The general rules are:
- public methods are shadowed
- private methods are shadowed for outside callsites, but not for inside callsites
Subclasses of the class the module extension method has been applied to have these extended rules:
- if the subclass defines a private method of the same signature as the module extension method, then outside callsites will still see the extension method, inside callsites the private method
- A call to "super" or "this" will call the module extension method. As such the subclass is seen as outside callsite.
Open Blocks are not seen as separate classes.
Currently MetaClass discovers properties based on the Java Beans conventions. It also allows pseudo properties matching a convention on java.beans.EventSetDescriptor. This allows the following trick in SwingBuilder for example
The pseudo property actionPerformed is inferred from the single method exposed by ActionListener, a type of listener that can be registered on a JButton. The code responsible for discovering these properties is buried in MetaClassImpl and is not accessible to the outside. It would be great if this mechanism be made pluggable.
The Realm concept
In MOP2 a Realm is a tree like structure containing the meta classes. There is a root realm, used as default, but there can be any number of lower realms. A meta class change is visible in a realm, if the change is done to the meta class in the same realm or to a meta class in a higher realm. Script execution engines are able to set a realm for example to prevent them changing meta classes they should not change. This can be used for unit tests to isolate meta class changes done during the tests as well. A library can have its own realm (defined through an annotation) to prevent other classes to leak their changes into that library, while the library can still use a higher realm to make changes more public visible, if the realm allows that. Realms can have a setting that prevents code executed from there to make changes to higher realms. Calling a method is always done using the meta classes from the current realm, even if the called class then calls other classes using its own realm. A realm is thus not thread local structure, it is more of a lexical scope. A realm can also use a different meta class flavor, to for example allow access to private methods and fields.