ENVY/Smalltalk Tips, Tricks, and Other Miscellany

Please mail me with any additions.

Interacting With Users

System has standard protocol for interacting with users:


Cool meta stuff on Behavior

Behavior provides:

Object provides:


ENVY/Manager Application Protocol

#areReleased:
#asScratch
#classEditionNamed: className at: timeStamp
#classEditionsFor: className
#classes
Answers all defined, extended and undefined classes
#defined
Answers all defined classes
#extended
Answers all extended classes
#releasedClassVersions
#existsInLibrary
Answer true if the edition'ss record exists in the library -- tests if it can be loaded
#isApplication
#isSubApplication
#isEdition
#isVersion
#previousTimeStamp
Return the previous timestamp for the receiver
#signature
Return a string describing the receiver with edition/version (the version name, '<>' if scrathed, or timestamp)
#timeStampFor: classOrClassName
#versionName
#timeStamp
#timeStamps
Answer a dictionary of {class, class timestamp} pairs for the classes in the receiver.
#shadows
Answer the shadow applications of the receiver sorted from latest to earliest.
#shadowAt: timeStamp
Application and SubApplication also support #shadowsFor:, which takes an application name. It is roughly equivalent to:
    (Smalltalk classAt: appName) shadows


Handy ENVY/Packager selectors on Application classes


List of ENVY/Packager Rules

It sure would be handy to have a list of packager rules, wouldn't it?


Customizing ENVY/Smalltalk's Browsers

Don't like the way you browse code with ES? Quite often, that particular UI behaviour is configurable. Browse the list of configurable preferences: ENVY -> Open Preferences Workspace. This is a workspace filled with doits and descriptions. Save the doits that you modify so that you can customize other images without having to browse this again.

Some of my favourite options:


Making Sense of OSErrorX

Got a walkback claiming 'something failed due to OSErrorX', where X is some number? This doit will find a symbolic meaning for the cause:

| errorNamePrefix osErrorCode |
errorNamePrefix := 'Err'.
osErrorCode := (System prompt: 'OSError number') asNumber.
PlatformConstants associationsDo: [:assoc |
    (assoc key size >= errorNamePrefix size and: [
        (assoc key copyFrom: 1 to: errorNamePrefix size) = errorNamePrefix and: [
            assoc value = osErrorCode]])
                ifTrue: [^assoc inspect]].
^System message: 'OSError mapping not found'

Unfortunately it only seems to work for Windows platforms (OS/2 is unconfirmed). That sucks! On the Unix platforms OSError1 is the shared-library couldn't be found, and OSError2 is the referenced procedure wasn't found within the shlib.

(Courtesy of Marcio)


Finding A Class By Name

Not sure how to track down a class? Do you know a potential substring that might be in its name? If so, try this doit:

| classNameFragment pattern collection |
(classNameFragment := System prompt: 'Class name fragment:') isNil
    ifTrue: [^nil].
pattern := '*', classNameFragment, '*'.
collection := OrderedCollection new.
Smalltalk associationsDo: [:assoc |
    (assoc key match: pattern)
        ifTrue: [collection add: assoc]].
^collection inspect


Determining the Platform Line-Delimeter

To find the platform line-delimiter, use the pool var LineDelimiter from CldtConstants. It also contains the various platform delimiters too, like WINLineDelimiter, UNIXLineDelimiter, and PMLineDelimiter. It's not clear what these answer on MVS with EBCDIC -- do they answer the ASCII values, or the EBCDIC equivalents?


TBD: More complex prompters; selecting from a list. CwListPrompter and the like.


TBD: Adding submenus to the ENVY menu. When you remove it (presumably from your app's #removing code), you'll have to #rebuildTranscriptMenus. I think this is a bug.


Relocalizing NLS Catalogues

If you're getting `MISSING in ...' messages, then you may need to relocalize your message catalogs.

| locale |
locale := Locale defaultMessagesLocale.
EsPoolDictionary allInstances do: [:pool |
    pool isNlsPool ifTrue: [pool verifyRelocalize: locale]].


Rebuiling Symbol and Atom Tables

After a while, your image will accumulate a lot of Symbols and Atoms which can cause false-positives when doing browse-implementors/senders. You can cure this by rebuilding the symbol and atom tables:

    Symbol recreateSymbolTable.
    EsAtom recreateAtomTable.


Finding Undefined Globals

Sometimes when you load code, you'll see messages on your Transcript saying 'Defined global X while loading ...'. This usually happens because your code is accessing a pool variables that hassn't been defined in your image: your code is out of date. Unfortunately fixing the pool's PRAGMA doesn't fix the problem, as the code will have the wrong association in it, and hence won't be updated. The following doit will fix this. Note: I think this is a bug.

System showBusyCursorWhile: [
    | methodNames methods apps |
    methods := Set new.
    apps := EtTools
        prompt:  'Choose the appropriate applications.'
        chooseMultipleFrom:
	    (System loadedSubApplications
		asSortedCollection: [:a :b| a symbol < b symbol])
        initialSelection: #()
        printBlock: nil
        statusIndicatorBlock: nil.

    (apps isNil or: [apps isEmpty]) ifTrue: [^nil].
    apps do: [:app |
        app classes do: [:cl |
            ((cl methodsIn: app), (cl class methodsIn: app)) do: [:method |
		    method allLiteralsDo: [:lit |
			(lit isAssociation and: [lit key isSymbol and:
			    [lit value isNil]])
				ifTrue: [methods add: method]]]]].
    methods isEmpty ifTrue: [^System message: 'No methods need rebinding'].
    methods do: [:method |
        method methodClass
	    addCompiledMethod: (method methodClass regenerate: method)].

    ((EtTools browser: #methods) on: methods labeled: 'Rebound methods')
        owningImage: System;  
        open]


K8DoitManager

You'll find that you accumulate a set of doits -- handy snippets of Smalltalk code. Not worthy of making into full-blown classes, they're still handy to have around. The PowerDoitManager is a great way to manage them. Look for the app K8DoitManager in a library near you. This is an internal OTI tool.


Created and maintained by Brian de Alwis (bsd@cs.ubc.ca).