Previous | Table of Contents | Next |
An extensive and mature class library accompanies all Smalltalk development environments. The libraries vary across versions on implementation of the GUI and external interfacing, but overall they share a significant number of common features. These features are unique to Smalltalk and provide a powerful environment that lends itself to many types of applications. Included in class libraries are multiprocess frameworks, external code interfacing (to C, COBOL, or another), external resource interfacing (such as OLE and OCXs), exception handling, dependency and event frameworks, and reflective capabilities (such as modifying the executing program and querying the structure of an application).
Smalltalk has always been a multiprocess environment. Even on operating systems that dont support simultaneously executing tasks, Smalltalk provides its own internal process framework. As shown in Figure 5.1, an operating system process may contain one or more threads, with one of these threads handling the Smalltalk language processing. The Smalltalk language processing is split among as many Smalltalk processes as the application requires. The scheduling of these processes differs between versions, as does the number of operating system threads. A Smalltalk process is similar to an operating system thread in that it is contained entirely within Smalltalk. However, on platforms that support threads, Smalltalk processes do not become operating system threads. There are some exceptions to this rule:
FIGURE 5.1. Smalltalk supports multiple processes, even when the host platform does not.
Often, Smalltalk applications are required to interface with C DLLs, COBOL programs, or other external code modules. Many options are available to interface with these modules, and Smalltalk programmers make use of the facilities to call these external programs. Because most Smalltalk development is done on PCs or workstations, the most common interface of external code is through a C dynamic link library or C shared library. The C interface is the most common external interface supported in Smalltalk, although Smalltalk MVS for IBM mainframes calls external COBOL modules and fits well in that environment.
Smalltalk programs take advantage of many of the same features that other languages use on the host platforms. This can include OCXs for custom GUI controls and OLE for interaction with email and desktop applications under Microsoft operating systems. These features are available in the base Smalltalk products, as well as toolkits from third-party developers. People have interfaced Smalltalk to hardware for communications and control, music and graphics systems, and every conceivable type of other system. Often, an application in Smalltalk is the GUI front end and the glue that holds together other separate technologies developed in other languages.
5.2.2.1. Exception Handling
Smalltalk systems include an extremely powerful exception-handling framework. Although the Smalltalk versions differ in syntax and implementation, the common function is to signal errors that occur many layers deep in code, and to respond to those errors in the best layer of application code. For example, in an engineering application, the divide-by-zero error must be handled in any situation in which it might occur. The five possible paths for dealing with an error are shown in Figure 5.2. Choices 4 and 5 create a new stack frame to further execute the other handlers registered previously, while options 1 and 3 drop back one stack frame, and option 2 may drop several. Experienced Smalltalk programmers realize that they must reset any state information changed before the error was encountered when dropping stack frames.
FIGURE 5.2. Exception handling in Smalltalk provides complex strategies for dealing with errors.
In Smalltalk, you have several options that are implemented based on the code that is executed:
[ (a + b) / c ] when: self divideByZeroException do: [:signal | signal resumeWith: 99999 ]
[ (a + b) / c ] when: self divideByZeroException do: [: signal | signal resumeWith: (a + b) ]
[ (a + b) / c ] when: self divideByZeroException do: [:signal | signal exitWith: 1 ]
[ (a + b) / c ] when: self divideByZeroException do: [:signal | signal retry ]
[ (a + b) / c ] when: self divideByZeroException do: [:signal | signal signal]
[ (a + b) / c ] when: self divideByZeroException do: [:signal | self badMathError signalWith: signal exception ]
Exception handling is a powerful framework that should be used to deal with unexpected system errors that could happen in your application. It is not good practice to go overboard with this mechanism and create exception handlers for nonexceptional cases (such as application logic). In such a case, the code might become cluttered, less readable, and much harder to maintain.
Previous | Table of Contents | Next |