home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / CLIPPER / CLIPTIPS.ZIP / CODEBLOC.ZIP / CBEASY.TXT
Text File  |  1990-08-15  |  9KB  |  125 lines

  1. *╔═══════════════════════════════════════════════════════════════════════════╗*
  2. *║   System Name:   CODE BLOCK DEMONSTRATION SUITE                           ║*
  3. *║   Module Name:   CBSTART.TXT                                              ║*
  4. *║   Description:   Shows how easy code blocks are to understand.            ║*
  5. *║   Author.....:   Micheal Todd Charron                                     ║*
  6. *║   Date.......:   Oct. 23, 1990                                            ║*
  7. *║   History....:   Thought up, on a Train to Montreal                       ║*
  8. *╚═══════════════════════════════════════════════════════════════════════════╝*
  9.  
  10. ┌─────────────────────────────────────────────────────────────────────────────┐
  11. │    bBlock := { | p1, p2 | DEVPOS( p1, 0 ),  cOutString := ( p2 +;           │
  12. │              ' ' + LTRIM( STR( p1 ) ) ), DEVOUT( cOutString ),;             │
  13. │              DEVPOS( p1, 8 ), DEVOUT( REPLICATE( ' .', 35 ) ),;             │
  14. │              ( p1 % 3 == 0 ) }                                              │
  15. └─────────────────────────────────────────────────────────────────────────────┘
  16. The code above is a Code Block.  If you don't have trouble understanding it,
  17. please read no further.  If your like me, you looked at these things for maybe
  18. three weeks not understanding them one bit.  Then another two months was
  19. spent with hesitation wondering if the one you just typed in was in the right
  20. format.
  21.  
  22. Then one day on a train to Montreal I began to wonder what was the best way to
  23. explain Code Blocks to a User Group.  I figured that the best way to start was
  24. to help them look at them in a way that was very familiar.
  25. ┌─────────────────────────────────────────────────────────────────────────────┐
  26. │    bBlock := {;                                                             │
  27. │               | p1, p2 |;                                                   │
  28. │               DEVPOS( p1, 0 ),;                                             │
  29. │               cOutString := ( p2 + ' ' + LTRIM( STR( p1 ) ) ),;             │
  30. │               DEVOUT( cOutString ),;                                        │
  31. │               DEVPOS( p1, 8 ),;                                             │
  32. │               DEVOUT( REPLICATE( ' .', 35 ) ),;                             │
  33. │               ( p1 % 3 == 0 );                                              │
  34. │            }                                                                │
  35. └─────────────────────────────────────────────────────────────────────────────┘
  36. By the way, DEVPOS() and DEVOUT() are new functions in Clipper 5.0/5.01.
  37. DEVPOS() positions the cursor on the screen.  DEVOUT() will display the value
  38. of its parameter at the current cursor position.
  39.  
  40. The Code Block above is a little easier to read and it also shows how similar
  41. Code Blocks are to User Defined Functions.  In fact, we could actually take this
  42. one step further and transform this Code Block to:
  43. ┌─────────────────────────────────────────────────────────────────────────────┐
  44. │     FUNCTION fName                                                          │
  45. │          PARAMETER  p1, p2                                                  │
  46. │               DEVPOS( p1, 0 )                                               │
  47. │               cOutString := ( p2 + ' ' + LTRIM( STR( p1 ) ) )               │
  48. │               DEVOUT( cOutString )                                          │
  49. │               DEVPOS( p1, 8 )                                               │
  50. │               DEVOUT( REPLICATE( ' .', 35 ) )                               │
  51. │      RETURN   ( p1 % 3 == 0 )                                               │
  52. └─────────────────────────────────────────────────────────────────────────────┘
  53.  
  54. As you can see there is little difference between a Code Block and a User
  55. Defined function.  In fact, they have been referred to as Unnamed Functions.
  56.  
  57. Even the simplest Code Blocks can be converted into this format:
  58. ┌─────────────────────────────────────────────────────────────────────────────┐
  59. │   { || 'just a string' }                         // Code Block              │
  60. │ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - │
  61. │   FUNCTION Userfunc                              // User defined function   │
  62. │   RETURN ( 'just a string' )                                                │
  63. └─────────────────────────────────────────────────────────────────────────────┘
  64. ┌─────────────────────────────────────────────────────────────────────────────┐
  65. │   { | p | p + 1 }                                // Code Block              │
  66. │ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - │
  67. │   FUNCTION Userfunc( p )                         // User defined function   │
  68. │   RETURN ( p + 1 )                                                          │
  69. └─────────────────────────────────────────────────────────────────────────────┘
  70. ┌─────────────────────────────────────────────────────────────────────────────┐
  71. │   { | x, y | SQRT( x ) + SQRT( y ) }             // Code Block              │
  72. │ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - │
  73. │   FUNCTION Userfunc( x, y )                      // User defined function   │
  74. │   RETURN ( SQRT( x ) + SQRT( y ) )                                          │
  75. └─────────────────────────────────────────────────────────────────────────────┘
  76. ┌─────────────────────────────────────────────────────────────────────────────┐
  77. │   { | a, b, c | Myfunc( a ), Myfunc( b ), Myfunc( c ) }   // Code Block     │
  78. │ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - │
  79. │   FUNCTION Userfunc( a, b, c )                   // User defined function   │
  80. │             Myfunc( a )                                                     │
  81. │             Myfunc( b )                                                     │
  82. │   RETURN Myfunc( c )                                                        │
  83. └─────────────────────────────────────────────────────────────────────────────┘
  84. Always remember that the variables between the vertical lines (||) are the
  85. parameters for the Code Block and the last expression in the Code Block
  86. determines the value returned from the Code Block.  If you run into trouble
  87. with Code Blocks, convert them into User Defined Functions and work them out.
  88.  
  89. The last paragraph presents a question that I get asked constantly, "Why use a
  90. Code Block instead of a User Defined Function?"  A good rule to follow is that
  91. you should use a User Defined Function unless the overhead of creating and
  92. calling a UDF are greater than that of a Code Block.  But alas there are times
  93. when a Code Block must be used such as with Clipper 5.0's Objects Oriented
  94. Classes.
  95.  
  96. The three companion programs CBMULTI.PRG, CBSAVE.PRG and CBRESTOR.PRG show a
  97. couple of uses of Code Blocks.  Please take a look at them.
  98.  
  99. *******************************************************************************
  100.  
  101. I don't want to confuse this discussion but I would like to take a second to
  102. explain something before you move on.
  103. ┌─────────────────────────────────────────────────────────────────────────────┐
  104. │    bBlock := { | p | p + 1 }                                                │
  105. └─────────────────────────────────────────────────────────────────────────────┘
  106. In the code above we created a simple Code Block.  Then we assigned the
  107. reference to that Code Block to the variable "bBlock".  The Code Block's name
  108. is not 'bBlock'.
  109. ┌─────────────────────────────────────────────────────────────────────────────┐
  110. │    bNewBlock := bBlock                                                      │
  111. └─────────────────────────────────────────────────────────────────────────────┘
  112. Both variables, "bNewBlock" and "bBlock", now contain the same reference to the
  113. Code Block that was created previously.  Now do you see why they call them
  114. `Unnamed Functions'?
  115. ┌─────────────────────────────────────────────────────────────────────────────┐
  116. │    ?  EVAL( bNewBlock, 3 )                       // Result: 4               │
  117. └─────────────────────────────────────────────────────────────────────────────┘
  118. Calling the above EVAL() function will pass the Code Block's reference into the
  119. EVAL() function.  Now that the EVAL() function has the reference, it can find
  120. the location of the Code Block and evaluate it.
  121.  
  122. I hope that didn't confuse you.  Especially since it is time to move on.
  123.  
  124. *******************************************************************************
  125.