Lescasse Consulting
 Home    Company    News    Prices    Download    Buy    Forums   
Read Me
Buy
Forums
Resume
AntiSpam 1.2
wBackup 1.11
NetAccess 2.0
Visual APL 1.0 
APL+Win 8.0 
APL+Win Products 
APL+Win Objects™ 
APL+Win Training 
APL+Web Services
APL+Web Component 
APL+ History
Dyalog.Net Tutorial
Conferences 
Powerpoint
White Papers
Web Hosting
References
Links
 
APL+Win Objects™ 6.0

TADO5
TADO5 Tutorial
TAPLDraw5
TAPLEdit5
TAPLSession5
TAbale5
TAboutBox5
TAccess5
TAgent5
TBlatMail5
TButton5
TCDO5
TCRC5
TCancelButton5
TCheck5
TCheckGroup5
TChildForm5
TChooseColor5
TChooseFont5
TClipBoard5
TClock5
TCodeStats5
TColors5
TCombo5
TComboDrive5
TComboFilter5
TComboList5
TComboTree5
TCommandBar5
TCommandButton5
TControlClass5
TCueCard5
TDHTML5
TDHTMLEditor5
TDateTime5
TDateTimeFr5
TDates5
TDemoHandlers5
TDisplay5
TDOS5
TDualSelect5
TEdit5
TEditAmount5
TEditDir5
TEditEnter5
TEditFile5
TEditGrid5
TEditList5
TEditListview5
TEditMenu5
TEditNum5
TEditSelect5
TEditSpin5
TEmail5
TError5
TExampleForm5
TExcel5
TExcel5 Tutorial
TFindReplace5
TFOne5
TFTP5
TFTP5 Tutorial
TFileCompare5
TFileMenu5
TFileMenuDef5
TFlatButton5
TForm5
TFormClass5
TFormEditor5
TFrame5
TGetDir5
TGif5
TGifForm5
TGifWb5
TGoMenu5
TGraphX5
TGrid5
TGridDisplay5
TGridPrint5
TGUID5
THLine5
THTML5
THTML5 Tutorial
THTTP5
THelp5
THelpMenu5
TImagelist5
TInfo5
TIniFile5
TInstall5
TInternet5
TJpg5
TJpgWb5
TLabel5
TList5
TListview5
TLock5
TLogs5
TMAPI5
TMath5
TMDIForm5
TMSOutlook5
TMaskEdit5
TMedia5
TMenu5
TMessage5
TModalCall5
TMsgBox5
TNavigator5
TNetwork5
TNonVisualClass5
TODBC5
TOKButton5
TObject5
TOpenFile5
TOption5
TOptionGroup5
TOutlook5
TOutlookMail5
TOWCSpread5
TPDF5
TPFKeys5
TPage5
TPassword5
TPicture5
TPing5
TPopupMenu5
TPowerpoint5
TPowerpoint5 Tutorial
TPrinter5
TProgress5
TProgressDlg5
TQuestion5
TRegistry5
TRegistryKey5
TResource5
TRichEdit5
TSPX5
TSQLDMO5
TScheduler5
TScroll5
TSelector5
TSpinner5
TSplitter5
TStatus5
TStopWatch5
TTest5
TTestError5
TTextFile5
TTimer5
TTip5
TTipForm5
TTLI5
TToolBar5
TToolbox5
TToolsMenu5
TTrackbar5
TTranslate5
TTree5
TVLine5
TViewMenu5
TWebBrowser5
TWebServer5
TWebSite5
TWebSiteNet5
TWinMenu5
TWord5
TYesNo5
    Visits:  1267 (59 on line) Last Update: Dec 21, 2005  
    APL+Win 6.0 ŒMOM Object System    Printer Friendly  
Introduction to the MOM Object System


This article presents 3 examples I have built during the APL2000 Conference, showing how to use the new ŒMOM Object Oriented System Function in APL+Win 6.0. Each of these example correspond to one of the Design Patterns identified by Bill Rutiser in his paper (partly reproduced below).

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:

’ SimpleCollections A;Z;text [1] ©’ SimpleCollections -- This example builds a form and save all form children values into an object [2] ©’ which members have the same name as the form controls [3] ©’ i.e. if an form Edit control is named 'ff.ed2', member ff.ed2 of the ff object contains the "ff.ed2" control content [4] [5] :select A [6] :case'' © Constructor [7] Z„'ff'Œwi'*Create' 'Form'('scale'5)('caption' 'A + B = C')('size'81 210) [8] Z„'ff'Œwi'*.ed1.Create' 'Edit'('where'5 5 21 200)('onChange' 'SimpleCollections"ed.onChange"') [9] Z„'ff'Œwi'*.ed2.Create' 'Edit'('where'31 5 21 200)('onChange' 'SimpleCollections"ed.onChange"') [10] Z„'ff'Œwi'*.ed3.Create' 'Edit'('where'56 5 21 200)('enabled'0) [11] SimpleCollectionObjects'ff' [12] Z„'ff'Œwi'Wait' [13] :case'ed.onChange' [14] –Œwself,'„†Œfi Œwi"text"' [15] Z„Œwi'..ed3.text'(•ff.ed3„ff.ed1+ff.ed2) [16] :endselect ’ ’ SimpleCollectionObjects container;children;child;i [1] children„container Œwi'*children' [2] –container,'„Œmom"" ""' [3] :for i :in¼½children [4] child„iœchildren [5] –child,'„0' [6] :endfor ’
SimpleCollections''

 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.

’ FunctionsCollection A;Z;text [1] ©’ FunctionsCollection -- This example builds a form and save all form handlers in a function collection of objects [2] ©’ i.e. if an form Edit control is named 'ff.ed2', member ff.ed2 of the ff object contains the "ff.ed2" control content [3] [4] :select A [5] :case'' © Constructor [6] Z„'ff'Œwi'*Create' 'Form'('scale'5)('caption' 'Functions Collection Object')('size'81 410) [7] Z„'ff'Œwi'*.ed1.Create' 'Edit'('where'5 5 21 400) [8] Z„'ff'Œwi'*.ed2.Create' 'Edit'('where'31 5 21 400) [9] Z„'ff'Œwi'*.ed3.Create' 'Edit'('where'56 5 21 400) [10] FunctionsCollectionObject'ff' [11] Z„'ff'Œwi'Wait' [12] :endselect ’ ’ FunctionsCollectionObject object;children;ed1_onChange;ed2_onChange;ed3_onChange;fn;Œwself [1] [2] Œwself„object [3] [4] Œwi'.ed1.onChange'(object,'.ed1_onChange') [5] fn„›'ed1_onChange' [6] fn„fn,›'© line 1' [7] fn„fn,›'© line 2' [8] fn„fn,›'Œ„"ed1: ",Œwi"*text"' [9] fn„fn,›'Œwi":ed3.text"(•(†Œfi,Œwi":ed1.text")+†Œfi,Œwi":ed2.text")' [10] fn„Œdefœfn [11] [12] Œwi'.ed2.onChange'(object,'.ed2_onChange') [13] fn„›'ed2_onChange' [14] fn„fn,›'© another handler' [15] fn„fn,›'© concerning Edit object ed2' [16] fn„fn,›'Œ„"ed2: ",Œwi"*text"' [17] fn„fn,›'Œwi":ed3.text"(•(†Œfi,Œwi":ed1.text")+†Œfi,Œwi":ed2.text")' [18] fn„Œdefœfn [19] [20] Œwi'.ed3.onChange'(object,'.ed3_onChange') [21] fn„›'ed3_onChange' [22] fn„fn,›'© another handler' [23] fn„fn,›'© concerning Edit object ed3' [24] fn„fn,›'Œ„"ed3: ",Œwi"*text"' [25] fn„Œdefœfn [26] [27] –object,'„Œmom"ed1_onChange" "ed2_onChange" "ed3_onChange"' ’
FunctionsCollection''

 Third example: Factory Functions and Objects

In this example, we create a small database made of ŒMOM person objects.

Our factory build person objects (PersonsFactory) and then children objects (ChildrenFactory).

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:

  • the personMethods generic ŒMOM object
  • the local version of Age and FullName

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

’ FamilyFactory [1] PersonsFactory [2] ChildrenFactory ’ ’ PersonsFactory [1] PersonMethodsFactory [2] person1„PersonFactory'Lescasse' 'Eric'1951 [3] person2„PersonFactory'Thevenin' 'Bruno'1958 ’ ’ PersonMethodsFactory [1] personMethods„Œmom'Age' 'FullName' ’

’ Z„Age birthyear
[1] Z„Œts[Œio]-birthyear


’ Z„FullName A
[1] Z„(1œA),' ',2œA

’ person„PersonFactory A;Z;Age;FullName [1] ©’ Building a Œmom object [2] [3] © Function delegations [4] © The following function stored in each object are delegates for functions of the same name [5] © saved in the object [6] Z„Œdefœ'Z„Age;personMethods' 'personMethods„Œmself.personMethods' 'Z„personMethods.Age Œmself.birthyear' [7] Z„Œdefœ'Z„FullName;personMethods' 'personMethods„Œmself.personMethods' 'Z„personMethods.FullName Œmself.fname Œmself.name' [8] [9] © Create a person object [10] person„Œmom'personMethods' 'Age' 'FullName' [11] person.name„1œA [12] person.fname„2œA [13] person.birthyear„3œA [14] person.ischild„0 ’ ’ ChildrenFactory [1] person1.child1„ChildFactory'Lescasse' 'Marie-Eglantine'1990 [2] person2.child2„ChildFactory'Thevenin' 'Kevin'1991 [3] person2.child3„ChildFactory'Thevenin' 'Yann'1995 ’ ’ child„ChildFactory A [1] child„PersonFactory A [2] child.ischild„1 ’
FamilyFactory''
person1.Œnl 2
birthyear child1 fname ischild name
person1.Œnl 3
Age FullName
person2.Œnl 2
birthyear child1 child2 fname ischild name
person1.name
Lescasse
person1.fname
Eric
person1.FullName
Eric Lescasse
person1.birthyear
1951
person1.Age
54
person1.child1
<<<Object Reference>>>
child1„person1.child1 child1.name
Lescasse
child1.Age
15
child1.FullName
Marie-Eglantine Lescasse
child2„person2.child2 child3„person2.child3 child2.FullName
Kevin Thevenin
child3.FullName
Yann Thevenin

Object Oriented Programming in APL+Win

William Rutiser
Copyright © 2005 APL2000

Introduction to the MOM Object System

Elevator description

The 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
every object; they refer only to an object's members. So, just as ŒNL 3 gives a list of the functions in the workspace, MyThing.ŒNL 3 gives a list of the functions in the object referred to by the variable MyThing.

(...)

Reference

The ŒMOM System Function

This 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 Variable

This 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 Members

Several 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 Function

The APL match function ( ­ ) shows whether two reference values refer to the same object.

 

 


Some Simple Patterns

These 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 Objects

You 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 Objects

You 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 Objects

You 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.

Monikers

You 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 Objects

You 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.

Delegation

You 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.