home *** CD-ROM | disk | FTP | other *** search
- Get Paper Exercises
-
-
- SECTION 1
- ------------------------------------------------------------------------------
-
- 1. What problems exist with using local GetLists to implement nested
- reads?
-
- If routines called from either a when clause, valid clause, or
- hot keys need to access the currently active get objects, they
- cannot simply refer to GetList; it is local to the routine performing
- the nested read. See page 17 and 18 for more detail and suggested
- ways of overcoming it.
-
-
- 2. What's the problem with the following attempt at declaring a local
- GetList for nested reads?
-
- LOCAL GetList
-
- The problem is that the declaration does not declare GetList as an array.
- It creates a variable, getList, whose type is undefined and whose value
- is NIL. Subsequent GET commands, which the preprocessor has translated to
- Aadd(GetList, _GET_(....) ) will thus fail.
-
- You must declare GetList with:
-
- LOCAL GetList := {}
-
-
- 3. What are the advantages of using code blocks for WHEN and VALID clauses?
-
- The blocks are passed the current get object as a parameter. They can thus
- process it without regard for which array it is contained within (see
- 1 above), and there is no problem validating array elements (Section
- 2 discusses how VALID a[i] ... will fail at run-time because of the
- value of i when the valid clause is evaluated).
-
- Another advantage is you can pass the entire array of get objects to
- the valid routine. This avoids the problem with nesting GetList as
- described in exercise 1 in this section.
-
-
- 4. What are the advantages of using teh SetKey function rather than the
- SET KEY command?
-
- The Principles paper discusses this in detail. The advantage here,
- pertaining to the Get object class, is you can pass the entire array
- of get objects to the function, thus avoiding the problems pointed
- out in exercise 1 in this section.
-
-
- SECTION 2
- ------------------------------------------------------------------------------
-
- 2. What is the difference between:
-
- Eval(Get:block)
-
- and:
-
- Get:varGet() ?
-
-
- In most cases, they are the same. Both return the contents of the
- variable or field which is the subject of the Get. The difference,
- however, occurs when the theing being "got", is an element of an array.
- Simply evaluating Get:block will only return a reference to the array;
- Get:varGet(), however, returns the contents of the array, as expected.
- Refer to the section discussing Get:varGet() for more details, and also
- look up its description in Nantucket's Norton Guides file (Note the
- printed documentation does not mention Get:varGet()).
-
-
- 3. How can you write a valid clause to validate the variable entered when
- the variable refers to an array element?
-
- This question refers to the fact that if you issue gets in a loop,
- using arrays to hold variables, the validation clause will fail, as in:
-
- LOCAL aGetVars := {......}
- ...
- DO WHILE i <= Len(aGetVars)
- @ ... GET aGetVars[i] VALID aGetVars[i] > 0
-
- The problem is that when the valid clause is evaluated, during the READ
- command (ReadModal), the value of i is invalid, and the run-time
- system produces a run-time error.
-
- The solution is to specify a code block directly for the valid clause,
- and use Get:varGet(), as in:
-
- @ ... GET aGetVars[i] VALID {|oGet| oGet:varGet() > 0 }
-
- See the section on Get:varGet() for more details, and the section on
- GETs and Arrays for a discussion of how to solve a similar problem with
- WHEN clauses referring to array elements.
-
-
- 4. What does Get:subscript contain when you issue a get on aVar[4]? What
- does it contain when you issue a get on aVar[4, 5].
-
- In the first case it contains {4}, in the second case {4, 5}. In both
- cases, then, get:sunscript contains an array. This is different from
- the documentation in Nantucket's Norton Guides which says if the
- array element you are getting is a single dimension, Get:subscript
- will not be an array. This is incorrect; Get:subscript is always an
- array.
-
-
- 5. Consider the following code block:
-
- {|| Test(&Stri) }
-
- Compile and run this program without linking a function test. Comment on
- the result. When and how does Clipper compile the expression defined by
- the macro operator?
-
- The program links fine without the function Test. This implies that
- the entire code block is compiled at run-time using the macro operator.
- If this were not the case, the compiler would have generated an external
- request for the function Test, and the linker would complain about an
- "Unresolved external".
-
- It appears that Clipper handles macros inside code blocks in three
- different ways:
-
- {|| &i } - Early macro expansion
- {|| &(i) } - Late macro expansion
- {|| more complex expansion } - Whole thing at compile-time
-
- If you do not understand the diffrence between early and late macro expansion,
- refer to the Principles paper
-
-
- SECTION 3
- ------------------------------------------------------------------------------
-
- 1. Why should you pass your array of get objects to WHEN and Valid clauses?
-
- This is so that if you nest reads using a local GetList, your when
- and valid clause routines can refer to the entire list of gets. They
- would be inaccesible, otherwise.
-
-
- 2. What are the problems with using a hard coded subscript to index the
- public GetList array in functions called from WHEN and VALID clauses?
-
- The position of the get may change as you modify the program, and
- the code is difficult to read. A better approach is to search the
- GetList to determine the get number you want.
-
-
- 3. Modify program 8 (on disk as Gets04.prg) to use Get:cargo as a dictionary.
-
- See Getex01.prg
-
-
- 4. Modify program 9 (on disk as Gets05.prg) to only display the prompts
- for the starting and ending page numbers when range is selected
-
- See Getex02.prg
-
-
- 5. How can you implement read only gets? That is, gets that are displayed
- like regular gets but that you cannot change.
-
- This is easy. Simply create a WHEN clause containing a false!
-
-
- SECTION 4
- ------------------------------------------------------------------------------
-
- 2. What does ReadModal return?
-
- It returns whether any gets were updated during the read. Thus, you
- can replace:
-
- READ
- IF Updated()
- ...
-
- with:
-
- IF ReadModal(GetList)
- ...
-
- if you really want to! Don't forget to clear GetList somewhere,
- however.
-
-
- 3. How does the read system handle the stacking of static variables when
- you call ReadModal recursively during a nested read?
-
- Upon entry, Readmodal calls ClearGetSysVars to save and clear the
- static variables, and before returning it calls RestoreGetSysVars
- to restore them. ClearGetSysVars returns an array containing the
- current values of the statics, and ReadModal saves this in a LOCAL
- variable, saveGetSysVars. It passes this local variable to
- RestoreGetSysVars. The important point here is this saved array
- is local. Thus, Clipper's run-time system is perform the stacking.
-
-
- 4. Where is the cursor positioned after a READ command? Why is this?
-
- It is positioned on the last but one row, at column 0 (!). This is
- for compatability with Summer '87, apparently!
-
-
- 5. How can you change the default read system so that ReadVar includes
- subscripts when the get variable is an arrau element?
-
- Compile getsys defining the symbol SUBSCRIPT_IN_READVAR, and uncomment
- the conditional compilation in GetReadVar().
-
-
- 6. What does the default read system do with the Ctrl-w key? How about
- Ctrl-End? Can you change this behaviour?
-
- Getsys is programmed so that both these keys terminate the READ.
- You can change this so they both go to the last get, by compiling
- Getsys defining the symbol CTRL_END_SPECIAL.
-
-
-
- SECTION 6
- ------------------------------------------------------------------------------
-
- 1. Implement a reader for dates that allows the user to use the + and -
- keys to increment and decrement the date field or variable.
-
- See Getex03.prg
-
-
- 2. Write a get reader that invokes a code block after each key. It should
- pass the block the current get object. Write a block that uses a TBrowse
- object to display records matching the current variable or field. This
- way, as the user enters characters, he or she automatically sees the
- matching records.
-
- See Getex04.prg
-
-
- 3. Modify the GoToGet function so that the programmer can pass a get's
- name rather than number
-
- See Getex05.prg
-
-
- 4. As you know, the user can leave a read just by pressing an Esc key,
- regardless of whether any gets have unsatisfied valids or not. Write
- a READ command that only allows the user to exit if all valid clauses
- are satisfied.
-
- See Getex06.prg