| Lescasse Consulting |
| Home Company News Prices Download Buy Forums |
|
|
At the end of these examples, you'll find an excerpt of the Presentation made by William Rutiser. First example: Simple Collections This simple example builds an APL+Win Form showing how the ŒMOM system function may be used to save all form children values into an object which members have the same name as the form controls and then how to use them in an event handler. The SimpleCollectionObjects function creates a ŒMOM object named with the same name as the form: ff object. The SimpleCollectionObjects then adds Members to this object called: ff.ed1, ff.ed2 and ff.ed3. The SimpleCollections functions makes use of the ŒMOM object in its ed.onChange handler. Every time the content of an Edit control is changed, this content is stored in the corresponding ŒMOM member (ff.ed1 or ff.ed2) on line 14. The third Edit control is then updated with the third ŒMOM member (ff.ed3) which has been simply calculated as the sum of the first 2 members ff.ed1 and ff.ed2. Here are the functions:
Second example: Functions Collections The second example is similar to the first one, but instead of using variable members, it creates a ŒMOM object with APL function members. The FunctionsCollection function creates an APL form called ff and then calls the FunctionsCollectionObject function. This function creates 3 local functions called ed1_onChange, ed2_onChange and ed3_onChange and then creates a ŒMOM object on line 27 with theses 3 functions as object Members. Despite line 27, the interesting lines are lines 4, 12 and 20 which register the onChange event on the 2 Edit controls: these event handlers call the corresponding ŒMOM object Member functions (ff.ed1_onChange, ff.ed2_onChange or ff.ed3_onChange). Functionnally this example works as the previous one: when entering values in the first 2 Edit controls, the 3rd Edit control is automatically updated with the sum of the first 2 Edit controls.
Third example: Factory Functions and Objects In this example, we create a small database made of ŒMOM person objects. The PersonsMethodsFactory creates a ŒMOM object containing 2 function Members: Age and FullName which we have defined in the workspace. The central function in this factory is PersonFactory which builds a person object. The non trivial part of this function is the creation of 2 local functions Age and FullName which override the global definitions of Age and FullName and serve as delegates to calling the global Age and FullName functions. A ŒMOM object is then created on line 10: its initial members being:
Then on line 11 to 14 more variable Members are added to the person object. The PersonFactory function finally returns the created person object. Note the use of ŒMSELF in the Age and FullName function. ŒMSELF refers to the current object, without having to name it. The ChildrenFactory builds all children for all existing persons, calling the ChildFactory function. A child being a person it should be no surprise that the ChildFactory function calls the PersonFactory to build a given child. Note that it overrides the isChild member resetting it to 1 after PersonFactory had created it and set it to 0. Examples follow and show how the created persons and children can be used in an application or in the APL Session. Note that with the current ŒMOM implementation the following construct is not allowed and yields a SYNTAX ERROR: person1.child1.name
Object Oriented Programming in APL+WinWilliam Rutiser Introduction to the MOM Object SystemElevator descriptionThe MOM object system extends APL with simple basic facilities for object oriented programming, a predominant design and structuring paradigm for modern programming languages. MOM objects are typeless, classless, and inherently polymorphic. They provide syntactic and semantic foundations for future elaboration guided by experience. Entirely internal to APL, MOM objects are not related to WI objects, COM objects, ActiveX objects, or any other family of objects. A MOM object is a simple container enclosing a set of named APL functions and variables. Each MOM object is distinct from every other MOM object. While MOM objects themselves are unnamed, each is associated with a unique object-reference value. Object-reference values join numbers and characters as a third fundamental APL data type. Object-references, just like numbers and characters, can be formed into arrays, assigned to variables, passed as parameters, and saved in workspaces. Where meaningful, they are included in the domains of primitive APL functions. Syntactically, object members are accessed as objref.member where objref is a variable holding an object reference and member is the name of the member within the object. This use of the dot, “.”, is given very high parsing precedence so that this compound name can be used wherever a simple name is allowed. This character retains its traditional meaning and precedence as the inner product operator; the two uses are distinguished by the immediate left context. A function, including user defined functions, causes the dot to be interpreted as inner product. A variable or undefined name will cause the dot to be interpreted as part of a compound name. Objects are created by the MOM system function. Arguments to MOM describe the object to be created; its result is a reference to the new object. During the execution of a member function, the system variable MSELF is set to the reference to the containing object. This gives the function access to the object's other members. Some system functions, such as NL and CR, are implicit members of (...) ReferenceThe MOM System FunctionThis function is the sole means for object creation. Its result is a scalar object reference. Its right argument, describes the object to be created. The left argument and other forms of the right argument are reserved for future extensions. Used nomadically with a scalar zero argument, MOM returns a reference to the sole instance of the special NIL object. This object has no state or behavior. It can be used as a placeholder or sentinel value. All references to the null object match each other, and do not match any reference to other objects. When the right argument is exactly a vector of character vectors, a new object is created. The character vectors in the argument must be the names of currently visible user defined functions and variables. Copies of the named functions and variables become the initial members of the new object. The object’s state is not changed by subsequent erasure of the named functions and variables. Note well that the argument must be a vector of vectors. An un-nested character vector or a character scalar won’t be accepted. However, empty names are ignored. This statement creates a new empty object. a_new_thing MOM '' '' This one creates an object with four members. StrUtils MOM 'DLB' 'DEB' 'DTB' 'CONTAINS' Temporary limitation:The names in the argument may not contain leading, trailing, or embedded spaces. The MSELF System VariableThis read-only variable returns the object reference for the most recent incomplete invocation of a member function. When no call to a member function is in progress, MSELF yields the special reference to the NIL object. System Functions as MembersSeveral system functions are implicit members of every object. As member functions they refer only to the object’s member functions and variables. Their arguments are analogous to those of the similarly named ordinary system function. Temporary limitation:Only CR and the monadic variant of NL are currently implemented. FX is in progress but not yet operational. The Match FunctionThe APL match function ( ) shows whether two reference values refer to the same object. Some Simple PatternsThese pattern descriptions begin with a description of a situation where use of the pattern may be appropriate. The pattern itself is the prescription beginning with the word “Therefore”. The prescription may be followed by examples and other comments, sometimes including a critique of the resulting situation. More interesting and complex patterns can be found in the literature. Try a google search for “design pattern”. Simple Collection ObjectsYou have an assortment of unstructured and perhaps only loosely related data. Items are needed one at a time in different parts of your program. The data items are stored in individual variables with carefully chosen names. However these names tend to clutter the global environment and the data is not readily handled as a whole. Therefore, maintain the data items as members of a simple collection object. New items can be added as needed and the object represents the collection itself. height17ªwidth37ªbrdrcolor"fuschia"... win_props
MOM'height'
'width' 'brdr_color' ... handle OpenNewWindow win_props Simple collection objects behave a lot like the hash objects in some other languages. At least with the current implementation, you may encounter performance and memory use when the collection is large. Member names share the symbol table, which has a limited number of slots, with ordinary functions and variables. Function Collection ObjectsYou would like to refactor a large and complicated function into a confederacy of smaller functions with intention revealing names. You are concerned that the relation between the new functions will disappear in a multi-screen )fns display. You also need to avoid name collisions with existing and future global functions and want to avoid relying on distracting naming conventions. Therefore, make the new functions members of a single object. You could also group related utility or other functions in the same way. Parameter ObjectsYou want to pass some stuff to a function, perhaps even another function. The usual APL technique is to pass the stuff as items of a nested array. The name of the parametric function would be passed as a character vector with the called function using the (execute) primitive to actually call the function. For this to work, the calling function and called function must agree on the indices of particular items in the passed array. If several functions are involved, each with somewhat different requirements, it may take some effort to establish a consensus. Also note that a numeric index has very little mnemonic value leading to a need for documentation which tends to get out of date when changes are made. Therefore, keep the parametric data and functions in an object’s named members and pass the object to the called function, which may return a complicated result in the same object. The updated object may be passed on to other functions. MonikersYou want to store an object reference in a context that does not allow object references such as a user defined property on a WI or NI object. You can store the name of a global variable, the value of which is the object reference. However, both the object references and the places for storage are created dynamically; and there may be many of them. The name of the global variable itself never needs to be used directly. Therefore, use a utility function, such as MonikerFor from the example workspace, that invents a unique name and creates the global variable by assigning the object reference to the invented name. some.name WI 'udp' (MonikerFor theObjectReference) This property can then be used in a handler: t "(WSELF WI 'udp') , '.method'" some.name WI 'onClick' t A simple implementation might create a new global variable for each use. A more complicated implementation might seek to reuse names or store the object references in an array. In the later case MonikerFor’s result might be something like "MONIKERS[131]". Factory Functions and ObjectsYou want to create multiple similar, but not identical, objects at several places in your program. The necessary code to populate the members is repetitive and distracting. Therefore, isolate this code in a function or object, the sole purpose of which is to create and set up a new object. Large objects, or those that use a number of other objects, may be more conveniently dealt with by several functions encapsulated in an object. The OOP design pattern literature frequently calls these factory objects. Note that the objects created by a particular factory object are analogous to the instances of a class. With duck typing the factory serves as the class definition. When several factory functions are used together in various combinations, we have something like multiple-inheritance. DelegationYou find that you have multiple objects that contain copies of the same member functions. This duplication seems wasteful, but more importantly, if the common function needs to be changed, it will need to be changed in many places. Furthermore, these functions are related and share a common purpose. Therefore, create a single new object that contains the sole copy of the functions. Place an object reference to the new object in each of the original objects. Revise the calls to the duplicated functions to call the member functions of the new object. It may be useful to pass the value of MSELF so that the now remote functions can access members in the calling object. This delegation of responsibility to other objects is used as an alternative to inheritance in some object oriented languages. |
||||||||||||||
| This entire Web site has been dynamically generated by APL+Win Objects™ 6.0 For all questions contact: info@lescasse.com Copyright © 2003-2005 Lescasse Consulting. All rights reserved. |