333 Library: Understanding libraries

VERSIONS: All ? - written for Paradox 5
SUBJECT: Understanding libraries
BY: William Hannan

Everyone is different, but 3 things it took me awhile to get a handle on with libraries are:

1. SELF--- the library treats the object that called it as SELF if a form calls the library then self.someField refers to someField on the form. This can save a lot of parameter passing

It is the UIObject that makes the call to the library that is SELF from the libraries point of view
if----- myLib.doSomeThing(whatEver) ---- is in a field's method then that field is SELF, if it is in a form level method then the form is SELF

If the only UIObject I need access to from the library is the UIObject(or objects it contains) that needs the function executed I call the library function from that UIObject. If however I need access to other UIObjects I may have a UIObject with broader containership call the library.

For example:
If the library function needs access to "field1" and "field2" and some event occurs that would cause a "field1" method to use "myLib.doSomeThing(whatEver)" I might have "field1" use a custom method on the page or form to call the method in the library. The page or form method may only contain only one line of code the "myLib.doSomeThing(whatEver)" but I have effectively pushed the containership level of SELF in the library up to the point that "self.field1" and "self.field2" are valid in the library. This gives me access to all the properties of the UIObjects without the need to pass them as parameters in the function prototype.

2. you can pass a tCursor as a variable
someFunction(var myTc tCursor)
now the library has the same tCursor with filter, links or whatever intact no need to open a new one

3. If you need to pass an array first you need to define it as a custom type and pass it as the custom type


BY: Gary Harvey
Believe it or not, for a neophyte like me, I have found a simpler way to do this in one of the Paradox books I bought. You can define a form in a library:
var 
   pForm form 
endvar
then create a method in the library named AttachToForm:
method AttachToForm()
  pForm.attach()
endmethod
Then put a uses statement in the calling form:
Uses ObjectPal
AttachToForm()
enduses
Then execute this statement from the calling form:
extLib.AttachToForm()
The library then knows which form called it and you can then refer to any object on the form from the library, such as
pForm.fieldname = libraryVar

I've done this on a library opened PrivateToForm and it works fine. I haven't tried it yet on a library opened GlobalToDesktop, though.

Does this seem simpler to you than using "self"? It does to me, but I'm only beginning to understand libraries and can easily have missed something.


BY: Mike Irwin

Libraries are pretty easy once you master a few basics, including:
  1. A library is just an extension of the code of the form that calls it.
  2. You give the calling code a template of the library methods you want it to use (the Uses section) so you can compile a form or script _before_ the library it references yet exists. Templates just let the compiler know what to check for, so typo's can be caught at compile time, rather than 6 months from now at run time!
  3. Libraries have Methods and Procedures. Methods are visible from outside; Procedures are not.
  4. You can have two libraries linked to the same form with a method of the same name, and determine which to use at runtime by dynamically selecting the library from which to invoke the method. Unfortunately, both versions of the method MUST have exactly the same template definition.
  5. If you open a library, you are opening a logical link to that library, and invoking its open() method. That library will remain open and in memory for as long as something (script, form, report, or another library) maintains a link to it. When all links are gone, the library closes, and all information that has been stored within it in global variables will be lost (unless you _make_ it persistent by writing it all to disk !).
  6. If you open library B from library A's open() method (or a method or procedure invoked from the open()) then don't do the reverse! What will happen is that B will open to A while A is part-way through opening itself the first go 'round. The result here is that A's first open() will be halted waiting on B's open(), and B's will be waiting on A's _second_ run of the open() method, at which point the whole thing starts again ... This is known as Recursion, and recursion without an explicitly defined way of finishing will continue forever (i.e. until the system runs out of memory and dies!).
There are lots of other things to say about libraries, but bear these in mind and have fun.


BY: Mandy Whalen

When code within a library method wants to refer to objects within the form that calls it, alternatives are:
  1. PRECEDE BY ".SELF". If you want to refer to objects within the container from which the code was called, just precede the names by "self.". For example, if library method was called from:
    FLD_X, self.color, self.value, etc. would refer to properties of field x.
    BOX_A, self.xxx refers to properties of the box. if it contains fields fld_1, fld_2 and fld_3, you can refer to self.fld_1.xxx
  2. PASS UIOBJECT. If you want the method to refer to an object other than the container from which the code was called, then you need this type of code:

    CALLER:
    var
    uiTarg UiObject
    endvar
    eventInfo.getTarget(uiTarg) ; get target for current event
    libX.methodX(uiTarg) ; pass UIobject var of target

    CALLED:
    methodX can refer to uiTarg. class, color, value, etc.
  3. ATTACH FORM. Within the library method, issue a form variable "attach" with a blank operand, to point to current active form variable; then the method can refer to any properties of the current form or objects within it.

To index