Category : Dbase (Clipper, FoxBase, etc) Languages Source Code
Archive   : FAQ.ZIP
Filename : FAQ100.2

 
Output of file : FAQ100.2 contained in archive : FAQ.ZIP
Archive-name: clipper-faq/part2
Last-modified: 1992/12/01
Version: 1.00


FREQUENTLY-ASKED-QUESTIONS (FAQ) LIST FOR CLIPPER
PART 2 OF 3
Copyright (C) 1992 by Mark W. Schumann

======================================================================
SHOPPING FOR CLIPPER AND THIRD-PARTY PRODUCTS.
======================================================================

Q. Where can I buy Clipper and third-party software products?

A. One of the more complete mail-order catalogs for PC programmers
is from The Programmer's Shop. They can be called from the United
States at 800-421-8006, from Canada at 800-446-3846, or
internationally at +1 617-740-2510. The Programmer's Shop accepts
VISA, MasterCard, and personal checks in US dollars drawn on a US
bank. As of this writing Clipper 5.01 costs US $570.00 there.

This is not an endorsement of any distributor or retailer.

As of May 1992 I have been informed that CA/Nantucket (then
Nantucket) offers discounts on Clipper 5 for personal use of
faculty, staff, and students of colleges and universities, as well
as discounts for the institutions themselves. For more
information, contact CA/Nantucket and ask about their Higher
Learning Program.

# Mike Leach, Morehead State University
23-May-92

----------------------------------------------------------------------

Q. Where can I get a copy of Clipper Summer '87?

A. Generally, nowhere that you can count on. The best advice is
to watch the CLIPPER Forum on Compuserve for any offers to
transfer a license on a new or used copy. Neither CA/Nantucket
nor its major resellers is selling Summer '87 anymore.

I have heard from CA representatives that CA/Nantucket allows use
of Clipper Summer '87 on the same CPU for which Clipper 5 is
already licensed. I have also heard to the contrary, also from
CA. Use at your own risk.

----------------------------------------------------------------------

Q. Third-party libraries cost too much. Where can I get a good
cheap library?

A. The Nanforum Toolkit originated in November 1990 when a number
of Clipper developers on Compuserve felt the same way and started
to develop their own public domain, user supported library. You
can get started by downloading NFREAD.ME (about 1K) from
Compuserve's CLIPPER forum Library 7, or from Simtel's directory
PD:.


======================================================================
TECHNIQUES.
======================================================================

Q. What are LOCAL variables and why do I care?

A. LOCAL variables are somewhat like PRIVATE variables in that they
do not "scope up"; if you declare a PRIVATE or LOCAL variable in
function B which is called from function A, then function A does
not know the variable exists. Function A is even free to use the
same name for a different variable entirely without risk of
confusion. This is useful for writing functions that can avoid
"stepping on" the variables that are floating around a larger
application.

LOCAL variables, introduced with Clipper 5.0, enforce a stricter
kind of modularity. A LOCAL variable must be declared, and it
is visible only to the particular function in which it is
declared. (Remember that PRIVATEs are created by default.) Not
only does a LOCAL variable refrain from "up-scoping" but it also
will not "down-scope" either.

For example:

// LOCAL1.PRG
FUNCTION caller
LOCAL a
PRIVATE x, y
a := "a"
x := "ABC"
y := "123"
? a, x, y // Prints "a ABC 123"
callee()
? a, x, y // Prints "a ABC 456"
RETURN NIL

FUNCTION callee
LOCAL a
PRIVATE x // Notice y not declared PRIVATE!
x := "DEF"
y := "456"
? a, x, y // Prints "NIL DEF 456"
RETURN NIL


The values of (a) in the two functions are completely
independent of each other, because they are indeed two
separate variables. The values of (x) in the two functions
are also separate and independent, because CALLEE() has declared
its version of (x) PRIVATE. There is only one (y) variable,
however, since CALLEE() has neglected to declare it.

LOCAL variables are useful for writing code that is guaranteed
bulletproof regardless of the application environment. LOCAL
variables (and their cousins, the STATICs) are immune from having
their values changed by unrelated underlying functions. This cuts
down on maintenance and debugging while offering some speed
advantages too.

----------------------------------------------------------------------

Q. What are STATIC variables and why do I care?

A. STATIC variables are similar to LOCALs in that they do not
"up-scope" or "down-scope." STATICs, however, keep their value
throughout the duration of the program, even when they are not
"visible." For example:

// STATIC1.PRG
FUNCTION caller
LOCAL i
? "BEGIN"
FOR i := 1 TO 100
? "Loop number ", i
callee()
NEXT
? "END"
RETURN NIL

FUNCTION callee
LOCAL l := 0
STATIC s := 0
l++
s++
? l, s
RETURN NIL


The output will look like this:

BEGIN
Loop number 1
1 1
Loop number 2
1 2
Loop number 3
1 3
Loop number 4
1 4
... ...
Loop number 100
1 100
END

Notice that each iteration of the loop increments the value of (s)
from the previous iteration, while the value of (l) starts all over
again from scratch.

The most common use of STATIC variables is to maintain values that
are useful to a group of functions, or to the whole application,
without resorting to global PRIVATE or PUBLIC variables. (See next
Question.)

----------------------------------------------------------------------

Q. I heard that you should use STATIC variables instead of PUBLICs at
all times, but I can't figure out how to make the switch. I have
_lots_ of variables that have to be available to the whole
application. Currently they are PUBLIC. I realize this may not
be a very modular concept, but what else to do?

A. Pull these variables in logical groups (e.g., all colors in
one place) into separate source files and declare them STATIC.
Then write a function or set of functions which allow you to get
(and optionally set) the values of these variables. For example,
COLORS1.PRG will return the current value of the cNormal variable,
and will also set the variable if you pass it a value.

// COLORS1.PRG
STATIC cNormal
FUNCTION setnorm (x)
LOCAL cRet := cNormal
IF x != NIL
cNormal := x
ENDIF
RETURN cRet


If you have more than a few of these variables to get and set this
may present a problem; the source and object code for these functions
will quickly grow out of hand! So let's take it one step further by
hiding this batch of functions with the preprocessor.

// COLORS2.PRG--Link this into your application.
// Colors: 1 Normal 2 Error Message 3 Prompt 4 F-key legend
STATIC acColor[4]
FUNCTION setstdcol (x, y)
LOCAL cRet := acColor[x]
IF y != NIL
acColor[x] := y
ENDIF
RETURN cRet

// APP.CH-- #include this in all your application's source files.
#xtranslate setnorm () => setstdcol (1, )
#xtranslate seterr () => setstdcol (2, )
#xtranslate setprompt () => setstdcol (3, )
#xtranslate setfkey () => setstdcol (4, )

With this set of directives and the single function setstdcol()
you can keep the size of your sources and EXE down. At the same
time the application programmer (you or someone else) can have a
stable interface to this array of values no matter how large the
application gets or how many new elements you want to add to the
array.


----------------------------------------------------------------------

Q. What are the ground rules for using LOCALs and STATICs?

A. LOCALs and STATICs must be the first statements in a function,
except possibly for the PARAMETERS statement. They may be
declared with initial values (e.g. LOCAL a := 1), but STATICs may
not be initialized with a value that is unknown to the compiler
(e.g. STATIC b := myfunc() is invalid). The initialization is
performed every time the function is called (in the case of
LOCALs) or once at the beginning of the program (in the case of
STATICs).

If you want to use a file-wide STATIC variable to share information
among functions within the same source module, that module must be
compiled with the /n switch, and the STATIC declarations must
precede the first FUNCTION or PROCEDURE.


======================================================================
LINKERS AND OVERLAYING.
======================================================================

Q. Running my Clipper Summer '87 code, I keep getting an "Out of
Memory" error, but CHKDSK says I have plenty.

A. Either upgrade to Clipper 5, or get Blinker, or do both. Clipper
5, given a reasonable amount of free conventional memory, can swap
memory to disk, or to memory above the first megabyte if you have
it. Blinker will not only overlay all your Clipper code, but it is
able to do it on a per-function basis. It also comes with a few
memory-packing functions which allow you to request extra memory
when you might need it most.


----------------------------------------------------------------------

Q. I am using Blinker but I still get "Out of Memory" after running
the Summer '87 application for a while. What else can I try?

A. Well first, I told you to get Clipper 5. If you simply must
continue using '87, then email Savannah Brentnall of CA/Nantucket
at 72711,3556 on Compuserve to request a printed copy of
"Memory Management in Clipper Summer '87." Between that document
and a special report from the "Reference (Clipper)" journal,
two outstanding warnings are:

* Don't create variables with PRIVATE &FOO or &FOO = VALUE
unless you have somewhere else in the program declared those
variables so the compiler knows about them. The memory Clipper
must allocate to make these variables is *never* recovered
at any time during program execution.

* Try really hard to avoid PUBLIC variables. If you must use them,
avoid declarations outside of the main top-level routine. If
you can't avoid even this, then at least declare PUBLIC variables
at the very beginning of a procedure or function.

# (I lost the name of the contributor of this Q&A. Acknowledged
anyhow.)



  3 Responses to “Category : Dbase (Clipper, FoxBase, etc) Languages Source Code
Archive   : FAQ.ZIP
Filename : FAQ100.2

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/