3. Changes in GemStone Smalltalk

Previous chapter

Next chapter

This chapter describes changes and new features important for programmers using GemStone Smalltalk, including:

Changes in Classes, compilation, and code management

Changes in Numeric/Time classes

ExternalSession Changes

Other Changes and Enhancements

Deprecated and removed classes and methods

3.1  Changes in Classes, compilation, and code management

Instance variable name length limit

Previously, instance variable names were limited to 64 characters; this has been increased. Now, class names, instance variable names, class variable names, class instance variable names, method temporaries, and method arguments all have a limit of 1024 characters.

Literal Arrays may now embed literal ByteArrays

The Array literal forms #( element1 element2 ...), previously could embed most other literal kinds with the exception of literal ByteArrays #[ int1 int2 ...]. Now, ByteArrays can also be embedded.

For example, this is now legal:

#( #[1 2 3 4] 'test' 1 2.0 ) 

Block not optimized no longer reports CompilerWarning

The compiler cannot inline blocks under some conditions, when the blocks are complex. Previously, this resulted in Warnings, such as "WARNING: at line 21, to:do: not optimized". These Warnings were not useful and are no longer produced.

Change in handing of transient symbol list

Historically, on login a copy of the UserProfile’s symbolList is made available as the transient symbolList, and the transient symbolList is then used for all lookups for classes and other variables. This allows a separation between the shared symbolList for that UserProfile, and any changes the user is making while logged in. The transient symbolList was kept in session state, and was not affected by commit or abort. If there were changes in the UserProfile’s persistent symbolList (made by other sessions), a session’s transient symbolList did not automatically pick these changes up on commit or abort.

In 3.6, this behavior has been modified to make it easier to keep the transient symbolList in sync with the persistent symbolList.

Now, on login, the transient symbolList is a reference to, not a copy of, the persistent symbolList. Applications that do not need to modify the transient symbolList will automatically pickup changes by commit or abort, without extra effort.

Executing any of the following methods will create a copy of the transient symbolList in session state. This results in the same behavior as in previous releases.

System class >> refreshTransientSymbolList
GsCurrentSession >> transientSymbolList: aSymbolList
GsCurrentSession >> transientSymbolList

Changes in Class Categories

GemStone Classes have a class category, which are not visible in GBS but are displays in tools such as Jade. There are a number of changes in the categories of classes in 3.6.

Private method to rename an instance variable

A method has been added to allow you to rename an instance variable in place, without versioning the class.

Note that this is not considered a safe operation. This is not intended for use in critical systems, or under production conditions. Use caution and perform thorough testing, since there may be unexpected consequences.

Class >> unsafeRenameInstVarNamed: oldName to: newName

See method comments in the image for more details.

3.2  Changes in Numeric/Time classes

Added Specials

Specials are kinds of objects in which the value of the object is encoded in the OOP itself, and thus do not require an entry in the object table, space on a data page, nor a fetch to fault into memory.

The following new Specials are subclasses of existing classes, and, like SmallDouble and Float, transparently interoperate to represent the most commonly used subsection of the full range of the superclass’s values.

SmallDate

SmallDates represents instances of Date; the SmallDate range covers all supported Dates.

Creating an instance of Date in the supported Date range will return an instance of SmallDate.

The technical requirement is that the year range is limited to -231 (-2147483648) to 231 - 1 (2147483647). The OOP uses 9 bits for an unsigned integer for the dayOfYear, and 47 bits for the 32 bit signed integer year.

SmallDateAndTime

A SmallDateAndTime is a DateAndTime representing a time (in microseconds) in the range of years 2001-2072, for times with offset from UTC (in hours) in the range -16..15).

Creating an instance of DateAndTime, when the result is in the range of SmallDateAndTime, will return an instance of SmallDateAndTime.

The OOP uses 5 bits signed offset from UTC in hours, and 51 bits of unsigned integer for the time since 2001 in units of microseconds.

SmallScaledDecimal

SmallScaledDecimal is used to represent ScaledDecimals that have scale <= 31 and mantissa in the range -250 (-1125899906842624) to 250 - 1 (1125899906842623).

Creating an instance of ScaledDecimal, when the result is in the range of SmallScaledDecimal, will return an instance of SmallScaledDecimal.

The OOP uses 51 bits for a signed integer mantissa and 5 bits unsigned scale.

SmallTime

SmallTime is used to represent instances of Time as the local time since midnight in units of microseconds.

Creating an instance of Time, when the result is in the range of SmallTime, will return an instance of SmallTime.

The OOP uses 56 bits for an unsigned integer. The maximum value of local time is 86399999999.

DateAndTime changes

To retain common behavior between the range of SmallDateAndTime and DateAndTime, DateAndTime has been adjusted. The following changes describe the behavior of instances of SmallDateAndTime as well as instance of DateAndTime.

  • DateAndTime instances are now invariant.
  • The method offset:, which modified and returned the receiver, now returns a new instance of DateAndTime with the new offset. Please examine your code to ensure that you are not relying on offset: to modify the receiver; this method is ANSI and could not be deprecated or return an error. SmallDateAndTime instances, since the value is encoded in the OOP, are inherently not modifiable.
  • The method beRounded modified the receiver, and will throw an invariant object error for DateAndTime and a shouldNotImplement for SmallDateAndTime. Code should use the method rounded, which returns a new instance.
  • DateAndTime instances are always created with an internal SmallScaledDecimal with 6 decimal places of precision, equivalent to microseconds, for equivalence with SmallDateAndTime.
  • DateAndTime asSeconds returns an instance of SmallScaledDecimal, not a SmallDouble.
  • DateAndTime instances no longer print based on the nature of the data in the seconds instance variable. DateAndTime instances print using printString with microseconds (6 digits of fractional seconds), and as integral seconds using asString.
  • The class method nowWithScale: is deprecated, and returns the same value as now. The DefaultScale class variable is obsolete and no longer used.
  • Class and method comments for DateAndTime and DateAndTimeANSI have been edited to remove boilerplate and general information, making the useful information easier to see.
  • Some instance creation errors now signal an OutOfRange error rather than an Error.

Special care when adding methods to kernel classes DateAndTime, Date, Time, and ScaledDecimal

Application extension methods that are added to DateAndTime, Date, Time, or ScaledDecimal may directly reference instance variables on that class; this is normal, and these methods will compile correctly. However, these methods are problematic when inherited by SmallDateAndTime, SmallDate, SmallTime, and SmallScaledDecimal, since specials by definition do not have instance variables.

If you have added methods directly to GemStone kernel classes DateAndTime, Date, Time, or ScaledDecimal, you must review your code and ensure that any direct accesses to instance variables are changed to use accessor methods. Methods with direct instance variable references will compile correctly, but will get Error 2710/instVar access not allowed in a special object on execution. Methods with direct references that are not recompiled will cause the Gem to crash.

Other added methods

Time >> asMicroseconds
Returns a SmallInteger that represents the receiver in units of microseconds since midnight, local time.

Time >> subtractMilliseconds: anInteger
Returns a Time or SmallTime (in practice, a SmallTime) that describes a time of day anInteger milliseconds earlier than that of the receiver.

Time class >> fromMicroseconds: anInteger
Create an instance of Time or SmallTime (in practice, a SmallTime) that is anInteger microseconds since midnight, local time.

3.3  ExternalSession Changes

The class GsTsExternalSession was added in v3.5.3. GsTsExternalSession uses the thread-safe GCI (gcits.hf), rather than the traditional GCI interface (gci.hf) that is used by GsExternalSession.

In this release, GsTsExternalSession has been associated with GsExternalSession under a common superclass, with adjustments to the API to improve the ability to move between these classes.

In addition, the class GsTsX509ExternalSession has been added, which allows X509-secured external sessions using the thread-safe GCI.

This is the new hierarchy:

AbstractExternalSession
GsExternalSession 
   GsLegacyExternalSession
   GsX509ExternalSession 
GsTsExternalSession 
   GsTsX509ExternalSession

GsExternalSession is now legacy; new code should use GsTsExternalSession. GsExternalSession may have issues in complicated environments with multiple threads.

The overhead of making calls using GsTsExternalSession is 1/2 to 1/4 the overhead required by calls to GsExternalSession.

GsTsExternalSession changes

GsTsExternalSession is now a subclass of AbstractExternalSession, and a number of methods are now implemented in the superclass.

In addition, many new methods have been added to make the transition between GsExternalSession and GsTsExternalSession more transparent.

  • You can now create an instance of GsTsExternalSession using newDefault, which creates an instance with the same library version as the current session.
  • GsTsExternalSession has added instance variables stoneSessionSerial and logger.
  • The logging feature from GsExternalSession is now available in GsTsExternalSession; however, the thread-safe API does not support user actions, so logging to the GCI client is not supported.
  • The methods quiet and quietLogout are now implemented in GsTsExternalSession; however, they have no effect (GsTsExternalSession is always quiet).
  • Methods to create a new instance, or update an existing instance, by setting specific parameter values have been added. The following methods are added:
GsTsExternalSession >> gemNRS:
GsTsExternalSession >> hostPassword:
GsTsExternalSession >> hostUsername:
GsTsExternalSession >> password:
GsTsExternalSession >> stoneNRS:
GsTsExternalSession >> username:
GsTsExternalSession class >> gemNRS:stoneNRS:username:password: 
GsTsExternalSession class >> gemNRS:stoneNRS:username:aUsernamehostUsername: hostPassword:
  • The following other methods have also been added:
hardBreak
isRemoteServerBigEndian
nbLogin
nbLoginFinished 
softBreak  
stoneSessionSerial  
waitForResultForSeconds:
waitForResultForSeconds:otherwise:

Methods added to both

The following methods have been added to both GsExternalSession and GsTsExternalSession:

begin
Abort current transaction and begin a transaction

commitOrError
Commit the current transaction in the remote session and return true, or signal an error if the commit fails.

3.4  Other Changes and Enhancements

Behavior >> isSpecial should not be used; replaced by Behavior >> areInstancesSpecial

The method Object >> isSpecial can be sent to any object to determine if it is a special (the OOP encodes the value, such as a Character or SmallInteger). Historically, this method was overriden by Behavior >> isSpecial, which returned if instance of the class would be Specials, rather than the status of receiver itself.

The method Behavior >> areInstancesSpecial has been added, and should be used to test if instances of a class are Specials.

In v3.6, Behavior >> isSpecial has been removed, and the behavior is inherited now from Object. Sending isSpecial to Classes such as Character, which previously returned true, will now return false. Examine your application senders of isSpecial to ensure that this does not have unexpected results; change your code as needed to use areInstancesSpecial.

Added commit failure types

After an attempt to commit a transaction fails, System class >> transactionConflicts returns the details of the commit failure. In addition to the previous possible return values, this may also now include #symbolFailure or #lockFailure.

Exiting the Client from Smalltalk

The class ExitClientError has been added, allowing you to exit f rom a client process (usually topaz) with a specific error code.

topaz 1> run
ExitClientError 
	signal: 'Disallowed Operation' 
	status: 34 
%
ERROR 3004 , a ExitClientError occurred (error 3004), , Disallowed Operation (ExitClientError)
Logging out session 1.
--- 08/11/2020 15:21:17.137 PDT Logging out

ClassOrganizer searches class comments, return arrays changed

String search in ClassOrganizer (and via topaz) now searches the text of class comments, as well as method source.

The Arrays returned from methods to perform search were previously of size 2, the methods containing the search string and the offsets into these methods, are now are of size 3. The new third element is a list of classes whose class comment includes the search string.

Affected methods are:

ClassOrganizer>>substringSearch:
ClassOrganizer>>substringSearch:in:
ClassOrganizer>>substringSearch:in:ignoreCase: 

3.5  Deprecated and removed classes and methods

The following methods are newly deprecated:

Class >> byteSubclass:classVars:classInstVars:poolDictionaries:category:inDictionary:instancesInvariant:
Class >> indexableSubclass:instVarNames:classVars:classInstVars:poolDictionaries:category:inDictionary:instancesInvariant:isModifiable:
Class >> subclass:instVarNames:classVars:classInstVars:poolDictionaries:category:inDictionary:constraints:instancesInvariant:isModifiable:
DateAndTime class >> nowWithScale:
DateAndTime class >> setDefaultScale:
System class >> reclaimGemSessionIds
System class >> _deadNotReclaimed

Removed Classes

The following classes were removed, and are now in Globals in the sub-dictionary ObsoleteClasses.

CanonicalStringDictionary
RubyBreakException
RubyCextData
RubyConstantRef
RubyHash
RubyProc
RubySocket
RubyThrowException
RubyTime
UnimplementedFloat1
UnimplementedFloat2

Find All Reference Path removed methods

The following methods related to the previously deprecated, now removed find all reference paths feature have been removed:

Repository >> findAllReferencePathsToObject:
Repository >> findAllReferencePathsToObject:maxPaths:
Repository >> findAllReferencePathsToObjects:
Repository >> findAllReferencePathsToObjects:limitObjArray:printToLog:
Repository >> findAllReferencePathsToObjects:limitObjArray:printToLog:maxPaths:
Repository >> findAllReferencePathsToObjects:maxPaths:
Repository >> findAllReferencePathsToObjects:printToLog:
Repository >> findAllReferencePathsToObjects:printToLog:maxPaths:
Repository >> _findAllReferencePathsToObjects:limitObjArray:printToLog:maxPaths:

Other removed methods:

AbstractCharacter >> asJISCharacter
Behavior >> isSpecial
Character >> asJISCharacter
CharacterCollection >> asJISString
CPreprocessor >> defaultAix61Definitions
DecimalFloat class >> on:do:
GsObjectInventory class >> profileObjectsInBm:
GsObjectInventory class >> profileObjectsInFile:
Integer >> asJISCharacter
Object >> asEUCString
System class >> fastFindObjectsLargerThan:limit:
System class >> findObjectsLargerThan:limit:

Private removed methods

The following private methods (including methods that were temporarily added during tonel code development) , have been removed:

AbstractDictionary >> at:ifPresent:
BlockClosure >> setPackage:withInMetacelloConfig:
CharacterCollection >> tonelSubstrings:
Class >> _newKernelSubclass:instVarNames:inDictionary:
Class >> _nonInheritedOptions
Class >> _optionsForDefinition
CLibrary >> _oneArgPrim:arg:
CLibrary class >> _oneArgPrim:arg:
Collection >> asMetacelloAttributeList
Collection >> setForDo:withInMetacelloConfig:
Collection >> setIncludesInMetacelloPackage:
Collection >> setLoadsInMetacelloProject:
Collection >> setRequiresInMetacelloPackage:
Collection >> sorted:
CPreprocessor >> _defaultAix61DefinitionsOld
CZstream class >> _initializeConstants
DateAndTimeANSI >> _secondsUTC:offset:
Dictionary class >> newFromPairs:
GciLibrary >> GciCHeapCheck
GciLibrary >> GciUtlExit_:
GciLibrary class >> initializeFunction_GciCHeapCheck_inLibrary:
GsBitmap >> _basicNew
GsBitmap >> _reportString
GsNMethod >> _debugInfoHasFileAndLine
GsNMethod >> _lineNumberBias
GsObjectInventory class >> _objInventory:waitForLock:pageBufSize:percentCpuActiveLimit:showHiddenClasses:aHiddenSet:listInstances:toFile:inMemoryOnly:
GsQuery class >> initialize
GsQueryFormula class >> initialize
GsQueryTokenParser class >> initialize
IO class >> new:mode:
IO class >> _forgetFileDescriptor:
IO class >> _rememberFileDescriptor:obj:
Object >> flag:
Object class >> fixReferencesAfterConversionFromDirectory:
ProcessorScheduler >> _endYield
ProcessorScheduler >> _findReadyProcess:
ProcessorScheduler >> _reapEvents:honorOob:
ProcessorScheduler >> _reschedule:
ProcessorScheduler >> _rescheduleHonorOob:
Repository >> _allReferencesByParentClass:
Repository >> _fastAllReferencesByParentClass:
Repository >> _primRestoreSecureBackups:scavPercentFree:bufSize:privateDecryptionKey:passphrase:numThreads:
Repository >> _restoreBackups:scavPercentFree:bufSize:numThreads:
SequenceableCollection >> writeStream
String >> addToMetacelloRepositories:
String >> asObsoleteSymbol
String >> execute:against:
String >> fetchRequiredForMetacelloMCVersion:
String >> loadRequiredForMetacelloMCVersion:
String >> mergeIntoMetacelloRepositories:
String >> packageFileSpecFor:
String >> recordRequiredForMetacelloMCVersion:
String >> removeFromMetacelloRepositories:
String >> resolvePackageSpecsNamedForMetacelloMCVersion:visited:ifAbsent:
String >> setIncludesInMetacelloPackage:
String >> setLoadsInMetacelloProject:
String >> setRequiresInMetacelloPackage:
Symbol >> asMetacelloAttributeList
Symbol >> asMetacelloAttributePath
Symbol >> setForDo:withInMetacelloConfig:
Symbol >> setForVersion:withInMetacelloConfig:
Symbol >> setPostLoadDoItInMetacelloSpec:
Symbol >> setPreLoadDoItInMetacelloSpec:
System class >> _breakSerialization
Time >> _initialize:
UserProfile >> _createDictionary:at:
UserProfile >> _renameDictionary:to:
 

Previous chapter

Next chapter