System has standard protocol for interacting with users:
#confirm: - prompts 'yes'/'no', answers true or
false respectively
#errorMessage: - displays error message
#message: - displays informational message
#proceed: - like #confirm: but prompts
'OK'/'Cancel', answering true or false respectively
#prompt: - answer the string or nil if cancelled
#prompt:answer: - same as #prompt: but
with a default response
Behavior
Behavior provides:
Object provides:
Application Protocol
#areReleased:
#asScratch
#classEditionNamed: className at: timeStamp
#classEditionsFor: className
#classes
#defined
#extended
#releasedClassVersions
#existsInLibrary
#isApplication
#isSubApplication
#isEdition
#isVersion
#previousTimeStamp
#signature
#timeStampFor: classOrClassName
#versionName
#timeStamp
#timeStamps
#shadows
#shadowAt: timeStamp
Application and SubApplication also support
#shadowsFor:, which takes an application name. It is
roughly equivalent to:
(Smalltalk classAt: appName) shadows
Application classes
#packagingRulesFor:
#packagerIncludeClassNames
#packagerIncludeSelectors
#packagerKnownSymbols
#packagerIncludeMethods (answers collection of methods)
#packagerIgnoreSelectors
#packagerIgnoreReferencesInSelectors
#packagerIncludeDoitMethods (answers collection of methods)
It sure would be handy to have a list of packager rules, wouldn't it?
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:
EmClassEditionEntry compareMethodSource: true.
System
fileOutComments: true;
fileOutDescriptions: true;
fileOutCategories: true.
EtTools stackPanes: true.
EtClassBrowser methodFiltering: #ShowPublicPrivateAll.
EtClassBrowser selectAllCategoriesByDefault: true.
OSErrorXGot 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)
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
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.
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]].
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.
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]
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.