Topaz is a GemStone programming environment that provides keyboard command 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. Chapter 3 provides descriptions of 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 must 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.
Topaz is designed to support the GemStone Ruby environment (MAGLEV) as well as GemStone/S 64 Bit. A number of Topaz commands and options are provided for use with Ruby but are not used in GemStone Smalltalk installations; the use of these commands is not described in this manual.
The environmentId specifies a method lookup environment that is primarily used in Ruby environments, although it may be available for Smalltalk applications. By default, it is 0 in Smalltalk applications.
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
A GemStone session consists of four parts, as shown in Figure 1.1. These are:
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 of which allows RPC logins only, the other allowing both Linked and RPC.
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.
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.
% topaz
__________________________________________________________________________
| GemStone/S64 Object-Oriented Data Management System |
| Copyright (C) GemTalk Systems 1986-2015 |
| All rights reserved. |
+--------------------------------------------------------------------------+
| PROGRAM: topaz, Linear GemStone Interface (Remote Session) |
| VERSION: 3.3.0, Thu Aug 18 14:47:21 US/Pacific 2015 |
| BUILD: 64bit-37204 |
| BUILT FOR: x86-64 (Linux) |
| MODE: 64 bit |
| RUNNING ON: 4-CPU benton x86_64 (Linux 3.2.0-58-generic #88-Ubuntu SMP Tue|
| Dec 3 17:37:58 UTC 2013) 5965MB |
| PROCESS ID: 27630 DATE: 09/10/15 15:41:54 PDT |
| USER IDS: REAL=gsuser (534) EFFECTIVE=gsuser (534) LOGIN=gsuser (534) |
|__________________________________________________________________________|
topaz>
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 most 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. You may include multiple topaz commands on a single line by separating each expression with a semicolon (;).
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.
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.
Here are the parameters to be established to log in to GemStone through Topaz:
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. Appendix B describes the syntax of network resource strings.
This is configured using the set command: set gemstone stonename.
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.
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.
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 caution in using set gemnetid in topaz initialization files.
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 of the form !@<remoteNode>#netldi:<netldiName>!gemnetobject. For example,
!@lark.gemtalksystems.com#netldi:gs64ldi!gemnetobject.
The GemStone service name is is configured using the set command: set gemnetid serviceName.
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
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)
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'
CacheName__________ (default)
Browsing Information:
Class_____________
Category__________ (as yet unclassified)
If you are will be 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)
[Info]: libssl-3.3.0-64.so: loaded
[05/14/2015 15:02:40.874 PDT]
gci login: currSession 1 rpc gem processId 1363
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
[Info]: libssl-3.3.0-64.so: loaded
[05/14/2015 15:02:40.874 PDT]
gci login: currSession 1 rpc gem processId 1363
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 = 33000/33000
[Info]: libssl-3.3.0-64.so: loaded
[Info]: User ID: Isaac_Newton
[Info]: Repository: gs64stone
[Info]: Session ID: 5
[Info]: GCI Client Host: <Linked>
[Info]: Page server PID: -1
[Info]: Login Time: 05/14/2015 15:00:39.542 PDT
[05/14/2015 15:00:39.543 PDT]
gci login: currSession 1 linked session
successful login
topaz 1>
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.
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.
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.
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>
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.
If an 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.
Use caution in including commands to set the gemnetid in a .topazini file. For example, avoid using lines such as:
set gemnetid gemnetobject
The .topazini file is executed for both RPC and linked topaz. If this line is present in a .topazini file, and that .topazini file is executed by linked topaz, the effect is to turn the linked login into an RPC login.
For more on the behavior of gemnetid in linked and RPC topaz, see under gemnetid.
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.
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
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
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>
If you use the topaz -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 OS credentials if your server configuration requires this, so you can get an RPC login.
If you are running linked topaz (topaz -l), 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>
[Info]: libssl-3.3.0-64.so: loaded
[09/10/2015 14:40:49.338 PDT]
gci login: currSession 1 rpc gem processId 31427
successful login
topaz 2> set gemnetid ''
topaz 2> login
[Info]: LNK client/gem GCI levels = 33001/33001
--- 09/10/2015 14:37:56.603 PDT 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
[09/10/2015 14:37:56.609 PDT]
gci login: currSession 1 linked session
successful login
topaz 1>
The messages displayed during login indicate if the session is linked or RPC.
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.
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.
See the System Administration Guide for GemStone/S 64 Bit for more information on managing transactions and handling sigAborts.
WARNING
Idle topaz sessions should not be left logged into 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 session may be terminated.
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.
The Ctrl-C key combination interrupts Topaz and GemStone:
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 2015
dayOfYear 126
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 2015
dayOfYear 126
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.
GemStone Smalltalk supports two set of string classes; the 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. This is 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.
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 .
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 2015
dayOfYear 126
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
%
06/05/2015 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
%
06/05/2015 15:05:23
Setting the level to 2 would give this view:
topaz 1> level 2
topaz 1> run
DateTime now
%
a DateTime
year 2015
dayOfYear 126
milliseconds 83121913
timeZone a TimeZone
transitions an Array
leapSeconds nil
stream nil
types nil
charcnt nil
standardPrintString PST
dstPrintString PDT
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.
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)
Two complementary commands, display and omit, control some features of how objects are displayed in topaz. For more details on the options, see DISPLAY.
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]
topaz 1> display oops
topaz 1> printit
DateTime now
%
[25521409 sz:4 cls: 118785 DateTime] a DateTime
year [16114 sz:0 cls: 74241 SmallInteger] 2014 == 0x7de
dayOfYear [362 sz:0 cls: 74241 SmallInteger] 45 == 0x2d
milliseconds [665595786 sz:0 cls: 74241 SmallInteger] 83199473 == 0x4f585f1
timeZone [12049153 sz:9 cls: 14631169 TimeZone] a TimeZone
You can turn off the display of OOPs by typing omit oops at the Topaz prompt.
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
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.
Some of the most important functionality that Topaz provides are related to working with file system files. Topaz uses files:
Topaz also provides one way to file code out from the repository.
The Topaz commands you have entered interactively to login and execute code can alternatively be stored in an external text file. This allows you to execute a sequence of commands as often as needed and whenever needed without having to type it in each time.
You have already seen the .topazini initialization file, which is a specialized use of scripting capability. Topaz provides the ability to run any of its commands, invoke other topaz scripts or operating system functions, and perform error checking and logging. It is not itself a complete scripting environment and does not provide flow-of-control operators; topaz invocations can be embedded in shell script as needed.
If you have complicated queries, sequences of repository updates, reports, or administrative tasks that you repeat on a regular basis, this is an easy way to do it. You can type the Topaz commands into a file, and test and edit them until they run correctly. If your procedures change, you can easily edit the script.
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.
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.
To perform automatic repository administrative operations, such as backup or markForCollection, you may create topaz scripts and embed them 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
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/sh
#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
Character with codepoints over 127 are outside the ASCII range, and how they 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.
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.
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
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.
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
05/07/2015 14:49:47.558 PDT
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.
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, simply invoke the 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.3.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.3.0-x86_64.Linux
% exit
topaz>
Topaz, in conjunction with methods in GemStone Smalltalk, can be used to examine and write classes and methods.
Creating a class is done using GemStone Smalltalk class creation protocol. For more on class creation, refer to the GemStone Programming Guide.
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.
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.
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.
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:
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.
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.
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.
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:.
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.
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.
@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).
#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.
When specifying a method selector in a Topaz command, you can use any of the following formats:
#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.
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.
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
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:
You cannot modify the definitions of these predefined variables with define.
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.