Public interface to a package
How to control which objects of a Tatin package are exposed to its users
By default, the public interface of your package is all its top-level objects:
⎕NL 2 3 4 9
The API space serves as a filter: referring to anything but the exposed names signals an error.
You can instead select objects to expose by specifying an API space: a namespace with references only to the exposed objects. Then when the package is loaded into the workspace, the contents go into the package cache, and its handle points to its API namespace.
For example, MarkAPL has an API space (called API
) with references to its exposed functions.
#.MarkAPL
#._tatin.aplteam_MarkAPL_13_1_0.API
api
setting in the package config tells Tatin how to use it.
Define an API space
Suppose package APkg consists of a single scripted namespace Core
with multiple variables, functions, and operators of which only Encode
and Decode
should be exposed
– as #.APkg.Encode
and #.APkg.Decode
.
In the Core
script you could create this structure
#.APkg
#.APkg.Core
... ⍝ vars, fns and oprs
#.APkg.Core.API
#.APkg.Core.API.Encode
#.APkg.Core.API.Decode
API.Decode←{⍺ ##.Decode ⍵}
API.Encode←{⍺ ##.Encode ⍵}
api
setting specify Core.API
.
The two functions would be exposed as #.APkg.Decode
and #.APkg.Encode
– and nothing else would.
Suppose you had reason not to modify the Core
script.
Just include a second namespace in your package:
:Namespace API
Decode←{⍺ ##.Core.Decode ⍵}
Encode←{⍺ ##.Core.Encode ⍵}
:EndNamespace
api
setting specify API
.
The effect would be the same.
An API can use multiple sources.
Suppose you have a third namespace: More
.
:Namespace API
Decode←{⍺ ##.Core.Decode ⍵}
Encode←{⍺ ##.More.Encode ⍵}
:EndNamespace
Create an API from the config
For many packages, Tatin can create the API space for you, at build or load time.
Specify the API space in the api
setting of the package config and list what is to be exposed in it.
Function CreateAPIfromCFG
creates the API space as a child of the source namespace and populates it with references to the exposed ojects.
You can substitute for this list (or override it) with an optional left argument.
It looks in the package for a constant Public
that names the objects to expose.
This list of strings can name functions, operators, variables, interfaces, classes and namespaces, both simple and scripted.
The objects must all be children (or, with dot syntax, grandchildren) of a single source namespace.
You can create the API by calling CreateAPIfrom CFG
- at load time from a function specified as the package’s
lx
setting - at build time, incorporating the API into the built package
If your source is a single scripted namespace, you cannot use CreateAPIfromCFG
The function cannot create a child space of a scripted namespace.
Instead, define an API space directly: see above.
Some scenarios
To expose from your package APkg (as e.g. #.APkg.Hello
)
object/s from | api | CreateAPIfromConfig |
---|---|---|
a single namespace Foo |
Foo |
|
a single scripted namespace | API |
|
a single class Foo 1 |
Foo |
|
multiple namespaces | API |
-
In a class, use
:Field
and:Access
declarations to expose objects. ↩