From: <gh...@nc...> - 2001-10-26 00:21:25
|
I'm happy to report that I am now in a position to put together a working foundation class library fairly quickly. I would be embarassed to say how long it took me to get this far but suffice it to say that it has been a very good learning experience. There was a bit of a learning curve to working with code in packages. In this post I want to explain what I propose to do and ask for comments to see if there is a consensus on it and related issues. Ok, let's start with some sample foundation class library code. Here is the current Foundation.curl. ------------------------------------------------------------------ ||foundation class for curl-email project {curl 1.6 package} {package ORG.CURL-EMAIL.FOUNDATION, author="", version="0.1"} {import * from CURL.GUI.BASE} {import * from CURL.GUI.CONTROL-BASE} {import * from CURL.GUI.CONTROLS} {import * from CURL.GUI.EXTRAS} {import * from CURL.GUI.SINGLETON} {import * from CURL.GUI.STANDARD} {import * from CURL.GUI.TEXT-EDIT} {import * from CURL.GUI.TEXT-FORMATS} {define-class public MyVBox {inherits VBox} {constructor public {default ...} {construct-super ...} } } {define-proc public {my-vbox ...}:MyVBox {return {MyVBox ...}} } {define-class public MyHBox {inherits HBox} {constructor public {default ...} {construct-super ...} } } {define-proc public {my-hbox ...}:MyHBox {return {MyHBox ...}} } {define-class public MyCommandButton {inherits CommandButton} {constructor public {default ...} {construct-super ...} } } {define-proc public {my-commandbutton ...}:MyCommandButton {return {MyCommandButton ...}} } {define-class public MyTextField {inherits TextField} {constructor public {default ...} {construct-super ...} } } {define-proc public {my-textfield ...}:MyTextField {return {MyTextField ...}} } ------------------------------------ This is largely based on examples from the curl basic docs for using rest arguments and the curl gui docs for building custom controls. Here is code that exercises the package above. ------------------------------------------- {curl 1.6 applet} {import * from ORG.CURL-EMAIL.FOUNDATION, location="file:///c:/cvs/curlmail/curl- email/Foundation.curl"} {value {MyVBox "test", background="pink", font-size=14} } {value {my-vbox "test", background="yellow", font- size=14} } {value h:MyHBox = {my-hbox background="blue"}b:MyCommandButton = {my- commandbutton} {h.add b} {h.add {my-commandbutton}} {h.add {my-textfield width=3in}} } ----------------------------------------- (some of the code lines probably got wrapped in odd places but hopefully the intent is clear) I suppose it is obvious that these rasise a swarm of questions/issues. I have worked with vendor supplied class libraries prior to curl and one of the golden rules that I have accepted is that you never create an object in code that inherits directly from a vendor library object. Instead all objects inherit from your own objects in your own libraries. Hence the idea of a foundation class library that holds all your lowest level objects that inherit directly from vendor library objects. The result is that you can make global changes in any of your objects by changing the corresponding ancestor object in your foundation class. So with the sample code above, instead of having VBox objects throughout your code you would have MyVBox objects. I've seen the advantages of doing this on some fairly large projects and it is hard to contemplate the alternative. Ultimately you would probably have several other objects in a UI package that inherit from MyVBox. You have probably read Dan Breslau's post where he suggests that the golden rule cited above may not be warranted and for sure suggests that objects should be named according to their function. My intent here is to get a feel how the rest of the team thinks on these issues and not to suggest that mine is the only way to go. I am new to programming in curl and suspect most of the team are relatively new to it too. My experience with this type of situation is that about the time we get the project finished is when we'll know how we wish we had done it from the beginning. Having a foundation class object underneath all our objects will give us the chance to go in and do some of the things we wished we had done in the beginning with the least amount of effort. The base class objects are the most generic objects of a given type that we will have. In the spirit of giving them descriptive names we could use GenericVBox instead of MyVBox or maybe GenVBox. I am personally not fussy about the exact name buy do prefer something rather short and consistent. Note in the package code above I have written a function for each class that returns an object of the given class. This would add a layer of indirection that may prove valuable and I like it because the curl naming conventions mean that function names are all lower case. So whether to create all objects through a function, directly from the class name, or a mix of the two is a related question. Finally a few smaller questions to think about. The location specifier in the package declaration above is specific to my computer so we need to find a way to deal with that. And how about author and version in the package declaration. Are we going to use our own names or a team name and what version to use for now? And what about the file name Foundation.curl? Do we want to think about standards for file names and indentifier names? Also points of style such as spaces around assignment operators, etc. I'm ready to move quickly on building a foundation class which for starters would hold all the visual GUI classes that I can come up with. Foundation classes can also be valuable for non-visual objects but it depends a lot on what you're doing with them. Your comments are requested and appreciated. Gene H. |