old-www/LDP/LG/issue59/steffler.html

426 lines
24 KiB
HTML

<!--startcut ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>Making Smalltalk: Spreading the OO Fun LG #59</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->
<CENTER>
<A HREF="http://www.linuxgazette.com/">
<H1><IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.jpg"
WIDTH="600" HEIGHT="124" border="0"></H1></A>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="nielsen.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue59/steffler.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_backpage59.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>
<!--endcut ============================================================-->
<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>
<P> <HR> <P>
<!--===================================================================-->
<!-- END header -->
<table COLS=2 WIDTH="100%" NOSAVE >
<tr NOSAVE>
<td NOSAVE>
<center>
<h1>
<img SRC="misc/steffler/makingSmalltalk.jpg" height=53 width=417></h1></center>
<center>
<h3>
Spreading the OO Fun (Series Introduction)</h3></center>
<center>
<p><br>By <a href="mailto:jagwar@magma.ca">Jason Steffler</a></center>
</td>
<td WIDTH="200" NOSAVE>
<center><img SRC="misc/steffler/penguinInBalloon.gif" height=230 width=200></center>
</td>
</tr>
</table>
<h2>
<a NAME="abstract"></a>Abstract</h2>
<a href="http://www.magma.ca/~jagwar/makingSmalltalkForwardingPage.html"><img SRC="misc/steffler/toc.jpg" ALT="Series Table of Contents" align=RIGHT></a>
<br>&nbsp;&nbsp;&nbsp; When I wrote the first Making Smalltalk with the
Penguin <a href="http://www.linuxgazette.com/issue51/steffler.html">article
back in March of 2000</a> <a href="../issue0-tourOfSmalltalk/tourOfSmalltalk.html">[LL]</a>,
my target audience was experienced programmers who didn't have much exposure
to <a href="#articleGlossary">OO</a> programming or to Smalltalk.&nbsp;
The article's intent was to give an overview of my favourite programming
language on my favourite operating system.&nbsp; Since then, I've had a
fair amount of email asking introductory type questions about Smalltalk
and OO programming.&nbsp; So I thought I'd try my hand at a small series.&nbsp;
It's been a while coming as after the first article I relocated from KS-&gt;CT
and had a baby (obviously using the corporate 'I' here! :-)
<br>&nbsp;&nbsp;&nbsp; The target audience for this series are people new
to OO or new to programming altogether.&nbsp; The intent is to not only
introduce OO programming, but to also spread the fun of Smalltalking.&nbsp;
Why do this format/effort when there's lots of good <a href="http://www.squeak.org/#tutorials">tutorials
out there</a>?&nbsp; Two reasons really:&nbsp; 1) Tutorials are great,
but can be static and dated pretty quickly.&nbsp; 2) An ongoing series
tends to be more engaging and digestible.
<br>&nbsp;&nbsp;&nbsp; To help address the second reason above, my intent
is to keep the articles concise so they can be digested in under an hour<sup><a href="#footnotes">1</a></sup>.&nbsp;
Hopefully, as newbies follow along, they can refer back to the original
article and make more sense of it.&nbsp; I plan on having a touch of advanced
stuff once in a while to add flavour and as before, the articles are going
to be written for read-along or code-along people.
<br>&nbsp;&nbsp;&nbsp; Something new I'm going to try is to make the ongoing
series viewable in a contiguous fashion and downloadable in one chunk for
people who want to browse the series locally.&nbsp; To do this, click on
TOC grapic to right.&nbsp; The articles are going to have 2 sets of links:&nbsp;
one set for www links, another set for local links, indicated as: <a href="#articleGlossary">[LL]</a>
<br>&nbsp;&nbsp;&nbsp; If you like what you're reading, <a href="mailto:jagwar@magma.ca">drop
me a line</a> letting me know, and I'll keep putting precious time into
it.
<br>&nbsp;
<h2>
<a NAME="whySmalltalk"></a>Why Smalltalk?</h2>
&nbsp;&nbsp;&nbsp; Before we can get into OO stuff, I feel the need to
set the context of the articles.&nbsp; Unfortunately, this will take up
the bulk of this first article, but it's an important thing to do.&nbsp;
We'll finish with a little bit of OO stuff at the end, and get into it
more in the next article.
<br>&nbsp;&nbsp;&nbsp; I believe Smalltalk is <b><u>the best</u></b> environment
to learn OO programming in because:
<ul>
<li>
Smalltalk has a very active and very helpful community; when you post a
question to the Smalltalk newsgroups you very often get an answer, unlike
many other newsgroups</li>
<li>
is very easy to learn... one of it's original design intententions was
to be a learning environment for children</li>
<li>
is a pure OO environment and encourages OO programming (as opposed to encouraging
procedural/Object mixed programming)</li>
<li>
cutting your teeth in Smalltalk makes you a better OO programmer in any
other language, because of the previous bullet</li>
<li>
is a portable environment:&nbsp; write once, run anywhere, so people can
learn on whatever OS they're running&nbsp; (as opposed to just the M$ variety)</li>
<li>
can look at and manipulate objects in real time; I haven't seen this ability
in any other environment</li>
<li>
Smalltalk is written in Smalltalk.&nbsp; You can view how the language
is put together to learn the language, and you can change anything that
you don't like about it.</li>
<li>
has garbage collection, no manual memory management, no explicit pointers</li>
<li>
is a literate language; by this I mean the syntax is very simple and is
geared towards programmer readability.</li>
<li>
there's lots of Cool Things that you can do in it that I haven't seen anywhere
else (will have some examples along the way)</li>
<li>
...and best of all: <b><u>it's fun</u></b>.</li>
</ul>
In particular, I'm going to use <a href="http://www.squeak.org/">Squeak</a>
as the playing vehicle.&nbsp; You'll notice this is a different flavour
of Smalltalk than I used in my first article.&nbsp; I've never used Squeak
before, so this'll be a learning experience for me too.&nbsp; The reasons
for this are:
<ul>
<li>
It's a completely opensource project</li>
<li>
It has some Really Cool features that I haven't seen in other flavours
of Smalltalk</li>
<li>
It has a comparitively small footprint and it's very easy to install</li>
<li>
It has a strong <a href="http://minnow.cc.gatech.edu/squeak/1">Swiki site</a>&nbsp;
(a <a href="#articleGlossary">Wiki</a> site hosted in Squeak, hence <b>S</b>queak
<b>Wiki</b>)</li>
</ul>
<h2>
<a NAME="quoteOfTheDay"></a>Quote of the day</h2>
In essence, Smalltalk is a programming language focused on human beings
rather than the computer.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -Alan Knight
<h2>
<a NAME="installationStuff"></a>Installation stuff</h2>
<b><font color="#CC0000">&nbsp;&nbsp;&nbsp; <i>Note:&nbsp; before you fire
up Squeak, I need to warn you to not be put off by the sparten GUI. </i></font><font color="#330000">There's
actually two types of GUIs in Squeak:&nbsp; MVC &amp; Morphic, both of
which have skins to implement specific look-n-feels.&nbsp; For at least
the beginning of the series, I plan on sticking to Morphic without skins,
as it's the newer GUI and I want to keep things simple.</font></b>
<br>&nbsp;&nbsp;&nbsp; To install Squeak, you basically need to download
and unzip 4 files.&nbsp; RPMs are available for people who prefer them.&nbsp;
For instructions on downloading and installing Squeak, see these <a href="http://www-sor.inria.fr/~piumarta/squeak/">installation
instructions</a>, or these <a href="http://minnow.cc.gatech.edu/squeak.388">installation
instructions.</a><i>&nbsp; (Note: I'm using v2.7 of Squeak, which isn't
the latest version, but for the purposes of these articles, the latest-n-greatest
version is not required unless otherwise noted)</i>
<h2>
<a NAME="firstLooks"></a>First Looks</h2>
<i>&nbsp;&nbsp;&nbsp; Note:&nbsp; do not save anything until we get to
that point below.&nbsp; The initial orientation and setup of squeak is
a little painful, but by the time we're done here it'll be much more friendly.</i>
<br>&nbsp;&nbsp;&nbsp; Now that you have Squeak installed, let's fire it
up.&nbsp; Go to a command prompt, cd to the directory where squeak is,
and type <b>squeak Squeak-2.7.image</b>.&nbsp; You'll see a window open,
with 10 windows within it.&nbsp; Feel free to read the <b>Welcome To...</b>
and <b>Getting Started...</b> windows.&nbsp; If you want to skip this and
read them later, that's fine too.&nbsp; You'll notice that the look-n-feel
is "weird", don't worry about this.&nbsp; There are reasons for this that
I'll get to in a future article.&nbsp; You can also play around with the
various <b>Play With Me</b>s (there's some neat things there).&nbsp; Feel
free to mess around to your heart's content, try resizing things, moving
them ,etc.&nbsp; Don't worry about breaking anything as we haven't saved
anything yet.&nbsp; When you click on <b>Play With Me 3, 6, 7 or 8</b>,
you need to click on the window to get into it.&nbsp; To get out of it,
<b>left
click</b> on the window background, and select <b>previous project</b>.
<br>&nbsp;&nbsp;&nbsp; When you're done playing, and you're back in the
main view you started out in, <b>middle click</b> on the squeak background
somewhere, and select <b>quit</b>, and <b>no</b>, as we don't want to save
any changes.&nbsp; Now restart squeak, and move the <b>Welcome To...</b>
window somewhere.&nbsp; Now <b>middle click</b> on the squeak background
somwhere, and select <b>save and quit.</b>&nbsp; Now, restart sqeuak again...
notice that the window is in the place where you left it.&nbsp; In fact,
every time you save in sqeuak <b><u>the state of the IDE is saved exactly
as it was!</u></b> <sup><a href="#footnotes">2</a></sup> All the window
placements, all the code - everything is exactly where you left it.&nbsp;
This is great for getting back up to speed quickly on what you were doing.
<br>&nbsp;&nbsp;&nbsp; For the read-along folks, here's what the <b>Welcome
To...</b> &amp; two of the <b>Play With Me</b> windows look like:
<br><img SRC="misc/steffler/picWelcomeScreen.png" height=356 width=390>
<br><img SRC="misc/steffler/picPlayWithMe2.png" height=351 width=568>
<br><img SRC="misc/steffler/picPlayWithMe5.png" height=490 width=558>
<p>&nbsp;&nbsp;&nbsp; Now, let's do a little customization before we move
on to examples.&nbsp; Open a workspace (<b>middle click</b> on the squeak
background, select <b>open...>workspace.</b>)&nbsp; You'll notice that
it's the same type of window as the <b>Welcome To...</b> and <b>Getting
Started...</b> windows.&nbsp; Enter in the following code snippits:
<p><b>&nbsp;&nbsp;&nbsp; Preferences setPreference: #noviceMode toValue:
true.</b>
<br><b>&nbsp;&nbsp;&nbsp; Preferences setPreference: #inboardScrollbars
toValue: true.</b>
<br><b>&nbsp;&nbsp;&nbsp; Preferences setPreference: #useGlobalFlaps toValue:
true.</b>
<p><b>&nbsp;&nbsp;&nbsp; </b>Then highlight both lines and execute the
code (<b>middle click>do it</b>).&nbsp; This is known as 'doing it' in
Smalltalk.&nbsp; Congratulations, you just ran your first Smalltalk code.&nbsp;
Don't worry about the symantics right now, just be aware that we set some
preferences.&nbsp; Now, remember when I mentioned that we'd be using the
morphic GUI type for these articles?&nbsp; To do this, <b>middle click</b>
on the squeak background, select <b>open...><a href="#articleGlossary">morphic
project</a></b>.&nbsp; You'll see a small window appear called <b>Unnamed1</b>.&nbsp;
Let's name this project something, as you've already probably experienced,
clicking on the title of the window will bring up a rename prompt.&nbsp;
Type in <b>Making Smalltalk. </b>If you want, you can resize the window
to see the whole title.
<br>&nbsp;&nbsp;&nbsp; Now, let's enter the project, do this by clicking
on the project to give it focus, then clicking on it again.&nbsp; You'll
notice there are four tabs&nbsp; arranged around the screen (<b>Menus,
Squeak, Tools, and Supplies</b>).&nbsp; If you mouse over the tab, a pop
up menu will appear with neat stuff on it.&nbsp; If you mouse over the
<b>Menu</b>
tab you'll see the <b>open...</b> menu in the top left corner, select <b>workspace</b>
to open up a workspace.&nbsp; You'll notice the look-n-feel is a little
different now, as we're using the Morphic type of GUI; this project will
be the basis of these articles.
<br><img SRC="misc/steffler/picMorphicWorkspace.png" height=245 width=406>
<p>One thing you'll notice from the menus, is that there's no saving option.&nbsp;
Since we want to save everything we've done, let's get that menu.&nbsp;
To do this, <b>right click</b> on the project background, you should see
a series of different coloured dots around the screen.&nbsp; We're not
going to get into their purpose just yet.&nbsp; Now <b>left click</b> on
the <b>red dot </b>in the top left hand corner of the screen, you'll see
a playfield menu, select <b>keep this menu up</b>.&nbsp; Now the menu is
sticky, and you can move it around.&nbsp; Let's move it out of the way
of the flaps to the bottow left hand corner of the screen.&nbsp; Finally,&nbsp;
let's save what we've done, on that menu you just made sticky, click on
<b>save</b>.&nbsp;
Your window should look something like:
<br><img SRC="misc/steffler/picSqueakStartingPoint.png" height=514 width=608>
<br>&nbsp;
<h2>
<a NAME="gettingToObjects"></a>Getting to objects</h2>
&nbsp;&nbsp;&nbsp; As I mentioned, the bulk of this article is going to
be setting the stage for future articles.&nbsp; Now we can finally start
addressing the topic at hand.&nbsp; There are many different definitions
of what an object is.&nbsp; One way of thinking about it is that an <a href="#articleGlossary">object</a>
is anything you can think of that is a noun.&nbsp; A window, a menu, an
array, a GUI, a string, an integer, a person, a tree, etc.&nbsp; This is
a very simple view of what an object is, and we'll refine the definition
over time.
<br>&nbsp;&nbsp;&nbsp; In Smalltalk, <b><u>everything is an object</u></b><sup><a href="#footnotes">3</a></sup>.&nbsp;&nbsp;
Unlike other languages where small building blocks like integers or strings
aren't objects, everything is an object.&nbsp; If you have procedural programming
experience, this is a good mantra to repeat for about 6 months.
<br>&nbsp;&nbsp;&nbsp; Let's start with the venerable Hello World example,
but with a minor update (sheesh, we're not back in the '60s here).&nbsp;
Instead of printing a string to the stdout (to the command line), let's
open a window with the string in it.&nbsp; In the workspace enter and 'do':
<p><b>&nbsp;&nbsp;&nbsp; (Workspace new contents: 'Hello World') openLabel:
'Hello World Workspace'</b>
<p>&nbsp;&nbsp;&nbsp; You'll see:
<br><img SRC="misc/steffler/picHelloWorldWorkspace.png" height=97 width=300>
<p>&nbsp;&nbsp;&nbsp; Remember when I said everything is an object?&nbsp;
Well, we asked a new Workspace object to make its contents<b> Hello World,
</b>then
asked it to open itself with the label <b>'Hello World Workspace'.</b>&nbsp;
Notice there's no 'main' method, no compiling and linking step, no switching
between a text editor and a compiler.&nbsp; The simplicity of being able
to just type Smalltalk code and run it is very refreshing.
<br><b>&nbsp;&nbsp;&nbsp; </b>...but this old example is pretty worn out.&nbsp;
Let's do something a little more up to date<sup><a href="#footnotes">4</a></sup>.&nbsp;
Let's make a line; in the workspace enter and do:
<p><b>&nbsp;&nbsp;&nbsp; World addMorph:</b>
<br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (PolygonMorph</b>
<br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vertices: {50@50.
200@200}</b>
<br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; color: Color red</b>
<br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; borderWidth: 20</b>
<br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; borderColor: Color
red)</b>
<p>&nbsp;&nbsp;&nbsp; You'll see:
<br><img SRC="misc/steffler/picRedLine.png" height=327 width=720>
<p>&nbsp;&nbsp;&nbsp; Here, we asked the project (World) we're in (projects
are objects too) to add a morph that is a red line from point 50x50 to
point 200x200.&nbsp; Now, let's play with this object a little bit, if
you right click on the line object, you'll get the various multi-coloured
points again (these are called halos).&nbsp; If you mouse over the line
object, you'll see pop-up help describing what the halos do (<b>Rote, Change
size, debug, Duplicate, Move, etc)</b>.&nbsp; <b>Left click</b> on the
yellow halo, and resize the line a few times.&nbsp; Try the <b>rotate,
duplicate, move</b> buttons to play some more.&nbsp; Finally <b>left click</b>
on the 'X' <b>button</b> when you want to get rid of the line object(s).
<br>&nbsp;&nbsp;&nbsp; To make this first article digestible, I'm going
to stop off here.&nbsp; Before I go though, I'm going to introduce the
'Sweet Squeak' section...
<h2>
<a NAME="aSweetSqueak"></a>A Sweet Squeak</h2>
This section won't explore/explain code or example, but merely present
a neat thing to try out<sup><a href="#footnotes">5</a></sup>.&nbsp; This
time, lets view a shockwave file.&nbsp; If you have an internet connection
up, try entering this code and do it:&nbsp; <i>(note, might take a while
over 28.8; I did this at a friend's place with a 128K ISDN and it was pretty
snappy)</i>
<p><b>&nbsp;&nbsp; (FlashMorphReader on: (HTTPSocket</b>
<br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; httpGet: 'http://www.audi.co.uk/flash/intro1.swf'</b>
<br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; accept:'application/x-shockwave-flash'))</b>
<br><b>&nbsp;&nbsp;&nbsp; processFile startPlaying openInWorld.</b>
<br>&nbsp;
<h2>
<a NAME="lookingForward"></a>Looking forward</h2>
The next article will discuss Objects again as well as classes, messages
and encapsulation.
<br>Also, if any Squeakers out there know of something neat that can be
easily done, let me know and I'll add it if there's room.
<h2>
<a NAME="questionsAndAnswers"></a>Questions and Answers</h2>
As opposed to including already answered questions via email, I'm going
to start this section with a clean slate to address questions (as I have
time) that this series raises.&nbsp; If you want a faster response, try
posting your question to the comp.lang.smalltalk newsgroup, or the <a href="http://minnow.cc.gatech.edu/squeak/1">Swiki</a>.
<h2>
<a NAME="articleGlossary"></a>Article Glossary</h2>
This is a glossary of terms that I've used for the first time in this series,
or a term that I want to refine.&nbsp; If you don't see a term defined
here, try the <a href="http://www.magma.ca/~jagwar/makingSmalltalkForwardingPage.html">ongoing
glossary</a> <a href="../ongoingSeriesGlossary.html">[LL]</a>
<p><b>IDE</b>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integrated Development Environment.&nbsp;&nbsp;
An environment that programmers use to develop code in that they can program
and debug in.
<br><b>[LL]</b>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; relative Local Link, use
this link when browsing these articles locally
<br><b>Object</b>
<br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </b>(def 1-simple)&nbsp;
An object is anything you can think of that is a noun.&nbsp; A window,
a menu, an array, a GUI, a string, an integer, a person, a tree, etc.
<br><b>OO</b>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object Oriented&nbsp; Briefly,
this is a popular style/methodology of programming that these articles
are going to introduce.
<br><b>Project</b>
<br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </b>A specific view of the
code.&nbsp; You can have multiple simultaneous views of the code.&nbsp;
This is very handy if you're doing two or three projects at once, and don't
want to lose track of where you're are in them.
<br><b>Wiki site</b>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A series of web sites where
there is no designated editor (for the most part, the odd page may have
a password). If you see a way to improve the site, you can do so yourself!
If you don't understand something, just edit the web page and type in your
question!
<h2>
<a NAME="footnotes"></a>Footnotes</h2>
[1]&nbsp; Keeping the articles concise will actually be the biggest challange.&nbsp;
There's such a wealth of information that it's hard to convey just what
is needed.&nbsp;&nbsp; To that end, I plan on making some simplifications
as I go along and gradually refine them to reflect the technicalities.
<br>[2]&nbsp; This is a feature common to all Smalltalk flavours that I
know of.&nbsp; It's one of the many thinks I like about Smalltalk.
<br>[3]&nbsp; This is the same assertion that I made in the first article,
and I had a pile of people email me about how this isn't technically accurate.&nbsp;
I thought from the context of the article that it would be apparent that
this was a simplified generalization, oh well.&nbsp; This time I'll be
explicit:&nbsp; this assertion is technically not accurate:&nbsp; not everything
in Smalltalk is an object, but the vast majority of things are.&nbsp; For
the beginner, it's a helpful simplifying view to have.&nbsp; I plan on
refining this view later on.
<br>[4]&nbsp; This snippet is from a <a href="http://minnow.cc.gatech.edu/squeak/1418">Swiki
entry by Dan Ingalls</a>
<br>[5]&nbsp; This snippet is also from the <a href="http://minnow.cc.gatech.edu/squeak/1651">Swiki</a>
<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P -->
<H5 ALIGN=center>
Copyright &copy; 2000, Jason Steffler.
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
Published in Issue 59 of <i>Linux Gazette</i>, November 2000</H5>
<!-- *** END copyright *** -->
<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="nielsen.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue59/steffler.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_backpage59.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->