1. Getting Started with Topaz

Next chapter

Topaz is a programming environment for GemStone/S 64 Bitâ„¢ that provides command-line access to the GemStone system. Topaz does not require a windowing system, and so is a useful interface for batch work and for many system administration functions.

This chapter explains how to run Topaz and how to use some of the most important Topaz commands.

To run Topaz, GemStone/S 64 Bit must be installed on your system. You must have an running repository monitor (Stone) that is the same version of GemStone as Topaz, and in some cases an accessible network service process (NetLDI). The GemStone/S 64 Bit Installation Guide explains how to install these components.

Your environment must contain a definition of the $GEMSTONE environment variable and your execution path should include the GemStone binary directory $GEMSTONE/bin. Consult your system administrator if you need help with this.

Examples throughout this book were created on a UNIX system. Topaz is also available with the GemStone/S 64 Bit Windows Client distribution, which allows Topaz to run on Windows, logging in remotely to a GemStone server running on UNIX. Topaz on Windows cannot login in linked mode, nor with a Gem session on Windows. Otherwise, Topaz operates similarly on UNIX and Windows. Differences are noted in the text.

1.1  Getting started with Topaz

Topaz provides an environment in which you can get a GemStone session and use that session to find out information about GemStone, and to execute Smalltalk code. To perform any server interaction, you must first log in. All server interaction is performed using the logged-in session. The sessions that Topaz uses are the same as sessions acquired via any other GemStone interface, such as GemBuilder for Smalltalk

Overview of a GemStone Session

A GemStone session consists of four parts, as shown in Figure 1.1. These are:

  • An application, in this case, Topaz.
  • One repository and repository monitor (Stone), and the associated server processes. An application has one repository to hold its persistent objects.
  • At least one GemStone session, or Gem process. All applications, including Topaz, must communicate with the repository through Gem processes. A Gem provides a work area within which objects can be used and modified. Several Gem processes can coexist, communicating with the repository through a single Stone process.
Figure 1.1   GemStone Object Server Components

 

Remote Versus Linked Versions

Figure 1.1 includes the two types of topaz sessions -- Remote Procedure Call (RPC) and Linked. With a Topaz RPC login, the Topaz application and the Gem session that provides the repository services exist in two separate processes. In a linked login, the Topaz application process includes the Gem session. These two types of sessions and configuration details are described in more detail in the System Administration Guide for GemStone/S 64 Bit.

To allow control over the use of linked logins, GemStone client libraries and Topaz provide separate versions; one which allows RPC logins only, the other allowing Linked and RPC.

  • Topaz RPC is the default, although you may specify the -r command line argument. You can run multiple RPC sessions from the Topaz RPC executable, but linked sessions are not possible.
  • Topaz Linked requires specifying the -L or -l command line argument to topaz. You can run a single linked session and multiple RPC sessions from the linked topaz executable.

In Figure 1.2, notice that the Topaz startup banner’s PROGRAM line refers to Remote Session. In a linked login, it will say Linked Session.

Under Windows, only the RPC version of Topaz is available. The Gem, which is part of the server code, can only run on a server platform.

The examples in this chapter can be executed equally well from either linked or RPC Topaz.

For additional command-line options, see Appendix A.

Invoking Topaz

To invoke Topaz, simply type topaz on the command line. The program responds by printing its copyright banner and issuing a prompt, as shown in Figure 1.2.

Figure 1.2   Topaz Banner and Prompt

unix> topaz
 ___________________________________________________________________________
|             GemStone/S64 Object-Oriented Data Management System           |
|               Copyright (C) GemTalk Systems 1986-2019                     |
|                            All rights reserved.                           |
+---------------------------------------------------------------------------+
|    PROGRAM: topaz, Linear GemStone Interface (Remote Session)             |
|    VERSION: 3.5.0, Mon Jan 28 14:47:21 US/Pacific 2019                    |
|      BUILD: 64bit-48440                                                   |
|  BUILT FOR: x86-64 (Linux)                                                |
| RUNNING ON: 4-CPU benton x86_64 (Linux 3.2.0-58-generic #88-Ubuntu SMP Tue|
| Dec 3 17:37:58 UTC 2013)                                                  |
|  PROCESSOR: 4-core Intel(R) Xeon(R) CPU W3565 @ 3.20GHz (Bloomfield)      |
|     MEMORY: 18057 MB                                                      |
| PROCESS ID: 27630     DATE: 02/03/19 15:41:54 PST                         |
|   USER IDS: REAL=gsuser (534) EFFECTIVE=gsuser (534) LOGIN=gsuser (534)   |
|___________________________________________________________________________|
topaz>
 

Topaz Commands

Topaz interaction is performed by sending commands. Each command begins with a keyword, and may have optional or required arguments. Some commands are only meaningful in certain contexts. Chapter 3 provides a list of the commands you will be using and the options and arguments for each command.

The first thing you will do is use the set command to provide login parameters, and use the login command to perform the login to GemStone. This is described in more detail in the next section.

The commands and keywords in Topaz are case-insensitive; so for example, the command login can be entered as LOGIN or Login. Arguments to topaz commands, however, such as user names or the names of Smalltalk classes, will follow their specific rules for case sensitivity.

You can abbreviate many Topaz command to uniqueness, so for example you can type log instead of login. Some commands such as logout may not be abbreviated, to avoid accidental use.

To enter an argument to a Topaz command that includes white space, enclose it within single quotes. For example, a username such as 'Issac Newton' requires quotes, while Issac_Newton does not.

Normally, each topaz command is on a separate line, and the command is terminated by the return at the end of the line. For most commands, you can include multiple topaz commands on a single line by separating each expression with a semicolon (;), however, commands that interpret the rest of the line in specific ways, such as run, do not allow this usage. Commands may not be longer than 64K characters.

Any text following a command that does not have arguments is ignored; topaz will print a warning to that effect after executing the valid portion of the line.

Logging In to GemStone

The first step in establishing a connection to GemStone and logging in is to give Topaz some information about the GemStone repository you will be using. To log in to the repository you must provide a GemStone user name and password.

The examples given here will be for RPC logins. Linked logins are similar. These examples also assume that the GemStone server configuration requires authentication in order to start the Gem session. This may not always be the case; see Configurations that do not require setting host information.

Note
This section does not apply to X509-Secured GemStone, which takes a completely different set of login parameters. Logins using X509-Secured GemStone are described in the GemStone/S 64 Bit X509-Secured GemStone Administration Guide.

Here are the parameters to be established to log in to GemStone through Topaz:

  • GemStone name. This the name of the Stone process to use and, optionally, the name of the network node on which it resides. The default name is gs64stone. If your Stone process is named gs64stone and is running on the local node, and the Gem process will also run on the local node, you don’t have to set the GemStone name.

Otherwise, specify the name of the Stone. If the node where the Stone is running is not the one where the Gem will run, you also need the name of the Stone host and perhaps the type of network connection between the Stone and Gem hosts. To specify a process named gs64stone running on node central, you can use a network resource string of the form !@central!gs64stone.

For details on using NRS and NRS syntax, see the System Administration Guide for GemStone/S 64 Bit.

This is configured using the set command: set gemstone stonename.

  • GemStone user name and password. These are defined within the GemStone server. You can log in using your personal username and password, created by your GemStone Administrator, or as predefined GemStone system users such as DataCurator. You may enter the user name and omit the password, in which case you will be interactively prompted for the password.

These are configured using the set command: set username gemStoneUserName and set password gemStoneUserPassword. You may abbreviate and combine them as
set user gemStoneUserName pass gemStoneUserPassword.

The default password for predefined GemStone users such as DataCurator is swordfish. However, it is strongly recommended that this is changed, to provide some basic system security.

  • host user name and password. The UNIX name and password for the account on the server that will own the Gem process. This are needed only for RPC sessions, and only if the NetLDI is configured to require this for authentication. You may enter the host user name and omit the host password, in which case you will be interactively prompted for the host password.

These are configured using the set command: set hostusername osUserName and set hostpassword osPassword. You may abbreviate and combine them as
set hostuser osUserName hostpass osPassword.

This is set using the command set hostusername and hostpassword.

  • GemStone service name. For the RPC version the default is gemnetobject. You may also use gemnetdebug, if you are debugging memory issues, or the name of a customized version of the gemnetobject script that you have created.

For the linked version of Topaz, do not set gemnetid, nor set the gemnetid to ''.

NOTE
If you are running the linked version of topaz, and set gemnetid to gemnetobject, all your sessions will be RPC, in spite of having invoked the linked version. Use -L to start linked topaz to avoid this issue.

The GemStone service name is configured using the set command: set gemnetid serviceName.

The gem service can be provided an NRS, in order to specify that the Gem process is running on a remote node. To do this, for the gemnetid, specify a network resource string (NRS) of the form !@<remoteNode>#netldi:<netldiName>!gemnetobject.

For example,

!@lark.gemtalksystems.com#netldi:gs64ldi!gemnetobject.

Additional NRS directives and gemnetobject arguments can be included. For details on using NRS and NRS syntax and the gemnetobject utility, see the System Administration Guide for GemStone/S 64 Bit.

Use the Topaz set command to establish these parameters. For example:

topaz> set gemstone gs64stone
topaz> set username Isaac_Newton

For RPC login, you may need to also provide the host login credentials:

topaz> set hostusername newtoni
topaz> set hostpassword
Host Password? (Type your host password; it won’t be echoed)

To see your current login settings and other information about your Topaz session, type status:

topaz 1> status
 
Current settings are:
 display level: 0
 byte limit: 0 lev1bytes: 0
 omit bytes
 include deprecated methods in lists of methods
 display instance variable names
 display oops   omit classoops   omit stacktemps
 oop limit: 0
 omit automatic result checks
 omit interactive pause on errors
 omit interactive pause on warnings
 listwindow: 20
 stackpad: 45
 tab (ctl-H) equals 8 spaces when listing method source
 transactionmode  autoBegin
 using line editor
   line editor history: 100
   topaz input is from a tty on stdin
EditorName________ vi
CompilationEnv____ 0
Source String Class String
fileformat          8bit (tty stdin is utf8)
SessionInit         On
EnableRemoveAll     On
CacheName_________ 'Topaz'
 
Connection Information:
UserName___________ 'Isaac_Newton'
Password __________ (set)
HostUserName_______ 'newtoni'
HostPassword_______ (set)
NRSdefaults________ '#netldi:gs64ldi'
GemStone___________ 'gs64stone'
GemStone NRS_______ '!#encrypted:newtoni@password#server!gs64stone'
GemNetId___________ '!#encrypted:newtoni@password!gemnetobject'
 
Browsing Information:
Class_____________
Category__________ (as yet unclassified)
 

If you are logging in linked, certain login parameters (HostUserName and HostPassword) have no effect. Setting GemNetId will result in an RPC login.

If any login settings are incorrect, use the set command to fix them.

You are now ready to issue the login command, connecting your Topaz session to the GemStone repository:

topaz> login
GemStone password? (type your GemStone password)
[02/06/2019 21:48:38.994 PST]
  gci login: currSession 1  rpc gem processId 1363 socket 6
successful login
topaz 1>

As this example shows, Topaz displays a session number in its prompt once you have logged in. In the topaz RPC version, these numbers start with 1. In the linked version of topaz, session 1 is the linked session, and the RPC session numbering starts with session 2.

You may supply several of these login parameters on a single command line in any order, and abbreviate the parameter names:

topaz> set gemstone gs64stone user Isaac_Newton pass gravity
topaz> set hostuser 'newtoni'
topaz> set hostpass <return>
Host Password? (type your host password)
topaz> login
[02/06/2019 21:48:38.994 PST]
  gci login: currSession 1  rpc gem processId 1363 socket 6
successful login
topaz 1> 

Because setting the host user name causes Topaz to discard the current host password, you must set hostusername before hostpassword.

If you are using the linked version of Topaz, you can login with fewer set commands:

topaz> set gemstone gs64stone user Isaac_Newton pass gravity
topaz> login
[Info]: LNK client/gem GCI levels = 35001/35001
--- 02/06/2019 21:48:38.834 PST Login
[Info]: User ID: Isaac_Newton
[Info]: Repository: gs64stone
[Info]: Session ID: 5
[Info]: GCI Client Host: <Linked>
[Info]: Page server PID: -1
[02/06/2019 21:48:38.994 PST]
  gci login: currSession 1  linked session 
successful login
topaz 1>

Configurations that do not require setting host information

You do not always have to enter the hostusername and hostpassword for logins.

For RPC logins, if the NetLDI that you are using to login is running in guest mode with captive account, you do not need to specify hostusername or hostpassword. Your gem will run according the account specified in the NetLDI.

More information on netldi modes can be found in the System Administration Guide for GemStone/S 64 Bit.

Setting Up a Login Initialization File .topazini

You can streamline the login process by creating an initialization file that contains the set commands needed for logging in. When you invoke Topaz, it automatically executes those commands for you. If you insert set hostpassword and login commands without parameters, Topaz automatically prompts you for the necessary values.

Table 1.1 Topaz Initialization File Names

Platform

Name of Topaz Initialization File

Locations searched for
initialization file

UNIX

.topazini

Current directory, then user’s home directory

Windows

topazini.tpz

Current directory, then user’s home directory. If home directory is undefined, uses home directory of the account that started Windows, if any, or C:\users\default.

You may also explicitly specify a path for a topazini file on the command line where you started up the Topaz executable. Using this option overrides any topazini files that Topaz would otherwise use.

% topaz -I /gemstone/utils/mylogin.topazini

If you want to run Topaz non-interactively, you must explicitly specify both the GemStone and host passwords in this initialization file.

CAUTION:
Entering your passwords in a file can pose a security risk.

The Topaz initialization file shown in Figure 1.3 performs most of the same functions as the interactive commands shown in the previous discussion.

Figure 1.3   Topaz Initialization File

set gemstone gs64stone
set username Isaac_Newton
set password mypassword
set hostusername 'newtoni'
set hostpassword hostpassword
login
 

If you choose not to include your password in an initialization file, Topaz will start up with the following prompt.

GemStone Password?     Type your password. It will not be echoed.
topaz 1>

Error handling and output

Commands that are executed from a login initialization file are not echoed to the display. However, if an error occurs, the output is reported to the topaz display, so you can determine the cause of the problem. In this case, the password and host password are struck out, for security.

Alternatives to automatic initialization

If a topaz initialization file exists in one of the search directories, it will be executed each time topaz is started. You can prevent this by starting Topaz using the -i argument, which suppresses loading of an initialization file.

You can also explicitly provide the initialization file to use on the topaz command line, by using the -I command, passing in the name of the initialization file. If you name your file other than the default, or locate this file in a directory other than the ones searched for, you can control the specific one you wish to load.

This also allows you to have multiple initialization files for different uses.

See Appendix A for more details on command line options.

Special care needed when setting gemnetid in .topazini

Use caution in including commands to set the gemnetid in a .topazini file. For example, using a line such as:

set gemnetid gemnetobject

The .topazini file is executed for RPC topaz, and for linked topaz started using the -l option. If this line is present in a .topazini file, and that .topazini file is executed by topaz -l, the effect is to turn the linked login into an RPC login.

When linked topaz is started using the -L option, set gemnetid commands in .topazini files are ignored. For this reasons, using -L rather than -l is recommended. Otherwise there is no difference between starting linked topaz using topaz -l vs. topaz -L.

For more on the behavior of gemnetid in linked and RPC topaz, see under gemnetid.

Multiple Concurrent GemStone Sessions

Topaz can keep several independent GemStone sessions alive simultaneously. This allows you to switch from one session to another, for instance to access more than one GemStone repository. Both RPC and linked versions of Topaz allow you to run multiple sessions by using the login and set session commands; however, you can only have one linked session at a time. While you can login both RPC and linked session from the linked version of topaz, the RPC version of topaz does not allow linked sessions.

Multiple sessions in the RPC version of Topaz

The following example shows how you might login a second session to a different GemStone server, make the new session your current session, then return to the original session. With the RPC version of Topaz, all sessions are always RPC.

topaz> login
[02/06/2019 12:34:02.292 PST]
 gci login: currSession 1 rpc gem processId 95
successful login
topaz 1> set gemstone !@srv2!gs64stone
topaz 1> set username Isaac_Newton
Warning: GemStone is clearing previous GemStone password.
GemStone password? <password typed here but not echoed> 
topaz 1> login
[02/06/2019 12:34:05.548 PST]
 gci login: currSession 2 rpc gem processId 141
successful login
topaz 2> printit
UserGlobals at: #myVar put: 1
%
1
topaz 2> set session 1
topaz 1>

Multiple sessions in the Linked version of Topaz

If you use the topaz -L or -l command to invoke Topaz, you may run multiple sessions, but only one of them may be linked. Normally, this is the first session that logs in. In order to run two sessions, you must specify a value for gemnetid, and provide OS credentials if your server configuration requires this, so you can get an RPC login.

If you are running linked topaz, and you first login an RPC session, then wish to login the linked session, you will need to clear the setting for gemnetid. For example:

topaz> set gemnetid gemnetobject
topaz> login
GemStone password? <password typed here but not echoed> 
[02/06/2019 14:40:49.338 PST]
  gci login: currSession 1  rpc gem processId 31427 socket 6
successful login
topaz 2> set gemnetid ''
topaz 2> login
[Info]: LNK client/gem GCI levels = 35001/35001
--- 02/06/2019 14:37:56.603 PST Login
[Info]: User ID: DataCurator
[Info]: Repository: gs64stone
[Info]: Session ID: 5
[Info]: GCI Client Host: <Linked>
[Info]: Page server PID: -1
[Info]: Gave this VM preference for OOM killer, Wrote to
/proc/4458/oom_adj value 250
[02/06/2019 14:37:56.609 PST]
  gci login: currSession 1  linked session 
successful login
topaz 1>

The messages displayed during login indicate if the session is linked or RPC.

Topaz sessions vs. GemStone sessions

Notice that the Topaz prompt always shows the number of the current session. These sequential session numbers are assigned by your individual Topaz environment, and do not correspond to the session numbers that are assigned by the GemStone server to each logged-in session.

To get a list of current GemStone sessions and the users who own them, you can execute the GemStone Smalltalk expression System currentSessionNames. For example:

topaz 1> printit
System currentSessionNames
%
session number: 2 UserId: GcUser
session number: 3 UserId: GcUser
session number: 4 UserId: SymbolUser
session number: 5 UserId: DataCurator
session number: 6 UserId: Isaac_Newton
session number: 7 UserId: Isaac_Newton
session number: 8 UserId: Gottfried_Leibniz

The GcUser session (or sessions) represent the garbage collection processes that usually (though not always) operate when GemStone is active. The SymbolUser session represents the process that administers Symbols to ensure canonicality.

This list includes all sessions that are currently logged into the GemStone system, not only the sessions within your Topaz environment.

Transaction state

GemStone is a transactional system. The process of making persistent changes in the GemStone repository require that you begin a transaction, make the changes, then commit the transaction.

To make this easier, GemStone provides automatic transaction mode (autoBegin). In this mode, the session is always in transaction. Each commit or abort automatically starts a new transaction.

When you login through Topaz, your session is in automatic transaction mode. This allows you to make changes and commit them without having to explicitly start a transaction.

However, being in transaction on a system in which other users are also committing changes incurs a risk. GemStone must maintain your transactional view of the repository as long as you are in the transaction and do not commit or abort. These commit records require space in the repository, and in a rapidly changing system, an idle session in transaction can create a “commit record backlog”. Under worst-case conditions, this can cause the repository to fill up with this old data, run out of space, and shut down. If you are logging into a system that is in use, avoid remaining logged in and idle.

If you use topaz to log into a multiple-user system, you may wish to configure your system to default to not being in a transaction; this mode is manual transaction mode (manualBegin). In manual transaction mode, you are out of transaction until you explicitly begin a transaction (either by the begin command, or by executing a Smalltalk expression such as System beginTransaction), and when you commit, your session becomes out of transaction.

You can set topaz to be in manual transaction mode:

topaz> set transactionmode manualBegin
no transaction was in progress, transaction mode changed to manualBegin

Note that if you are logged in, using this command will abort any transaction in progress, so it is better to execute this before login. You may wish to add this to the .topazini initialization file; see details starting here.

You can also change the default for the entire system, by using the Stone configuration parameter STN_GEM_INITIAL_TRANSACTION_MODE. This sets the initial transaction mode for all sessions logging in, and may be particularly beneficial in production systems in which an inadvertent login can create problems.

See the System Administration Guide for GemStone/S 64 Bit for more information on managing transactions, handling sigAborts, and configuring STN_GEM_INITIAL_TRANSACTION_MODE.

WARNING
Idle topaz sessions should not be left in transaction in active multi-user systems. Even if the session is not in transaction and does not cause serious problems, your stale commit record requires extra work for the stone, and sessions may be terminated.

Other Types of Logins

X509-Secured

The GemStone server supports both traditional password-based login, and X509 secured certificate-based logins. These two types of login use a disjoint set of login parameters. When any of the traditional login parameters are set, all the X509 login parameters are unset, and vice versa. When you intend to authenticate using X509 certificates, do not set any of the following: username, password, hostusername, hostpassword, gemstone, gemnetid, or solologin

For X509 login, the following are required: cert, cacert, key, netldi

and the following are optional: logfile, directory, and extragemargs

You must also create the appropriate keyfiles, and have a Stone that is running with a keyfile that allows X509 logins.

X509-Secured topaz and other logins are described in detail in the X509-Secured GemStone System Administration Guide.

Solo Scripting

Topaz supports login without a running Stone, for scripting. See Topaz Solo for Scripting.

 

Multiple Execution Environments

The GemStone server has multiple compilation/execution environments available, which define separate environments for method lookup and code execution.

The default, and the location of the GemStone kernel, is environment 0. Most applications will only use environment 0 and can disregard references to execution environments.

The environmentId is set using commands:

set compile_env: anInteger
env anInteger

Most topaz commands operate on the current environment, and many accept an optional argument specifying the environmentId; see the command comments for exceptions.

1.2  Interacting with Topaz

The Help Command

You can type help at the Topaz prompt for information about any Topaz command. For example:

topaz 1> help time
TIME
 
The first execution of TIME during the life of a topaz
process displays current date and time from the operating
system clock, total CPU time used by the topaz process.
 
Subsequent execution of TIME will display in addition
elapsed time since the previous TIME command, CPU time used
by the topaz process since the previous TIME command.
 
Topic?

You may enter further help topics at the Topic> prompt.

The enter key brings you back to the topaz command prompt.

For a full list of help topics, use help without specifying an argument.

Interrupting Topaz and GemStone

The Ctrl-C key combination interrupts Topaz and GemStone:

  • When Topaz is awaiting input from your terminal, such as when you’re entering a command, you can enter Ctrl-C to terminate entry of the command and prepare Topaz for accepting a new command.
  • When GemStone is compiling or executing some GemStone Smalltalk code sent to it by Topaz, such as in a printit command, typing Ctrl-C sends a request to GemStone to interrupt its activities as soon as possible. GemStone stops execution at the conclusion of the current method, and Topaz displays the message: A soft break was received.

Logging Out

To log out from your current GemStone session, just type logout.

topaz 1> logout
topaz>

Logging out implicitly aborts your transaction.

Leaving Topaz

To leave Topaz and return to your host operating system, just type exit:

topaz> exit

If you are still logged in when you type exit, this will implicitly abort all your transactions and log out all active sessions.

You can also use quit, which has the same effect as exit.

1.3  Executing GemStone Smalltalk Expressions

There are a number of commands allowing you to execute Smalltalk expressions: run, printit, doit, and exec. The following use of printit, for example, creates an instance of DateTime representing the current Date and Time:

topaz 1> printit
DateTime now
%
a DateTime
  year                2019
  dayOfYear           38
  milliseconds        83048864
  timeZone            a TimeZone

All of the lines after the printit command and before a line in which % is the first character are sent to GemStone for execution as GemStone Smalltalk code. Topaz then displays the result and prompts you for a new command.

The doit, run, and printit commands differ in the way the output is displayed; this is described in the next section.

The exec command allows the expression to be entirely on one line, which can improve readability of input and output files when there are many brief lines to be executed. For example:

topaz 1> exec DateTime now %
a DateTime
  year                2019
  dayOfYear           38
  milliseconds        67995686
  timeZone            a TimeZone

If there is an error in your code, Topaz displays an error message instead of a legitimate result. You can then retype the expression with errors corrected, or use the Topaz edit function to correct and refine the expression.

Strings vs. Unicode strings

GemStone Smalltalk supports two set of string classes; traditional Strings, including String, DoubleByteString and QuadByteString; and Unicode strings, including Unicode7, Unicode16, and Unicode32. Traditional Strings are native GemStone, while Unicode strings rely on the ICU libraries to provide sophisticated national language support. Both sets of string classes support the full Unicode character range. String classes are described in more detail in the Programming Guide for GemStone/S 64 Bit.

When you execute a Smalltalk expression in Topaz that creates a string object, the class of this object depends on the Topaz setting for SourceStringClass. The default is String, in which case a traditional string is created, of the lowest order in which all Characters of the result can be contained. Or it can be set to Unicode16, in which case a Unicode string is created, either a Unicode7, Unicode16, or Unicode32.

topaz 1> set sourcestringclass unicode16
topaz 1> display oops
topaz 1> exec 'hello' %
[4582145 sz:5 cls: 154369 Unicode7] hello

For further details, see sourcestringclass.

When a repository is in Unicode Comparison Mode, topaz detect this on login, and automatically changes the sourcestringclass to Unicode16, and the fileformat to utf8, and prints a message on this change on the topaz console. See the Programming Guide for GemStone/S 64 Bit for details on Unicode Comparison Mode.

Controlling the Display of Results

The result of the Smalltalk expression is returned to Topaz, and this object is displayed on the topaz console. Topaz provides several options to allow you to control the level of detail that is displayed for the object .

Display Level

When Topaz displays a result object, it always displays the object itself, but the display of the name and value of each instance variable is controlled by the level and the specific command used to execute the code.

A level of 0 displays only the object itself; level 1 displays the object and its instance variables, level 2 include the instance variables of the instance variables of the object, and so on.

The printit command always displays results with level 1:

topaz 1> printit
DateTime now
%
a DateTime
  year                2019
  dayOfYear           38
  milliseconds        83048864
  timeZone            a TimeZone

This display is one level deep: the instance variables are displayed, but not the instance variables of any complex objects in the instance variable values.

The doit command displays 0 levels:

topaz 1> doit
DateTime now
%
02/06/2019 15:04:35

You can set the level explicitly using the level command, and the run command will use the current level setting to display the results.

For example, with level 0, the run command produces the same display as the doit command:

topaz 1> level 0
topaz 1> run
DateTime now
%
02/06/2019 15:05:23

Setting the level to 2 would give this view:

topaz 1> level 2
topaz 1> run 
DateTime now
%
a DateTime
  year                2019
  dayOfYear           38
  milliseconds        83121913
  timeZone            a TimeZone
    transitions         an Array
    leapSeconds         nil
    stream              nil
    types               nil
    charcnt             nil
    standardPrintString PST
    dstPrintString      PST
    dstStartTimeList an IntegerKeyValueDictionary
    dstEndTimeList      an IntegerKeyValueDictionary
 

As you can see, setting the display level to 2 causes Topaz to display each instance variable for the objects that are within each of DateTime’s instance variables. The maximum display level is 32767.

If the display level setting is high enough and the object to be displayed is cyclic (that is, if it contains itself in an instance variable), Topaz will faithfully follow the circularity, displaying the object repeatedly.

Setting Limits on Object Displays

By default, Topaz attempts to display all of a result, no matter how long. So for example if an expression returns a collection, every item in the collection will be displayed.

The limit oops controls how much Topaz displays of pointer or NSC objects, such as Arrays and Sets, that come back as a result. Similarly, limit bytes command controls how much Topaz displays of a byte object (instance of String or one of String’s subclasses) that comes back as a result. To avoid

The following example shows how you could use limit bytes to make Topaz limit the display to the first 4 bytes:

topaz 1> limit bytes 4
topaz 1> printit
'this and that'
%
this
...(9 more bytes)

Setting the limit to 0 restores the default condition.

Displaying Variable Names, OOPs, and Hex Byte Values

Two complementary commands, display and omit, control some features of how objects are displayed in topaz. For more details on the options, see DISPLAY.

OOP Values

It’s useful in debugging to be able to examine the numeric object identifiers that GemStone uses internally. If you tell Topaz to display oops, it prints a bracketed object header with each object, which looks like this:

[21336065 sz:3 cls: 110849 Symbol]

Each object header contains:

  • The object’s OOP (a 64-bit unsigned integer)
  • the object’s size, calculated by summing all of its named, indexed, and unordered instance variable fields
  • the OOP of the object’s class and the class name

For example:

topaz 1> display oops
topaz 1> printit
DateTime now
%
[42370305 sz:4 cls: 118785 DateTime] a DateTime
  year         [16138 sz:0 cls: 74241 SmallInteger] 2019 == 0x7e1
  dayOfYear    [2266 sz:0 cls: 74241 SmallInteger] 38 == 0x11b
  milliseconds [594793738 sz:0 cls: 74241 SmallInteger] 74349217 == 0x46e7aa1
  timeZone     [10528513 sz:12 cls: 13530113 TimeZone] a TimeZone

You can turn off the display of OOPs by typing omit oops at the Topaz prompt.

Hexadecimal Byte Values

Topaz ordinarily displays byte objects such as Strings literally, with no additional information. If you enter display bytes Topaz includes the hexadecimal value of each byte. For example:

topaz 1> display bytes
topaz 1> printit
'this and that'
%
1 'this and that' 74 68 69 73 20 61 6e 64 20 74 68 61 74

Entering omit bytes restores the default byte display mode.

Committing and Aborting Transactions

To commit a transaction while using Topaz, you can execute the GemStone Smalltalk expression System commitTransaction within a printit command, or you can enter the Topaz commit command:

topaz 1> commitSuccessful commit

Similarly, you abort a transaction by executing the GemStone Smalltalk expression System abortTransaction within a printit command, or by entering abort at the Topaz command prompt. Entering abort does not reset Topaz system definitions, such as your current class and category.

The topaz command begin, or executing System beginTransaction, may also be used to begin a transaction if you are not in automatic transaction mode, or to abort your transaction.

Although you can abbreviate most Topaz commands and parameter names, commit, abort, and begin (as well as some others such as quit and exit) must be typed in full.

Importing files: topaz commands and GemStone code

The Topaz interactive environment takes its input from standard input, such as your terminal. You can also use the input command to make Topaz take its input from a file. Topaz treats the lines in the input file as if they were entered on the command line; this file may contain commands to perform work, or code to be filed in; there is no difference.

For example, the following command, would make Topaz read and execute the commands in a file called animal.gs in your UNIX $HOME directory:

topaz 1> input $HOME/animal.gs

The UNIX environment variable $HOME is expanded to the full filename before the input command is carried out.

When you have code that was filed out of GemStone, the input command allows you to load this code into another Stone. You will need to check for errors and commit to make the code persistent.

topaz 1> input $HOME/animal.gs
<input by default echos all input>
topaz 1> errorcount
0
topaz 1> commit
Successful commit

Batch processing goes very quickly. It is a good idea to record your topaz session to a file, use output push, so you can check for errors. This is described starting here.

Handling text outside the ASCII range

Character with codepoints between 128 and 255 are outside the ASCII range, but the codepoints only require one byte. Since UTF-8 encoding is identical only for characters with up to 7 bits, how Characters in this range are encoded in a text file or paste buffer depends on how your system is configured.

If all your code and text file contents, and all commands entered via scripts, are limited to the ASCII range, there is no difference in behavior and your system requires no further configuration.

Terminal input such as pasting into your command line is always decoded from UTF-8. If you are copying from a text editor, and the text you are pasting includes characters outside the range, ensure that the copy buffer encoding is UTF-8.

Text files that are input into Topaz are interpreted based on Topaz’s fileformat setting. The default is 8BIT. With this setting, text files are interpreted as 8-bit extended ASCII, the way GemStone historically has encoded this range.

With the setting of UTF8, text files are assumed to be encoded as UTF-8, and it will attempt to decode any bytes in the 128-255 range.

To input text files that are encoded as UTF-8 into Topaz, use:

topaz> fileformat UTF8

If you use any characters with codepoints over 127, the fileformat must be set according to the encoding of the input file, otherwise the results will be corrupted.

If you have logged in, and topaz detects that the repository is in Unicode mode, then it will automatically change the fileformat to UTF8. For more information on Unicode mode, see the Programming Guide for GemStone/S 64 Bit.

The same considerations apply for text files output from topaz. Log files produced by the output command are always encoded as UTF-8. Code fileouts produced by the topaz fileout command include a header line specifying the file format, so these files can be filed in again without problems.

Topaz displays characters in the range 0-31 using caret notation, for example, Character cr is displayed as ^M. The exceptions are Character lf and Character tab, which control display as designed. Characters with codePoints 128-159 and Characters with codePoints over 255 are displayed using C\Java hex format, for example, \u012c.

Capturing Your Topaz Session In a File

It’s often useful to keep a record of your interactions with GemStone during testing and debugging, and when executing scripts to simplifying finding errors.

You can do this with the Topaz command output. This command causes Topaz to write all input and output to a named file as well as to standard input and standard output (your terminal).

For example, either of these lines cause all subsequent interactions to be captured in a file called animaltest.log:

topaz 1> output animaltest.log
 
topaz 1> output push animaltest.log

Using output alone or output push, if the file you name doesn’t exist, Topaz creates it. Under UNIX, if you name an existing file, Topaz will overwrite the previous file.

To add output to an existing file without losing its current contents, use output append, or precede the file name with an ampersand (&). For example:

topaz 1> output push &animaltest.log

To have topaz create a new file if a file with the given name already exists, use pushnew:

topaz 1> output pushnew animaltest.log

If animaltest.log already exists, the file animaltest_1.log is created.

To stop writing to the current log, use output pop.

topaz 1> output pop

Writing to multiple log files

As the command names push and pop imply, Topaz can maintain a stack of up to 20 output files. Topaz input and results are written to each file on the stack.

You can specify topaz only write only to the file on the top of the stack using the keyword only.

For example:

topaz 1> output push animaltest.log only

The keyword only will also prevent the results of any topaz commands from being displayed on your screen; they will only be written to the log file.

The following sequence would capture one set of commands in the file mathtest.log, and a second set of commands in mathtest2.log:

topaz 1> ! Capture the next command and result in mathtest.log
topaz 1> output push mathtest.log
topaz 1> time
02/06/2019 14:49:47.558 PST
CPU time:   0.013 seconds
topaz 1> exec 5 * 8 %
40
topaz 1> ! Capture the next command and result in mathtest2.log
topaz 1> output push mathtest2.log only
topaz 1> time
topaz 1> exec 5 * 9 %
topaz 1> ! Close mathtest2.log and resume using mathtest.log
topaz 1> output pop

Notice that the result of the second time and the result of 45 did not appear on the screen. If the second push command line did not have the only keyword, the entire sequence would have been recorded in mathtest.log, and the second command duplicated in mathtest2.log.

Also notice the use of the exclamation mark ! in this example, to indicate a comment line. You can use either exclamation point or pound sign as the first character in a line, or the command remark, to begin a comment. Comments are important for annotating Topaz input files created for batch processing or testing.

1.4  Using Topaz for Scripting

The Topaz commands that are entered interactively to login and execute code can be stored in external text files. When these files are input into topaz, the command are executed, just as if they were entered interactively. These files of topaz commands can login to GemStone and perform GemStone code, input other topaz files, invoke operating system functionality, and perform error checking and logging.

However, topaz does not provide flow of control. If you have complicated queries, sequences of repository updates, reports, or administrative tasks that you repeat on a regular basis, you can combine topaz with bash shell processing, or use GemStone itself to provide the flow of control.

Topaz commands in text files

To perform automatic repository administrative operations, such as backup or markForCollection, you may create topaz scripts. These can be embedded within shell scripts which are invoked automatically.

For example, this might be the content of a text file script that runs markForCollection, with the name runmfc.topaz:

set user DataCurator password swordfish gemstone gs64stone
login
! run garbage collection mark/sweep 
exec SystemRepository markForCollection %
exit

You can execute this script by starting topaz and inputting the file.

topaz 1> input runmfc.topaz

For more automation, this file can be specified as an input to the topaz command itself, using the -I (or -S) topaz argument.

For example:

unix> topaz -I runmfc.topaz > MFC.out

Both -I and -S suppress output. The -I suppresses the use of a .topazini, while -S does read a .topazini.

Embedding Topaz within shell scripts

You can embed the topaz code within a UNIX shell script, to create a file that can be easily executed on the command line.

#! /bin/bash
#set -x
$GEMSTONE/bin/topaz -il <<EOF >>MFC.out
set user DataCurator password swordfish gemstone gs64stone
login
! run garbage collection mark/sweep 
exec SystemRepository markForCollection %
exit
EOF

Topaz Solo for Scripting

A solo login is a special kind of login, which does not require a running Stone. This allows a Gem session to start up and execute GemStone Smalltalk code (based on reading from a GemStone extent file), without any connection to a Stone. Without a Stone, a solo session is single-user, and no persistent objects can be modified. Solo sessions cannot, for example, run markForCollection in their own environments, nor execute methods that make or restore backups.

By default, a solo login uses the read-only extent in the GemStone distribution ($GEMSTONE/bin/extent0.dbf). However, you can configure it, by setting the Stone configuration parameter GEM_SOLO_EXTENT, to use another single extent file that contains scripting code or that contains your application code and data, provided that the following are true for the repository extent:

  • The extent must not part of a multi-extent repository
  • The extent file must either have read-only file permissions, or it will be exclusive-locked by the solo session.
  • If not read-only, the extent repository must have been previously cleanly shutdown by the Stone

To login solo from topaz linked or RPC, execute set solologin on, then login.

For example:

topaz> set solologin on
topaz> login
[Info]: LNK client/gem GCI levels = 35001/35001
[Info]: Read-Only Repository: /benton2/users/lalmarod/GS6435/bin/extent0.dbf
[Info]: using libicu version 58.2
[Info]: Gave this process preference for OOM killer: wrote 
to /proc/20027/oom_score_adj value 250
[03/26/2018 16:40:33.628 PDT]
  gci login: currSession 1  linked session 
successful Solo login
topaz 1> 

Any setting for gemstone is not used.

In topaz RPC, you may perform a solo login while also logged into a GemStone Stone, provided the extent file used by the Solo session is not in use. In a default configuration with GEM_SOLO_EXTENT set to $GEMSTONE/bin/extent0.dbf, this will be true.

Object creation and memory use

Each Solo RPC or linked Gem also opens a 10MB read-write temporary file, /tmp/gemRO_<pid>_extent1.dbf, which is deleted on logout or process exit.

Object creation in a Solo session is limited to temporary object memory, but you may create objects as needed up to the limit of memory. To ensure there is sufficient memory, you may:

  • Set a larger value for GEM_TEMPOBJ_CACHE_SIZE in the configuration file used by the topaz or Gem session.
  • For linked sessions, use -T cachesize on the topaz command line.
  • For RPC sessions, include -T cachesize in the NRS gemnetid login parameter. For example,
topaz> set gemnetid 'gemnetobject -T 200000'

Topaz solo connecting to a running stone

While a solo session cannot run operations such as markForCollection, it can establish a GsExternalSession to a running Stone and invoke operations such as markForCollection remotely. See the Programming Guide for GemStone/S 64 Bit for details on GsExternalSessions.

Scripting with topaz solo using she-bang

You may create executable text files containing GemStone code, and execute these in a solo session at the command line. The following restrictions apply:

  • The environment variable $GEMSTONE must be set
  • she-bang scripts execute in a solo session, that is, do not log into a running stone.
  • she-bang scripts run in a linked topaz session
  • no topaz command line options can be passed in
  • No .topazini files are read

The first line of the she-band can be defined two ways:

#!/usr/bin/env topaz
$GEMSTONE/bin
must be on the machine executable search path.

#!fullPathToExecutable/topaz
GEMSTONE/bin
does not need to be on the machine executable search path, but fullPathToExecutable must be the full path, not including environment variables.

For example, if you define a executable text file, myscript, with the following contents:

#!/usr/bin/env topaz
set u DataCurator p swordfish
login
run
  | files sz |
  files := GsFile 
	contentsOfDirectory: '$GEMSTONE/data/tranlog*.dbf'
	onClient: false.
  sz := 0.
  files do: [:ea | sz := sz + (GsFile sizeOfOnServer: ea)].
  'tranlogs consume ', (sz / 1024) asInteger asString, ' KB'.
%

This file can be executed, with or without a running stone, to report the sum total size of tranlog files in the given directory.

Note that this will (in a default configuration) execute using the empty distribution extent, and checks the file sizes on disk rather than using any internal representation in the repository that is actually generating the transaction logs.

Topaz exits when the script completes.

Topaz Solo Scripting using bash to pass arguments

By using bash to invoke topaz, you can perform topaz scripting that can include command line arguments. This uses a number of topaz features.

  • the topaz -q argument suppresses output, as does passing in the script using the -S argument.
  • Logins can be normal, that is topaz can login to a running stone, or solo. The advantage of solologin is that the script can run GemStone code whether or not the Stone is running, and without impact on anything going on in the Stone.
  • topaz command line arguments passed in after a -- are available from Smalltalk code using System commandLineArguments.

The following example uses three files to demonstrate writing a command-line script that executes GemStone Smalltalk code. The top-level bash script invokes topaz with the login information in a topaz initialization file and the actual script file, passing in a single argument. For simplicity, this example does no error checking. An actual script, of course, should check that the arguments are present and valid.

Example 1.1 Example bash script

Contents of executable gettranlogspace:
#!/bin/bash
export GEMSTONE=/lark/users/gsadmin/3.5
$GEMSTONE/bin/topaz -lq -I $GEMSTONE/scripts/myini -S
$GEMSTONE/scripts/reporttranlogspace.tpz -- $1

This invokes linked topaz (-l), passing in the initialization file (-I) and the script file (-S). The use of the -q flag suppresses topaz output that will clutter the output. Arguments following -- are passed to topaz, in this case, the bash shell’s (0-based) second element.

By setting $GEMSTONE explicitly and specifying the path to topaz, there is no need to perform GemStone environment setup before executing this script - it can be run in any environment.

Contents of file myini:
set user DataCurator pass swordfish
set gemstone gs64stone
set solologin on

This sets solo login, so no stone login is required. This script logs in as DataCurator, but creating a specific user with limited privileges would be sufficient, since the script will only perform limited operations.

Contents of file reporttranlogspace.tpz:
login
run
  | dir files sz |
  dir := System commandLineArguments last.
  files := GsFile 
        contentsOfDirectory: dir
        onClient: false.
  sz := 0.
  files do: [:ea | sz := sz + (GsFile sizeOfOnServer: ea)].
  GsFile gciLogClient: dir, ': tranlogs consume total ', 
(sz / 1024) asInteger asString, ' KB'.
%
logout
exit

The use of System commandLineArguments gets the full set of tokens that invoked topaz, so the last element is the bash argument. Again, no error checking is done.

Executing the example:
unix> ./gettranlogspace /lark/users/gsadmin/tranlogs
/lark/users/gsadmin/tranlogs: tranlogs consume total 98477 KB
 
 

Invoking Operating System Functionality from Topaz

From within topaz, you can easily execute operating system commands, or escape to an operating system shell and execute commands directly on the command line. To do this, sinvoke the topaz shell command.

You can enter your operating system command on the shell command line, as for example:

topaz> shell echo $GEMSTONE
/lark1/users/gsadmin/GemStone64Bit3.5.0-x86_64.Linux
 
topaz>

Or you can enter shell with no arguments, in which case you can interactively enter a sequence of operating system commands. When you are done, type exit or control-D to returns to topaz.

topaz> shell
% echo $GEMSTONE
/lark1/users/gsadmin/GemStone64Bit3.5.0-x86_64.Linux
% exit
 
topaz> 

You can, of course, also execute operating system functionality from GemStone Smalltalk using:

topaz 1> run
System performOnServer: codeToBeExecuted
%

1.5  Using Topaz for Code Development

Topaz, in conjunction with methods in GemStone Smalltalk, can be used to examine and write classes and methods.

Creating Methods

Creating a class is done using GemStone Smalltalk class creation protocol. For more on class creation, refer to the GemStone Programming Guide.

For example,

topaz 1> printit
Object subclass: 'Animal'
  instVarNames: #('name' 'favoriteFood' 'habitat') 
  classVars: #() 
  classInstVars: #() 
  poolDictionaries: #() 
  inDictionary: UserGlobals
%
a metaAnimal
  superClass          a metaObject
  format              0
  instVarsInfo        1125899906846723
  instVarNames        an Array
  constraints         an Array
  classVars           nil
  methDicts           a GsMethodDictionary
  poolDictionaries nil
  categorys           a GsMethodDictionary
  primaryCopy         nil
  name                Animal
  classHistory        a ClassHistory
  transientMethDicts an Array
  destClass           nil
  timeStamp           a DateTime
  userId              DataCurator
  extraDict           a SymbolDictionary
  classCategory       nil
  subclasses          nil

Once you have a class, you can create methods for it in topaz.

You can begin the definition of an instance method by issuing the method: command at the Topaz prompt. This command takes a single argument: the name of the class for which the method will be compiled.

topaz 1> set category 'Accessing'
topaz 1> method: Animal
habitat
	"Return the value of the instance variable 'habitat'."
	^habitat
%

A class method definition is similarly initiated by the Topaz command classmethod:. For example:

topaz 1> set category 'Instance creation'
topaz 1> classmethod: Animal
returnAString
	"Returns an empty String"
	^String new
%

Topaz maintains state for the Class and method category, so if you have multiple methods, you do not need to specify these values for each method definition. Expressions such as the above will set the Class and the category, and this will be used for subsequent methods until changed.

To set the current class, use the set class command:

topaz 1> set class Animal

To set the current category, use the set category command:

topaz 1> set category Updating

If the category you name doesn’t exist, Topaz creates it when you compile the method.

You can examine your current class and category settings by typing status.

topaz 1> status
 
Current settings are:
(display of current settings and connection information appears here)
 
browsing information:
Class_____________ Animal
Category__________ Updating

Once you’ve established a class and a category, you can define a method simply:

topaz 1> method:
habitat: newValue
	"Modify the value of the instance variable 'habitat'."
	habitat := newValue
%

Like the text of a printit command, the text of a method definition is terminated by the first line that starts with the % character. As soon as you enter the %, Topaz sends the method’s text to GemStone for compilation and inclusion in the selected class and category.

Using a Text Editor to Edit Methods

The edit command allows you to use a host text editor to edit GemStone Smalltalk expressions, including method text.

To use the edit function, you must first have established the name of the host editor you wish to use. Topaz can read the UNIX environment variable EDITOR, if you have it set. Otherwise, use the Topaz set editorname command, interactively or in your Topaz initialization file.

topaz 1> set editorname vi

Then, to edit the text of the last printit command, you need only do this:

topaz 1> edit last

Topaz opens your editor, as a subprocess, on the text of the last command that defined Smalltalk expressions: including printit, exec, run, doit, method, and classmethod. When you exit the editor, Topaz saves the edited text in a temporary file and asks you whether you’d like to compile the altered code. If you type y or yes, Topaz effectively reissues your command with the new text.

For example, to edit the existing instance method habitat: in the current class, you would enter edit as shown below:

topaz 1> edit method habitat:

To edit an existing class method, use an expression of the form:

topaz 1> edit classmethod returnAString

To create an entirely new method with the editor, you can enter edit new method or edit new classmethod.

Listing Methods, Categories, and other information

The topaz list command provides a way to find out information about classes and methods, as well as other information about your system.

To list the instances method selectors for a class, use list selectors:

topaz 1> list selectors
  habitat
  habitat:

To see the categories and methods that are in the current class, use list categoriesin. Topaz lists all of the class and instance method selectors in the selected class by category.

topaz 1> list categoriesin
----------------- Instance Methods:
category (as yet unclassified)
  habitat
category Updating
  habitat:
----------------- Class Methods:
category (as yet unclassified)
  returnAString

To list the source code of an instance method, use list method:

topaz 1> list method: habitat:
habitat: newValue
"Modify the value of the instance variable 'habitat'."
habitat := newValue

A parallel command, list classmethod:, lists the source of the given class method.

Other list options allow you to examine the classes in one or all of your symbol list dictionaries or to examine the methods in some class other than the current class. The list command by itself is used in debugging, to display source for a method on the current execution stack. For more information, see the options described under LIST.

 

Filing Out Classes and Methods

You will commonly want to file out GemStone Smalltalk code at some level of granularity, by Method, Method Category, Class, or SymbolDictionary. Some reasons to do this are:

  • transport your code to other GemStone systems,
  • perform global edits and recompilations,
  • produce paper copies of your work, and
  • recover code that would otherwise be lost when you are unable to commit.

GemStone fileouts are in topaz executable form. You can process this text using editors or other operating system utilities and then execute it with the Topaz input command.

Fileouts are commonly done using GemStone Smalltalk methods, including Class fileOutMethod:on:, Class fileOutCategory:on:, Class fileOutClassOn:, and similar methods; and ClassOrganizer fileOutClassesAndMethodsInDictionary:on:. For more information on these methods, see the methods in the image.

Fileout can also be performed using the Topaz fileout command. For example, the following command:

topaz 1> fileout class: Animal toFile: animal.gs

would create in the file animal.gs, a Topaz script containing a definition of class Animal and all of its categories and methods. Here is how animal.gs would look:

fileformat 8Bit
set sourcestringclass String
run
Object subclass: 'Animal'
	instVarNames: #( 'name' 'favoriteFood' 'habitat')
	classVars: #()
	classInstVars: #() 
	poolDictionaries: {} 
	inDictionary: UserGlobals 
%
category: 'Updating' 
method: Animal
habitat: newValue
	"Modify the value of the instance variable 'habitat'."
	habitat := newValue
%
...

“Filing in” this script with the input command would create a new class Animal exactly like the original.

In addition to class:, the fileout command has other subcommands, to allow you to fileout a method or other granularity of code. For more details, see the options under FILEOUT.

Code outside the ASCII range

The fileout command encodes the resulting file according to the current fileformat setting. By default, this is 8BIT, specifying 8-bit extended ASCII.

If your application code contains characters outside the ASCII range (with values over 127), you may want to fileout your code encoded as UTF-8. This setting is required if you will file out text with any Characters with values over 255; characters with these values cannot be filed out as 8BIT.

To configure your system to fileout in UTF-8:

topaz 1> fileformat UTF8

The current fileformat and SourceStringClass settings are automatically added to the results of fileout. This ensures that the same format is used to filein as was used to fileout. Do not removes these statements, unless you are certain the correct settings will be used on any later filein; the incorrect settings can cause the input to be corrupted.

1.6  Advanced Topaz features

The features previously described to manage your session, execute Smalltalk server code, and accept input from and write to files, are sufficient for most application needs.

Topaz also provides additional features that support sophisticated debugging of GemStone Smalltalk code and streamline access to specific objects.

Structural Access To Objects

In your GemStone Smalltalk programs, you should generally access the values stored in objects only by sending messages. During debugging, however, it’s sometimes useful to be able to read an instance variable or store a value in it without sending a message. For example, if an instance variable is normally read only by a message with side effects, it won’t do to examine its value during debugging by sending that message.

To allow you to “peek” and “poke” at objects without passing messages, Topaz provides the commands object at: and object at:put:.

Examining Instance Variables with Structural Access

The command object at: returns the value of an instance variable within an object at some integral offset. Suppose, for example, that you had created an instance of Animal:

topaz 1> printit
UserGlobals at: #MyAnimal put: Animal new.
%
an Animal
	name               nil
	favoriteFood       nil
	habitat            nil
topaz 1> printit
MyAnimal habitat: 'water'
%
an Animal
	name               nil
	favoriteFood       nil
	habitat            water

The following example shows how you could use object at: to display the value of MyAnimal’s third instance variable.

topaz 1> object MyAnimal at: 3 
water

You can string together at: parameters after object to descend as far as you like into the object of interest. The following example retrieves the first instance variable of MyAnimal’s third instance variable.

topaz 1> object MyAnimal at: 3 at: 1 
$w

As far as at: is concerned, named, indexed, and unordered instance variables are all numbered, with named instance variables appearing first, followed by indexed instance variables, then unordered instance variables. That is, if an indexed object also had three named instance variables, the first indexable field would be addressed with object at: 4. Offsets into the unordered portions of NSCs are not consistent across add: or remove: commands.

Specifying Objects

As you have seen, objects can be identified within an object command by global GemStone Smalltalk variable names. This is only one of several kinds of object specification acceptable in such Topaz commands as object at:. The others include object identity specification formats and literal object specification formats.

Object Identity Specification Formats

@integer
An unsigned 64-bit decimal OOP value that denotes an object.

integer
A 61-bit literal SmallInteger.

$character
A literal Character.

aVariableName
This can be either a GemStone Smalltalk variable name or a local variable created with the define command.

** The object that was the result of the last execution.

^ The current class (as defined by the most recent set class, list categoriesIn:, method:, classmethod:, or fileout command).

Literal Object Specification Formats

'text'
A literal String.

#text
A literal Symbol (no white space allowed).

#'t e x t'
A quoted literal Symbol.

float
A Float object (C double-precision Float). The syntax for literal floating point numbers in Topaz commands is:

[sign]digits[.[digits][E[sign]digits]]

The OOP specifications and ** (last result) are especially interesting. For example:

topaz 1> display oops
topaz 1> object Animal
[1337089 sz:19 cls: 150617 Animal class] Animal class
  superClass      [72193 sz:19 cls: 206081 Object class] Object class
  format          [2 sz:0 cls: 74241 SmallInteger] 0
  instVars        [26 sz:0 cls: 74241 SmallInteger] 3
  instVarNames    [1335297 sz:3 cls: 66817 Array] an Array
 
...
topaz 1> ! Look at first element of instVarNames array 
topaz 1> object @1335297 at: 1
[1248257 sz:4 cls: 110849 Symbol] name
topaz 1> ! Look at first character of first instvarname
topaz 1> omit oops
topaz 1> object ** at: 1
$n

Note that when you look at the first element of the instVarNames array, you need to use the OOP returned by your own GemStone system, not @1335297.

Specifying Method Selectors

When specifying a method selector in a Topaz command, you can use any of the following formats:

text

'text'
A literal String.

#text
A literal Symbol (no white space allowed).

#'t e x t'
A quoted literal Symbol.

The resulting token becomes a String object and is subsequently converted to a Symbol object if required by the command.

Topaz Variables

As you saw in the last section, Topaz lets you refer to objects via their OOPs. Because long numerical OOPs are hard to remember, Topaz also provides a facility for defining local Topaz variables so that you can name those OOPs.

Creating Variables

The following example shows the use of the Topaz define command to create a reasonable name for an object previously known by its OOP.

topaz 1> display oops
topaz 1> object Animal
[1337089 sz:19 cls: 1337601 Animal class] Animal class
	superClass  [72193 sz:19 cls: 206081 Object class] Object class
	format      [2 sz:0 cls: 74241 SmallInteger] 0
	instVars    [26 sz:0 cls: 74241 SmallInteger] 3
	instVarNames[1335297 sz:3 cls: 66817 Array] an Array
...topaz 1> define animalVars @1335297
topaz 1> omit oops
topaz 1> object animalVars at: 1
name

A local variable must begin with a letter or an underscore, can be up to 255 characters in length, and cannot contain white space.

If additional tokens follow define’s second parameter, Topaz will try to interpret them as a message to the object represented by the second parameter. For example:

topaz 1> define thirdvar animalVars at: 3
topaz 1> object thirdvar
habitat

Note that Topaz does not parse message expressions exactly as the GemStone Smalltalk compiler does; Topaz requires you to separate tokens with white space.

As the last example shows, local variables can be used in object commands. When used in this way, the local definition of a symbol always overrides any definition of the symbol in GemStone. For example, if “thirdvar” were defined in UserGlobals, that definition would be ignored in object commands.

All Topaz object specification formats (described above in “Specifying Objects”) are legal in define commands. For example:

topaz 1> define sum 1.0e1 + 500
topaz 1> define mystring 'this and that'
topaz 1> define mycharacter $z

Displaying Current Variable Definitions

To see all current local variable definitions, just type define with no arguments:

topaz 1> define
Current definitions are:
	mycharacter        = 142538
	mystring           = 150133
	sum                = 147709
	thirdvar           = 114793
	animalVars         = 147682
------------------------
	CurrentMethod       = nil
	ErrorCount          = 2
	SourceStringClass   = 74753
	CurrentCategory     = nil
	CurrentClass        = nil
	LastResult          = nil
	LastText            = nil
	myUserProfile       = nil

Note that define reports values as OOPs rather than literals.

In this status report the user-defined local variables are listed first. The last items are local variables that Topaz automatically creates for you. They refer, respectively, to:

  • the OOP of the current method
  • the OOP of the number of Topaz and GemStone errors made since you started Topaz
  • the OOP of the class to which sourcestringclass is set
  • the OOP of the current category
  • the OOP of the current class
  • the OOP of the last execution result
  • the OOP of the text of the last GemStone Smalltalk expression executed or compiled
  • the OOP of your UserProfile

You cannot modify the definitions of these predefined variables with define.

Clearing Variable Definitions

To clear a definition, type define aVarName with no second argument.

For example:

topaz 1> define abc 'this string'
topaz 1> object abc
this string
topaz 1> define abc
topaz 1> object abc
GemStone could not find an object named abc.

Sending Messages

Usually you’ll send messages only inside methods or within printit commands. If you can point to an object only via a local Topaz variable or via an OOP, however, this won’t work.

Therefore, Topaz provides the send command, which lets you send a message to an object identified by any of the means described in Specifying Objects. For example:

topaz 1> send @71425 class
a Metaclass
	superClass     a Metaclass
	format 1040
	...
	categories     a GsMethodDictionary
	secondarySuperclasses nil
	thisClass       UndefinedObject class

The send command’s first argument is an object specification identifying a receiver. That argument is followed by a message expression built almost as it would be in GemStone Smalltalk. Here’s another example:

topaz 1> send 2 - 1
1

There are some differences between send syntax and GemStone Smalltalk expression syntax. Only one message send can be performed at a time with send. Cascaded messages, parenthetical messages, and the like are not recognized by this command. Also note that each item must be delimited by one or more spaces or tabs.

 

Next chapter