Smalltalk User Guide
Preface
Notices
Trademarks
About this book
Who this book is for
What's new?
Support for Tonel has been added
VAST Platform 2022 (version 11.0.0)
Conventions used in this book
Tell us what you think
Overview
Getting started
The basic development environment
Browsers in the basic environment
Standard browsers
TrailBlazer browsers
Pop-up menus
Picking a browser
System architecture
Image
Image files
Library
Loading and unloading components
Starting your image
Starting from the desktop
Starting from a command line
Command line arguments
Accessing the command line arguments
Saving an image to keep components loaded
Using the Save Image option
Using the Save Image As option
Saving upon exit
Components
System components
Software components
Getting started with team concepts
Version control
Editions
Versions
Scratch editions
Change and access controls
Component ownership
Application groups
Change controls
Class owner
Class developers
Application managers
Configuration map managers
Access controls
Image and library controls
Application controls
Setting access control privileges for applications
Configuration management
Application lineups
Configuration map lineups
Releasing
Organizing your team
Assigning team roles
Starting a project
The generic development process
Naming your components
Developing classes and creating individual baselines
Creating baselines as a team
Making your own applications
Creating applications
Creating applications--The basic steps
Example: Creating the application DevelopChooser
Setting application prerequisites
Checking prerequisites
Changing prerequisites
Example: Changing prerequisites for the application DevelopChooser
Defining group members for your application
Adding group members
Deleting group members
Assigning an application manager for your application
Assigning owners for classes
Defining classes
Defining a class--The basic steps
Using an existing class as a template
Using menu options
Example: Defining the class Chooser
Ensuring that the class you are subclassing from is visible
Creating a subclass
Adding variable declarations
Implementing methods
Implementing methods--The basic steps
Example: Adding methods to the defined class Chooser
Implementing the method open
Implementing the remaining ten methods
Opening Chooser
Ensuring that Chooser loads with DevelopChooser
Extending defined classes
Creating a class extension: The basic steps
Example: Extending the class Object
Example: Adding the method needsMoreWork to your class extension
Creating subapplications
Creating subapplications: The basic steps
Example: Creating the subapplication DevelopStopwatch
Creating a subapplication component
Defining the subclass Stopwatch
Implementing methods for Stopwatch
Opening the window
Completing work on your subapplication
Practice: Creating DevelopTextEditor and DevelopTimeLogger
A shortcut: Copying code into a browser
If you want to skip this practice...
Example: Creating DevelopTextEditor
Creating an application component for DevelopTextEditor
Defining the class TextEditor
Implementing the public instance methods
Implementing the private instance methods
Private methods for category Getters & Setters
Private methods for category Initialization & Startup
Private methods for category Window Creation
Private methods for category Event Handlers
Private methods for category File Operations
Example: Creating DevelopTimeLogger
Creating an application component for DevelopTimeLogger
Defining the class TimeLogger
Implementing the public instance methods
Implementing the private instance methods
Private methods for category Window Creation
Private methods for category Event Handlers
Private methods for category Operations
Copying methods into TimeLogger
Copying methods from Stopwatch
Copying methods from TextEditor
Code for the private instance methods
Opening an instance of TimeLogger
Using TrailBlazer browsers
Loading TrailBlazer
Opening TrailBlazer
Returning to the standard browsers
Example: Using TrailBlazer to create DevelopScreenCapture
Creating an application component for DevelopScreenCapture
Changing prerequisites
Example: Defining the classes ScreenPMCapture and ScreenWinCapture
Creating a subclass
Adding variable declarations
Example: Implementing methods for ScreenPMCapture and ScreenWinCapture
Implementing the private instance methods
Private methods for category Getters & Setters
Private methods for category Initialization
Private methods for category Window Creation
Private methods for category Event Handlers
Private methods for category Image Operations
Opening an instance of the screen capture tool
Categorizing the methods
Copying methods to the other platform-specific class
Example: Enabling a Display Image push button
Inspecting and debugging code
Inspecting objects
Using an Inspector
Inspecting variables
Evaluating expressions in the value pane
Changing variables
Using a Dictionary Inspector
Inspecting some dictionaries in the system
Inspecting your own dictionary
Adding and removing dictionary keys
Adding Keys
Removing Keys
Using a Basic Inspector
Debugging code
Opening a debugger and examining its contents
Determining the cause of an error
Finding errors in evaluated expressions
Finding errors in nonevaluated code
Examining a message stack
Inspecting variables from a debugger
Correcting errors from a debugger
Changing a method in the description pane
Changing an inspected object's variables and values
Adding breakpoints and executing code step-by-step
Adding the message halt
Adding breakpoints using menu options
Modifying breakpoint constraints
Browsing breakpoints
Removing breakpoints
Executing messages individually
Watching value changes
Browsing information on entries in a message stack
Generating an error report
Generating a System Configuration Report
Setting debugger options
Common errors to watch for
Messages not understood
Missing separators
Mismatched brackets or parentheses
Transcript Logging
Transcript Logging menu
Transcript Logging scriptable interface
Handling software components
Moving classes and methods
Moving classes between applications
Preconditions
Steps
Example: Making DevelopStopwatch into an application
Creating the application DevelopStopwatchApp
Moving a class from DevelopStopwatch to DevelopStopwatchApp
Moving methods between classes in the same application
Preconditions
Steps
Moving methods between classes in different applications
Preconditions
Steps
Deleting components
Deleting classes
Prerequisites
Steps
Example: Deleting the class extension from DevelopChooser
Deleting methods
Steps
Deleting applications
Deleting subapplications
Deleting a subapplication from one lineup
Deleting a subapplication from many lineups
Deleting application prerequisites
Deleting a prerequisite from the lineup in your image
Deleting a prerequisite from a lineup not in your image
Deleting a prerequisite from all lineups
Filing out and filing in components
What is the VAST chunk format?
Example: Examining the format of filed-out code
Ensuring that your system is set to the VAST chunk format
Filing out a method
Viewing the method's format in a workspace
Filing out components
Filing in components
Filing in components stored in the generic chunk format
Example: Renaming a class and changing its methods
Filing out ScreenPMCapture in the generic chunk format
Examining the filed-out code
Changing the filed-out code
Filing the changed code into the subapplication DevelopCaptureWin
Monticello Importer
Loading the Monticello Importer
Using the Monticello Importer
What the Monticello Importer does
Monticello Importer Troubleshooting
Missing superclass
Missing base class
Method that won’t compile
Tonel
Loading Tonel
Handling team software components
Loading components from a library
Loading components: The process
Loading classes
Steps
Loading methods
Steps
Loading applications
If you know what application you want to load
If you do not know what application you want to load
Loading subapplications
Preconditions
Steps
Loading configuration maps
Example: Loading a configuration map
Unloading components from your image
Unloading classes
Preconditions
Steps
Unloading applications
Preconditions
Steps
Unloading subapplications
Preconditions
Steps
Unloading configuration maps
Creating new editions of existing components
Creating editions: the process
Creating class editions
Preconditions
Steps
Example: Creating a class edition
Creating application or subapplication editions
Preconditions
Steps
Example: Creating an application edition
Creating configuration map editions
Preconditions
Steps
Displaying configuration map timestamps
Loading other editions of components already loaded
Loading editions: The process
Loading class editions
Steps
Loading method editions
Preconditions
Steps
Loading application editions
Preconditions
Steps
Loading subapplication editions
Steps
Loading configuration map editions
Comparing editions
Comparing applications contained in two editions of a configuration map
Example: Comparing two editions of a single configuration map
Comparing classes contained in two application editions
Comparing methods
Comparing methods used by two class editions
Comparing two editions of one method
Comparing two methods used by one class
Comparing editions of two different configuration maps
Creating versions of components
Creating class versions
Preconditions
Steps
Example: Creating a class version
Creating application versions
Preconditions
Steps
Example: Creating an application version
Creating configuration map versions
Preconditions
Steps
Example: Creating a configuration map version
Versioning and releasing the contained components
Versioning the configuration map
Releasing components
Releasing classes
Preconditions
Steps
Example: Releasing a class
Releasing applications
Preconditions
Steps
Replacing application editions or versions
Adding new applications to a configuration map
Releasing subapplications
Preconditions
Steps
Releasing subapplications into the loaded lineup
Releasing subapplications into several lineups
Grouping applications using configuration maps
Creating configuration maps: The basic steps
Adding new applications
Replacing applications
Deleting applications
Adding, replacing, or deleting applications with TrailBlazer
Adding applications
Replacing applications
Deleting applications
Example: Creating the configuration map Chooser Map
Defining lineups for multiple platforms
Application lineups
Defining application lineups: The process and preconditions
Preconditions
Example: Defining application lineups for OS/2 and Windows
Creating the subapplications DevelopCapturePM and DevelopCaptureWin
Moving platform-specific classes to the subapplications
Releasing the classes to the subapplications
Specifying Boolean expressions for the lineups
Testing lineup expressions in a Workspace
Releasing prerequisites
Releasing platform-specific subapplications
Ensuring that DevelopScreenCapture loads
Replacing subapplications in a lineup
Configuration map lineups
Defining a configuration map lineup: The process and preconditions
Preconditions
Example: Adding a required map to a Chooser Map lineup
Creating Chooser Required Map
Releasing Chooser Required Map into the Chooser Map Lineup
Deleting DevelopmentWidget from Chooser Map
Replacing required map editions or versions in a lineup
Importing components
Preconditions
Importing user objects
Importing class versions
Importing application or subapplication versions
Steps
Importing configuration map versions
Exporting components
Preconditions
Exporting user objects
Exporting class versions
Exporting application or subapplication versions
Steps
Exporting configuration map versions
Setting exporting options
Steps for exporting configuration maps
Attaching non-Smalltalk files
About attachments
Attachment folders
Attachments and stored path names
Attachment types
No versioning of attachments
Opening the Application Attachments browser
Using the Application Attachments browser
Storing attachments
Retrieving attachments
Browsing attachments
Browser menu choices
Folders
Attachments
Stored path names
How stored path names are derived
How stored path names are displayed
Supported platforms and file system types
Performing team system administration
Library operations
Creating libraries
Giving users access to libraries
Adding a user object to a library list
Changing to a different user object
Changing default libraries
Purging and salvaging components
Purging user objects
Purging applications and subapplications
Purging configuration maps
Cloning libraries
Recovering from crashes
Recovering from a file server or EMSRV crash
Recovering from image crashes
What the system checks
Invoking the check for consistency
Recovering lost components
Using the Available Classes menu item
Using the More Recent Editions menu item
Packaging, unloading, and analyzing code
Introduction to packaging
Packaging guidelines
Application prerequisites
Method dispatch
Class/global access
Accessing development environment information
Example: specifying launch code
Implementing the launching method
Files to distribute with your application
Choosing your executable
Simple packaging
What to do before packaging your application
Running the packager
Possible problems
Starting Application
Example: Running the packager
Example: Packaging - saving packaging instructions
Versioning the packaging instructions
Repackaging
Running your packaged image
Problems
Example: Running DevelopChooser
Advanced packaging
Packaging: An overview
Advanced packaging: The process
Summary of packaging steps
Browse Packaged Images
Choose Instructions
Choosing the Packaging Instruction Type
Modify Instructions
Applications and ICs
Startup Code
Policies
Reduce
Examine & Fix Problems
Browse Image Contents Examine & Fix Problems
Save Instructions
Packaging Instructions Application
Output Image
Version packing instructions
Running your packaged image
Setting up to run
Running a packaged image with a User Interface
Running a headless packaged image
Example: Running DevelopChooser
Development Envirionment
VAST Runtime
Making applications "packager friendly"
Application centered packaging
Application packaging hints
packagerIncludeSelectors
packagerKnownSymbols
packagerIncludeClassNames
packagerTranslateSelectors
packagerIgnoreSelectors
packagerIgnoreReferencesInSelectors
Reducing the size of your packaged image
Reducing the number of classes and methods
Avoid unnecessary components
Minimize polymorphism
Create well-structured applications
Minimizing other objects in the packaged image
Finding and removing hidden data
Discarding unnecessary components from base Smalltalk classes
Avoiding unnecessary references to pool dictionaries
Troubleshooting
Exit due to error: 33--Could not open image file
Could not open image file
Exit due to error: 37--Image file is not an image
Does Not Understand errors
Problems during packaging
Output file path
Saving your image
Duplicate object error when packaging
Packaging Statistics
Automated Build Support
AbsBuildSpecification
Public Attributes available for defining an AbsBuildSpecification:
Public Actions:
Validations and Logging
Build Artifacts Output
Unloading ENVY/App image components
Limitations
Unloading specific components
Applications
Example: Unloading an application and its subapplication
Classes
Example: Unloading one class
Example: Unloading a class and its subclasses
Example: Unloading many classes
Compiled methods
Example: Unloading one method
Example: Unloading many methods
Class variables
Example: Unloading a class variable with its current value
Example: Unloading a class variable with a specific value
Class instance variables
Example: Unloading class instance variables
Shared pool variables
Example: Unloading shared pool variables
Global variables
Example: Unloading global variables
Unlinking all instances of a specific class
Example: Unlinking all instances of a class
Unlinking all instances of a specific method
Excluding version information
Setting the image startUp class
Running code at load time
Example: Specifying the class and selector to be run
Packaging with image components (ICs)
About ICs
Image components (ICs) and their benefits
Reducing the memory footprint
Facilitating incremental development
Image components as compared to DLLs
The structure of ICs within an application
IC dependencies
Relationship of ICs to applications
IC usage architecture
Pure ICs
Image file with ICs
Explicit binding and unbinding
The process of loading ICs
Explicit loading of ICs
Removing ICs
Initializing an IC
Things to Consider: When to use ICs
General issues
Making maintenance easier
Reducing memory footprint
Minimizing memory footprint during IC loading
Packaging preparation
Step-by-step examples building VA Smalltalk ICs
Creating a leaf IC
Creating a reusable and a leaf IC
Creating a reusable IC
Creating a leaf IC
Test ICs
Creating ICs to be explicitly loaded
Desktop Launcher IC
Creating a platform-dependent IC
Creating the Windows subapplication
Adding a config expression for a Windows subapplication
Creating the OS/2 subapplication
Adding config expressions for OS/2 subapplications
Creating the ICs
Windows leaf IC
OS/2 leaf IC
Implementation issues and tips
Understanding packaging instruction classes
Snapshot classes and snapshot IDs
How snapshot files are located
Caches
Troubleshooting
Exit due to error: 33--Could not open image file
Exit due to error: 37--Image file is not an image
Problems during packaging
Output file path
Saving your image
Duplicate object error when packaging
Prerequisite ICs
Side effects of using the -r command line option
Error attempting to load into a read-only object
Primitive failures during explicit IC loading
Errors during IC packaging
Reference to excluded pool
Excessive packaging time
Evaluation images
Runtime error at startup
Development image fails to start-up (Error 33)
Loading and unloading ICs
Customizing the icon and splash screen
Changing the program icon on Windows
Providing a customized splash screen
Displaying the splash screen longer
Swapping objects between disks and images
Getting started
Simple object loading and unloading using files
Object loading and unloading using streams
Features of the Swapper
Basic features
Advanced features
Using the Swapper
Simple object loading and unloading
Object replacement
Dumping replacement
Object-identity-based replacement
Class-based replacement
Instance-variable-based replacement
Loading replacement
Combining dumping and loading replacement
Another look at "Redefining methods to implement class-based replacement"
Summary on replacement
Object mutation
Mutation of loaded instances
Requirements for object mutation
Loading objects whose instance variable names have been renamed
Loading objects whose classes have been renamed
Overriding default object mutation code
Application considerations
CompiledMethods
Classes and Metaclasses
Special object considerations
Rehashing of collections
Limitations
Error processing
Where errors are generated
API methods that return error codes
Obsolete API methods that return error codes
Error codes and their expected error objects
Debugging Swapper operations
The Swapper framework
Replacers and strategies as first class objects
Why replacers and strategies?
Dumping replacers
Loading replacers
When to define your own strategies
Resolving method conflicts
Analyzing the runtime performance of code
Quickly determining how long it takes code to run
Example: Having millisecondsToRun: display your code's run time
Analyzing code using the Benchmark Workshop
Writing the bench method
Inherited instance variables
Timing sections of code
Advantages of bench methods
Overview of the Benchmark Workshop
The tool bar
The work area
The execution buttons and benchmark list
The text pane
The line graph
The results bar graph
The status line
Executing the bench method
Preparing to execute the bench method
Specifying the mode of execution
Running a bench method [R]
Sampling a bench method [S]
Tracing a bench method [T]
Stabilizing the benchmark
Factors that affect stability
Factors beyond the control of the Stats tool
Viewing the results
Filtering raw time
Comparing benchmarks
Storing, loading, and clearing benchmarks
Browsing the time distribution
Browsing the method execution
Total time and local time
The methods list and execution tree
Limitations when sampling [S]
Optimizing Smalltalk code
The rules for optimizing Smalltalk code
Run less code
Send fewer messages
Avoid expensive operations
Run your code--not the garbage collector
Using a Memory Monitor
Types of memory space that you can monitor
Interpreting the Memory Monitor display
Using a Memory Use Report
Memory usage by application, class, and method
Memory usage by application, class, and method
Memory usage during execution
Setting up, customizing, and extending the system
Using and maintaining configuration (.ini) files
.INI file syntax
.INI file contents
Library access stanza
Examples
EMSRV example
File I/O example
Image component (IC) mapping stanza
CommonGraphics stanza
NLS and Locale stanzas
Feature Load stanza
Kernel stanza
Virtual machine options stanza
SocketCommunicationsInterface stanza
PlatformLibrary name mappings stanza
Development Tools stanza
Printing stanza
Preference Settings Framework
Settings Framework API
Application Public Class Methods (modifiable)
Application Public Class Methods (delegated)
Application Public Class Methods
Number, subclass of Number, and Point Public Class Methods
Examples
Executing scripted Smalltalk code during image start up
Ex: pre and post startup
Ex: Load code
Ex: Test code library size
Ex: Automate packaging
Setting up Smalltalk images
Using Preferences Workspace to configure images
Example: Evaluating an expression to change a setting
What Is the VAST chunk format?
Changing the setting to false
Verifying that the setting changed
Extending the system
Changing Transcript menus
Methods that add or remove menus
Example: Adding a Transcript menu
Extending Browser Menus
Adding to browser menus
Adding items to main menus
Adding items to submenus
Controlling menu visibility
Application initialization
Application behavior when starting and stopping the system
Example: Using startUp to open DevelopChooser when the system starts
Application behavior when Windows Power Management events occur
User fields
Stored objects
Storing versions of objects in object stores
Index
Smalltalk User Guide
Index