HI, I thought I may have trouble with this area :-(
I am migrating quite a lot of gambas2 components that work well and most of the pain has arisen in this signature checking in the runtime, as in the "incorrectly overridden" message. First, because this is only evident in the runtime, I have a fear that testing the converted components may miss the error when the override is in a rarely executed area of code. Secondly, I can no longer override a method declared in a base class as Identifier(...) with a method in the child class with a real and restricted parameter set. To explain, I have a set of base classes in component X that provide the very fundamental features of an inheritance hierarchy. As well, they prescribe a set of methods that must be implemented in the child classes. In short, they are "stubs" for required methods. All they do is raise an error if the method is not overridden in the child class. Because of this, these stubs have no idea nor do they care what the parameters of the child class method are. As an example, I have a persistence model that involves three levels of code: the [application] ----uses---> [a business_object library] ---inherits---> [base_persistence] The persistence of the data is entirely handled by the two lower level libraries, the application only has to call the Create, Read, Update or Delete methods on the business_object object and all it's persistence needs are handled. The business_object library contains all the relevant business rules for its classes, e.g. whether objects can be deleted from the persistence or whether a cascaded delete is necessary etc etc. However, the business_object layer has no idea exactly how the persistence is achieved, it just validates the action applies the relevant transformations between the object data model and the persistence data model and then passes the object data off to the low level persistence methods in it's parent class. This is the high level design. The implementation employs the following code model: at the business_object library level, each business object has (at least) two classes, the main object class, e.g. "Account" and one or more mapping classes, say "_sqlaccount" and "_xmlaccount". The main class is visible to the application, the mapping classes are hidden. The mapping classes provide the two way transformation between the object data and the persistence data, in short they have a "Marshall" method and an "Unmarshall" method. These two methods are very importantly "visible" to the base_persistence library. The last comment requires explanation. In the base_persistence library there is a similar split between the "object" model and the "persistence" model. There is a base "BusinessObject" class, from which all the classes in the business_object library inherit, and a base "persistor" from which all the mapping classes in the business_object library inherit. (There is a tricky bit here that is important to the design but irrelevant to this message - there is a base persistor for each persistance type, e.g. postgresql, mysql, xml, flatfile etc. Each of these is in separate libraries and is loaded explicitly at runtime by the BusinessObject class depending on the settings file for the business_object library. Suffice to say that it is the actual base persistor that provides the actual input/output methods to "add", "load", "save" and "remove" the data. Note the change from the CRUD method names!) When the application instantiates a business object, say an Account object called "MyAccount", the constructor in the base_persistence library BusinessObject class i.e. BusinessObject._new() checks the persistence method in use and instantiates the relevant mapping class in the business_object library, i.e. it creates an actual persistor which is either a "_sqlaccount" or an "_xmlaccount". How I do this is irrelevant, the important thing is that the BusinessObject has access to, via the gambas virtual dispatching feature, one of these things which as far as it is concerned is a "persistor". The CRUD methods are actually public in the BusinessObject class, i.e. they are inherited by the classes in the business object library. So when the application does a "MyAccount.Update, it is actually calling the BusinessObject.Update method. This in turn calls its' persistor.save method. In fact, what it does is call its' persistor.Marshall method and then its' persistor.save method. Note the subtle inference here, the Marshall method is the the one in the active mapping class and the save method is the one in the base persistor class (there is no save method in the mapping class). However, in order to compile the base_persistence libraries there must be a "stub" method called "Marshall" at this level and this is the one that MUST be overridden at the higher level. Further, at this level (in the base persistor libraries) I have no idea as to how the business_object library level "Marshall" method works, nor what parameters it needs to achieve that work - that is a matter for the specialised classes and the BusinessObject class. All I know is that the method must be declared and it must be overridden, so it is: Public Sub Marshall(...) Error.Raise("Implementation fault - this method must be overridden in the business_object library") End I hope you have managed to follow all this and can offer some advice. The persistence architecture model is not my own invention, it comes from work by Fowler and others. It has worked for me for the last two years in gambas2 and (the code) is the result of significant!!! effort on my part. I just can't see a solution now with this signature checking in the gambas3 runtime. Finally, I still can't see the value in this signature checking. This is only one area where I have successfully used method overrides in gambas2 which now have to be not only rewritten but redesigned for gambas3. Why was it introduced? If it is really necessary for something else then I'd like to ask for a way to turn it off, preferably at the gbx3 compile, not only for signature checking but also for result type checking. regards Bruce ------------------------------------------------------------------------------ All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity and more. Splunk takes this data and makes sense of it. Business sense. IT sense. Common sense. http://p.sf.net/sfu/splunk-d2dcopy1 _______________________________________________ Gambas-user mailing list Gambas-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gambas-user