The following list details methods that you can include in your application to make it more "packager friendly". Note that these methods should be defined as class methods in your application class.
This method should return a list of method names that are not directly referenced by your application, but which you want to include in the packaged image. You might use this method if your code uses perform: to send messages at runtime. For example, suppose a class implements seven methods, one for each day of the week, and you call these methods based on the following code:
dayMethod := Date today asLowercase asSymbol. self perform: dayMethod.
Then, the seven methods are not directly referenced and the packager will assume that they are not needed in the packaged image. To include them, implement the following class method in the application class:
packagerIncludeSelectors "Return a list of method selecors that must be included in the packaged image." ^#(monday tuesday wednesday thursday friday saturday sunday)
The packager assumes that any symbols it finds in the source code of
applications are references to methods. The packager does this to
minimize problems caused by the use of perform:, as noted
above. When the packager looks for errors, it may produce a list of
warnings related to symbols that are used only to describe state and are not
used as selectors. To eliminate these errors, your application can
return a list of known symbols. The application should provide a class
method named packagerKnownSymbols that returns a list of these
symbols.
![]() | You can use atoms instead of symbols for the purpose of identifying state. For example, use ##mode instead of #mode. Atoms are instances of EsAtom. The packager does not interpret atoms as selectors, so the use of atoms reduces the need for packagerKnownSymbols. |
Sometimes no direct references to classes in your application code exist in the packaged image. This situation can occur when, for example, you read data from an external file and convert it into objects within the image.
For example, suppose you want to create, from an ASCII file, EmployeeRecord (an abstract class) that may be SalariedEmployeeRecord or WeeklyEmployeeRecord (concrete subclasses). You can read an identifier from the file and then broadcast a message to subclasses of the abstract class to determine which kind of object is in the file at this point. For example:
EmployeeRecord allSubclasses detect: [:class | class forIdentifier: identifierJustRead].
The class thus identified (which has to know by which identifier it is described) then reads the rest of its information from the stream.
Because a message was broadcast to subclasses, there is no direct reference to the subclasses. If there are no other references to these classes, the packager will omit them and the application will fail.
If your application uses this technique or a similar one, it should implement a class method named packagerIncludeClassNames, which returns a list of classes to include in the packaged image. In the above example, the method may look like the following:
packagerIncludeClassNames "Return a list of class names that must be included in the packaged image." ^EmployeeRecord allSubclasses collect: [:each | each symbol].
Sometimes a class may override the doesNotUnderstand: method and then redispatch a different method. For example, you might have a set of selectors (#sequentialFile, #keyedFile, and #directFile) that are sent to some central point, trapped through doesNotUnderstand:, then redispatched as #sequentialFileFor:, #keyedFileFor:, and #directFileFor: to an appropriate service by code such as the following:
doesNotUnderstand: aMessage "Forward the given request to the appropriate service." | oldSelector newSelector service | oldSelector := aMessage selector. newSelector := (oldSelector, 'For:') asSymbol. service := self serviceAppropriateFor: oldSelector. ^service perform: newSelector with: self
If your application uses this coding style, you should define the method packagerTranslateSelectors in your application class. This method should return a dictionary with the keys being the original selectors and the values being the redispatched selectors. The packager will then include in the packaged image methods referenced by both the key and value of each entry. In the above example, the method would look like this:
packagerTranslateSelectors "Return a dictionary of translated selectors." ^Dictionary new at: #sequentialFile put: #sequentialFileFor:; at: #keyedFile put: #keyedFileFor:; at: #directFile put: #directFileFor:; yourself.
This method allows an application to provide a list of selectors to which references can be ignored. This method is functionally identical to packagerKnownSymbols, however, methods identified with packagerIgnoreSelectors are not made visible to the user.
This method returns a list of selectors. The packager will ignore any invalid references inside of the methods represented by this list.