home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / Apps / DevTools / ClassBuilder / Source / GuidedTour.wsp < prev    next >
Encoding:
Text File  |  1993-01-25  |  10.1 KB  |  291 lines

  1.  
  2.  
  3.                A Guided Tour to CB
  4.  
  5.                   Glen Diener
  6. Center for Computer Research in Music and Acoustics
  7.                 Stanford University
  8.                  Stanford, CA
  9.              grd@ccrma.stanford.edu
  10.  
  11.  
  12. Introduction
  13.  
  14. This is a "guided tour" of Class Builder (CB). CB
  15. is an application designed to give people
  16. a flavour of what a Smalltalk-80-like 
  17. programming environment for the NeXT machine
  18. might look like. It is by no means a complete
  19. system...my hope is that it will stimulate
  20. the imagination of people with more time and ability
  21. than myself to devoting some of their energies to
  22. the creation of a better program development environment.
  23.  
  24. The following takes you on a guided tour through the
  25. capabilities of CB.
  26.  
  27. 1) The workspace
  28.   
  29.    You are currently looking at a workspace.  Think of
  30. it as simply a long piece of paper on which you can
  31. type whatever you want.  In addition, if you select
  32. any text using the mouse, then press the Evaluate button
  33. up in the top left corner ot this window, then
  34. the selected text will be compiled, loaded, executed,
  35. then unloaded.  As an example, select the following 
  36. snippet of C code,  then press evaluate:
  37.  
  38.  
  39. int i,j = 0 ;
  40. for(i = 0 ; i < 100 ; i++)
  41.   j += i ;
  42.  
  43.  
  44. Now, how do you know that the code was executed?
  45. Well, lets add a statement which prints out the
  46. result. CB's application object, referenced through
  47. the global variable "NXApp", understands the
  48. message printf:, which takes a variable number of
  49. parameters.  printf: works just like the printf()
  50. function, except that it always writes its output
  51. into a window called the Transcript.  To see the
  52. Transcript, just go to CB's menu, and click on
  53. Transcript... Now, lets try the previous code example,
  54. but with a printf: statement.  Select and evaluate the
  55. following:
  56.  
  57. int i,j = 0 ;
  58. for(i = 0 ; i < 100 ; i++)
  59.   j += i ;
  60. [NXApp printf: "The answer is %d\n", j] ;
  61.  
  62. The result should have appeared in the Transcript window.
  63. Anthing which is written to the Transcript is simply
  64. concatenated to any existing text.  To clear the transcript,
  65. hit the "Clear" button.  You cannot edit this text,
  66. though you can copy it using Command-C.
  67.  
  68. If there are errors in your program, they will also 
  69. appear in the Transcript window.  For example, evaluate
  70. the following...
  71.  
  72.  
  73. int i ;
  74. j = 0 ;
  75.  
  76. and note the errors and warnings in the transcript.  
  77. It says that on line 2, `j' was undeclared.  Note
  78. that this refers to line 2 of the selected text,
  79. which may be on any line number in your workspace.
  80.  
  81. I hate the way Objective C programs always die when
  82. they don't understand a message.  All Objects in
  83. CB are actually NObjects...NObjects are just like
  84. objects, except that if they don't understand 
  85. something, they pop up a Panel allowing you to
  86. either continue or abort the program.  To illustrate,
  87. evaluate the following:
  88.  
  89. [[[Object new] init] hazanga] ;
  90.  
  91. --and choose "Continue" from the alert panel.
  92. NObjects "pose" as objects, so any object you create
  93. in CB will have this behaviour.  Now, if this were
  94. Smalltalk, an unrecognized message would pop you
  95. into a debugger, where you could examine the stack,
  96. define a new message, etc. etc. Anyone interested
  97. in "grafting" gdb onto CB?
  98.  
  99.  
  100. The code that you write does not get interpreted: it
  101. is compiled, linked, and executed just like any other
  102. C code.  CB accomplishes this by creating a new 
  103. "temporary" class and a single class method, called "doit",
  104. "around" the code you write. This class is compiled,
  105. then loaded, and the class is sent the message "doit"
  106. in order to execute the code. Finally, the class is
  107. unloaded.
  108.  
  109. The temporary class "knows about" the classes 
  110. "Object" and "HashTable", as well as the class
  111. "DictManager" (explained in the next section), 
  112. and the external variable "NXApp".
  113. If you want to send messages to other classes,
  114. two things need to be done. First, the other 
  115. classes must be loaded (this will be explained
  116. later).  Second, a #import "otherclass.h" will
  117. have to be created for each of these other classes.
  118. Workspaces use a special syntax to ensure these
  119. #import directives end up at the top of
  120. the "temporary" class definition they create.
  121. All headers should go between the directives
  122. #header and #endheader. The following example
  123. shows how this is done:
  124.  
  125. #header
  126. #import <appkit/Window.h>
  127. #endheader
  128. id aWindow ;
  129. NXRect aRect = {{100.0,100.0},{400.0,400.}} ;
  130. aWindow = [Window alloc] ;
  131. [aWindow  initContent: &aRect
  132.                        style:NX_TITLEDSTYLE
  133.                       backing:NX_BUFFERED
  134.                       buttonMask:NX_CLOSEBUTTONMASK
  135.                       defer:NO ] ;
  136. [aWindow setTitle: "Created by CB!"] ;
  137. [aWindow display] ;
  138. [aWindow orderFront: self] ;
  139.  
  140. You can create as many workspaces as you want; they will
  141. always have the extension ".wsp".  Workspaces are saved
  142. using the "File/Save" or "File/Save As" menu options.
  143.  
  144. 2) Dictionaries
  145.  
  146. What if you wanted to create an object in one hunk of
  147. ObjC, then reference it in another?  CB has  a built
  148. in dictionary for just this purpose.  Currently, you
  149. can save ids, integers, and strings in the dictionary.
  150. Here is an example of each. Evaluate the following...
  151.  
  152. #header
  153. #import <appkit/Window.h>
  154. #endheader
  155. [DictManager insertKey: "aWindow" value: [Window new] type: "@"] ;
  156. [DictManager insertKey: "hello" value: "hello" type: "*"] ;
  157. [DictManager insertKey: "goodbye" value: "goodbye" type: "*"] ;
  158. [DictManager insertKey: "a" value: 1 type: "i"] ;
  159.  
  160.  
  161. Note that the class DictManager is already known to the workspace,
  162. so you don't need a #import directive for it.  Also note that
  163. you must specify the "type" of the object you are putting into
  164. the dictionary, using the standard ObjC syntax of "@" for objects,
  165. "*" for char *, and "i" for integer.  To see the results of the
  166. above evaluation, choose Dictionary... from the menu, and play
  167. with the browsers you see there.  You can change the values
  168. of the integer and the strings right in the Dictionary Manager,
  169. by typing in the text view below, then hitting the "New Value"
  170. button.  You can't (yet) change the value of an id this way,
  171. however. Any of the three types may be deleted.  The following
  172. code shows how to retrieve values from the dictionary...
  173.  
  174. [[DictManager valueForKey: "aWindow" type: "@"] orderFront: 0] ;
  175.  
  176.  
  177. --this will put a small window in the left-hand corner of your
  178. screen.  To make it go away, evalute the following:
  179.  
  180. [[DictManager valueForKey: "aWindow" type: "@"] free] ;
  181. [DictManager removeKey: "aWindow" type: "@"] ;
  182.  
  183. (The Dictionary Manager does not (yet) update itself automatically
  184. to reflect the fact that the Key "aWindow" was removed).
  185.  
  186.  
  187. 2. The Class Manager
  188.  
  189. Now we get to the real heart of CB: its ability to help create
  190. new classes.  As an introduction, choose "File Open..."
  191. from the file menu, and open the file called "Test.m".
  192. This opens a "Class Manager" window, and displays
  193. the implementation code for the class Test.
  194. Click on the Compile button, then on the Load button, and
  195. class Test is now ready for use! Let's test it out.  Before
  196. you evaluate the following code, you will have to change
  197. the #import statement to point to the directory you have
  198. installed CB in...
  199.  
  200. #header
  201. #import "/local/grd/CB/Test.h" /* Edit this line !!! */
  202. #endheader
  203. [[Test new] howAreYou] ;
  204.  
  205.  
  206. A few points need to be made here.  First, in the file
  207. "Test.m", look at the first line:
  208.  
  209. #pragma .h #import  <objc/Object.h> 
  210.  
  211.  
  212. This line is there because I refuse to write .h files.  
  213. Instead, an awk script scans the .m file and creates
  214. the .h file automatically (you can see the script in
  215. the "compile:" method in ClassManager.m).  There does,
  216. however, need to be a way to put something in the .h
  217. file which is not read by the .m file.  This is the
  218. purpose of the #pragma .h directive. Everything 
  219. after the #pragma .h , up to the next newline,
  220. is copied verbatim (minus the  #pragma .h, of course!)
  221. into the .m file.  Since the compiler does not 
  222. recognize the #pragma .h, it is essentially a comment
  223. in the .m file.
  224.  
  225. Next, note that Test.m imports Application.h.  Unlike
  226. the workspace Evaluation mechanism, where the global
  227. var NXApp is already  known, you must declare it
  228. (normally by including Application.h).  There are
  229. no "implicit" declarations in Class Manager windows.
  230.  
  231.  
  232. There is a Panel in CB which is invoked by the
  233. "Loaded Classes..." menu button.  This panel
  234. displays the names of all the classes which you
  235. have loaded.  It is a scrolling browser in which
  236. individual classes may be selected and unloaded
  237. (Unload Sel), or in which all classes may be
  238. unloaded (Unload All).  The order in which classes
  239. are loaded is important: NeXT's incremental loading
  240. hooks have an unload module call which doesn't
  241. specify which module (in CB, module means class)
  242. to unload! It simply unloads the last one that
  243. was loaded.  So what happens if you load 20 classes,
  244. then want to go back and modify the first one you
  245. loaded?  You have to unload all 20, modify and reload the
  246. first, than reload the remaining 19.  CB does all this
  247. for you, however: you can unload any class you want
  248. at any time.  Be aware, however, if you have placed
  249. an instance of one a class in the dictionary, then you
  250. change a class that was loaded before you loaded that
  251. class, the instance in the dictionary will be stale.
  252.  
  253.  
  254. Finally, here is a more complicated example which uses a nib
  255. file from the interface builder.  A nib file was created,
  256. using Interface Builder, starting by choosing the
  257. "File/New Module..." IB menu option.  Then a window
  258. was dragged from Palettes, and a scrolling text view
  259. placed upon it.  In IB's Classes menu, a subclass of
  260. Object, called IBExample, was created, and the File's
  261. Owner was set to this class in the File's Owner Inspector.
  262. A single outlet, called textView, was created, and the
  263. scrolling text view was "plugged" into it.
  264.  
  265. Now open the file IBExample.m from CB's "File/Open..."
  266. menu.  Compile and load this class, just as we did
  267. above for class Test.  Then evaluate the following:
  268.  
  269. #header
  270. #import <appkit/Application.h>
  271. #import "/local/grd/CB/IBExample.h"
  272. #endheader
  273. id anIBExample ;
  274. [NXApp loadNibFile:
  275.          "IBExample.nib"
  276.         owner: anIBExample = [[IBExample alloc]init] ] ;
  277. [anIBExample setText: "An ambition to squint "
  278.      "at my versus in print\n"
  279.      "Makes me hope for these few you'll find room.\n"
  280.      "If you so condescend, then please sirs, at the end,\n"
  281.      "The name of yours truly,\n\t\t\t L. Bloom\n"] ;
  282.  
  283.  
  284.  
  285. --happy hacking!
  286.  
  287.  
  288.  
  289.  
  290.  
  291.