Cincom

Web Log Stats Lesson 7
The System Browser 101


| Table of Contents | Lesson 6 | Lesson 8 |


Everything you have accomplished so far has been done using existing Smalltalk objects and their methods in a workspace. However, to really take advantage of the Smalltalk development environment, in order to make the code do more, you need to create your own objects and methods.

This lesson explains how to use the System Browser in order for you to create your own packages, classes, protocols and methods. By the end of this lesson, your code to view web hits for a given directory of log files will work just as it did in the previous lesson. However, your code will be in a more efficient, powerful and re-usable format.

Moving code from a Workspace to the System Browser (where you will have your own classes and methods) requires some tweaking. This is necessary in order for the code to execute properly. This lesson covers that procedure.

1. From the main VisualWorks Launcher window, click the fourth button on the Toolbar or select the menu option Browse >> System.


Figure 7-1. The System Browser Toolbar Option


Figure 7-2. The System Browser

A window will appear with Packages in the title, which is a bit misleading. The dialog you are looking at is called the System Browser and by default, it displays packages that currently exist in your VisualWorks library. You don't know it yet, but this is the most powerful tool in the Smalltalk development environment. Although it is not the best analogy (nor is it a fair one), the System Browser can be compared to what other developnment languages call an IDE (Integrated Development Environment). It is THE main tool used by Smalltalk developers. Because it is so powerful, there's way too much to explain at this stage so we will proceed right to the steps we need for now. However, if you would like to learn more a little more about this tool, you can view the System Browser primer.

Proceed to the System Browser primer.

 

From the System Browser menu, select Browse >> System. Below is a graphic that summarized how the System Browser, in package mode, is organized:


Figure 7-3. How the System Browser (packages) is organized

You can change the default mode from Packages to Parcels by going to the main launcher window and select System >> Settings from the main menu. Then select Tools >> Browser from the list of options in the left pane and on the right you will see a drop-down selection list for default browser type. We recommend that you stay with the Packages view.


Figure 7-3a. Changing the System Browser default type

Packages and protocols are just mechanisms for organizing the classes and methods. Packages are also an aspect of the version control system, but that's beyond the scope of this tutorial. It will take a while to start remembering which classes belong to which Packages and which methods belong to which protocols but let's not worry about that for now. We're just about ready to start coding, but before we do, there's just one more catch - Namespaces.

What is a Namespace?

A Namespace is a difficult concept to explain so instead let's use an analogy. Suppose there was this building (for the sake of the analogy, this building would represent your Smalltalk image, the library of all Smalltalk methods). In this building, you are going to allow people to enter; however, no two people who enter can have the same name. For example, as soon as you allow BOB to enter the buildling, no other BOB can enter. A problem would arise if we allowed a second BOB into the building. Suppose SUSAN walks in and says "Hey BOB! Let's do lunch." Which BOB does she mean?

So here's the solution. You are allowed to create as many rooms in this building as you want. Now SUSAN can ask "Hey BOB in room A. Let's do lunch." and the conflict is solved.

This is how the Smalltalk image (class library) is organized. Instead of having all of the existing (delivered) classes and the new ones you create living in the same (one room) building, they are sequestered off into separate rooms. These separate rooms would represent namespaces. When you create your own classes, it is highly recommended that you create a separate room (namespace) for them. The reason for this is quite simple. Since you can make up your own names for your classes, it is likely that you and another programmer might want to use the same name for your classes even though they may do entirely different things. This is called a collision. In the past, people used a "prefixing" naming convention to avoid collisions, but this discouraged reuse so namespaces were invented.

Normally, before you choose your classes, protocols and methods, you would first create a namespace where they all will belong. Not that this is a complicated procedure, but for the scope of this tutorial, in order to keep things very simple, we will not create our own namespace. We will add all of our classes into an existing namespace, and use a single package. That namespace is called Smalltalk.

2. If you have closed the System Browser, re-open it and select the first package listed (Base VisualWorks) in the list of packages. A list of classes will appear in the class list to the right of the packages. In the bottom (method) pane, the System Browser will display a template for defining a new class in the method code area. However, since you selected the Base VisualWorks package, that will be the name of the package listed in the code area. (Base VisualWorks is actually a bundle - which contains other packages. We won't be going into that in this tutorial). The System Browser should look like the one below:


Figure 7-4. The System Browser with the "New Class" template.

3. The next step is to create a new package, which is where we will save all of the code you'll create. In the browser, pull down the "Package" menu item, and select "New Package". You should see the following:



Name your package WebLogStats.

The next step is to create a new class. The easiest way to do that is to use the class creation tool. In the the open browser, with the new package selected, pull down the "Class" menu, and select "New Class". You should see a dialog that looks like what's below; fill in the appropriate fields as shown. Most of the fields in the dialog are optional, and you can allow them to default for now:



Once you click "Ok", you should see a new class defined in the browser, with the definition as seen below

 
    Smalltalk defineClass: #WebLog
        superclass: #{Core.Object}
        indexedType: #none
        private: false
        instanceVariableNames: 'filter logDirectory '
        classInstanceVariableNames: ''
        imports: ''
        category: 'WebLogStats'
    


4.
When you selected "Ok", the class was compiled and placed into the new WebLogStats package. You'll notice that two method protocols were created for you - "accessing" and "initialize-release". By default, the class creation dialog generated basic methods for accessing the instance variables, as well as an initialization method. We'll be looking at (and modifying) that code below. You should now see a window that looks like this:


Figure 7-5b. Our new package (WebLogStats) with our new class WebLog

Making the class name and package name just slightly different makes things easier to differentiate. You do not need to call your class WebLog (you could have used just WebLogStats but this way, you'll know it's a class).

Note the line regarding instanceVariableNames. These are variables that belong to each instance. Once set, their values remain for as long as the object remains.


5. Click the WebLog (Class) so that it is highlighted, then click the Class tab above the protocol pane. Again, you'll see that a method category (and a method) have been auto-generated. Select the protocol "instance creation" and the method "new". If you didn't have this generated, then do the following:

6. Now <Operate-Click> in the protocol pane. Select New...

A dialog box will appear asking you to enter a new protocol name. When it comes to protocol names, there is a de-facto naming convention amongst all Smalltalkers for "common" protocols to which everyone agrees. Enter instance creation and click OK.

Note that some text has appeared in the bottom pane. This is a "template" for you to use when creating methods.

You should see a window like the one below.


Figure 7-6. Our new protocol (instance creation) viewed in the Browser

7. Make sure the protocol tab is set to Class. If the new method was not automatically generated, create it by replacing the following text:

message selector and argument names
    "comment stating purpose of message"

    | temporary variable names |
    statements


with

new
    ^super new initialize



8. Now <Operate-Click> in the bottom pane and select Accept. You can also use the keyboard shortcut ctrl-s. This will "compile" the code you just entered and barring any typos, the new method will appear in the method pane.

You should see a window like the one below.


Figure 7-7. Our new method (new) viewed in the Browser

What the heck does "^super new initiaize" mean? Proceed to the super primer.

9. Click the Instance tab above the protocol pane.

Note that your class definition text has reappeared.

10. Now <Operate-Click> in the protocol pane.

Select New... A dialog box will appear asking you to enter a new protocol name. When it comes to protocol names, there is a de-facto naming convention amongst all Smalltalkers for "common" methods to which everyone agrees. If you let the class creation dialog generate code, there's already an "initialize-release" protocol category. If there's not, do the next step. Enter initialize-release and click OK. Note that you will already have this protocol and an "initialize" method if you let the creation dialog generate it.

Note that some text has appeared in the bottom pane. This is a "template" for you to use when creating methods. If you already have the "initialize" method, don't worry - you can overwrite it in place, with the code you'll need. In the examples below, you may need to change the VW home directory - we are using "c:\vw7.4" here. Change that as appropriate for your platform and installation. Again, if you let the class creation dialog generate code, you'll see a default "initialize" method.

You should see a window like the one below.


Figure 7-8. The default method generated for you

11. Replace the text in the method code area with the following:

initialize
  "initialize the WebLog. Set the logDirectory variable."
  logDirectory := 'c:\vw7.4'.


The initialize method is one of those "common" methods that "unofficially" belongs to the initialize-release protocol. Also, now would be a good time to modify the value of the instance variable to the directory where the log files exist (otherwise your code will not work properly).

12. Before you <Operate-Click> in the bottom pane and select Accept (or type ctrl-s), you may want to change the string c:\vw7.4 to the actual directory that contains your log files. This will "compile" the code you just entered and barring any typos, the initialize method will appear in the Method pane.

You should see a window like the one below.


Figure 7-9. Our new method (initialize) viewed in the Browser

13. Make sure the Instance tab above the protocol pane is still selected. Now <Operate-Click> in the protocol pane. Select New... A dialog box will appear asking you to enter a new protocol name. Enter testing and click OK.

Note that the "template" for creating methods appears.

14. Replace the text in the method code area with the following:

viewDirectory
| workingDir contents |
workingDir := logDirectory asFilename.
contents := workingDir directoryContents.
contents do: [ :each | Transcript show: each printString; cr. ]


15. Now <Operate-Click> in the bottom pane and select Accept. This will "compile" the code you just entered and barring any typos, the viewDirectory method will appear in the Method pane.

You should see a window like the one below (probably not formatted; the code presented below is in "standard" Smalltalk formatting style).


Figure 7-10. Our new method (viewDirectory) viewed in the Browser

16. Open a Workspace and make sure the Transcript is visible too.
Enter WebLog new viewDirectory then Do it.
See? The code still works. You are now using a Workspace to test the objects you just created.

17. Make sure the Instance tab above the protocol pane is still selected. Now <Operate-Click> in the protocol pane.
Select New... A dialog box will appear asking you to enter a new protocol name. Enter private and click OK.

Note that the "template" for creating methods appears.

18. Replace the text in the method code area with the following:

showHits: aFile

| myFile myStream myLine addrIP mySet |
mySet := Set new.
myFile := logDirectory asFilename construct: aFile.
myStream := myFile readStream.
[ myStream atEnd ] whileFalse:
[myLine := myStream upTo: Character cr.
addrIP := myLine copyUpTo: $,.
mySet add: addrIP.].
myStream close.
^mySet size.


19. Now <Operate-Click> in the bottom pane and select Accept. This will "compile" the code you just entered and barring any typos, the showHits method will appear in the Method pane. The "construct:" method above lets us create filename objects in a platform neutral way - the code above will work the same way on Unix, Linux, Windows, and Macintosh platforms.

You should see a window like the one below.


Figure 7-11. Our new method (showHits) viewed in the Browser

Methods in Smalltalk are like subroutines or functions in other languages. The COBOL language calls them "procedures" and most BASIC dialects call them "SUBs". However, the term "function" is commonly used when a routine will return or pass back some value. In Smalltalk, when you want to "return" something, you use the caret (^) sign.

Whenever you have an expression that uses the return caret, remember to always evaluate the entire expression first. The actual "return" is the very last thing that happens. So an expression like ^mySet size, Smalltalk will evaluate mySet size (which probably produces a SmallInteger instance) and returns that to the object that invoked the entire method.

If you are wondering about the proper formatting of the code (indentations, line breaks, code blocks, etc.), you are free to use whatever form you like. However, there is a defacto standard that VisualWorks uses. The Browser provides an automatic formatting facility.

In the method area, <Operate-Click> and select Format. This will "format" the code according to this defacto-standard.


Figure 7-12. The Format option on the menu


Figure 7-13. The code in a defacto-standard Smalltalk format

20. With the private protocol still selected, replace the text in the method code area (it should be the showHits method) with the following (don't worry - your code for the showHits method is saved in memory):

getLogFiles

| workingDir contents xFound count |
workingDir := logDirectory asFilename.
contents := workingDir directoryContents.
contents do: [ :each |
xFound := each findString: filter startingAt: 1.
xFound > 0
ifTrue:[ count := self showHits: each.
Transcript show: each, ' . . . ', (count printString); cr. ].
].


Note that we have resorted back to a simplified (non-compound) "filtering" logic. Since the only files that begin with ws00 are our log files, then all we have to do is search for files that begin with ws00. You will see how this comes into play shortly when we initialize the filter variable.

21. Now <Operate-Click> in the bottom pane and select Accept. This will "compile" the code you just entered and barring any typos, the getLogFiles method will appear in the Method pane.

You should see a window like the one below.


Figure 7-14. Our new method (getLogFiles) viewed in the Browser

What a minute! There's something new in that code I haven't seen before - self. What does that do?
Find out more about self.

22. With the private protocol still selected, replace the text in the method code area (it should be the getLogFiles method) with the following:

start

filter := (Dialog request: 'Please enter a filter ' initialAnswer: 'ws00').
(filter size) > 0
ifTrue: [self getLogFiles]


23. Now <Operate-Click> in the bottom pane and select Accept. This will "compile" the code you just entered and barring any typos, the start method will appear in the Method pane.

You should see a window like the one below.


Figure 7-15. Our new method (start) viewed in the Browser

24. Open a workspace and enter the following:

WebLog new start


Highlight all of this text, <Operate-Click> and select Do it.

The code should now run just like it did in the previous lesson.


Figure 7-16. The results are still the same - the code is just in a different location

Summary

Wow! That was a long workshop but worth it. It seemed that way because you had to do a lot of "up front foundation" work to create a package and some standard protocols.

In the next lesson, you will learn how to save your work. And the lesson after that, you will add more functionality to your class, namely to figure out which web pages were the most popular (i.e. had the most hits).

You now should know how to:

Use the System Browser to create a new package, class, protocol and method

Identify 2 types of methods - Class and Instance

Format code according to a Smalltalk defacto-standard

Test your objects with a Workspace


| Table of Contents | Lesson 6 | Lesson 8 |