For a simple ScriptX title that is to be distributed to others, you might define a single module that uses the ScriptX module. It can also use other modules-such as modules associated with library or accessory containers.
module MyOwnTitle uses ScriptX end
in module MyOwnTitle
-- build your title here . . .
For simple programs, encapsulating code within modules and importing and exporting variables is reasonably straightforward. Larger and more complex programs, with multiple modules that use and are used by each other, can create complex dependencies. In large networks of modules, it may become difficult to keep track of the relationships between modules.
The interface/implementation model is a model for designing networks of modules. Using the interface/implementation model, you can create modules with implicit circular use relationships. You can combine interfaces to construct customized, general interfaces that are based on the needs of the client module.
The interface/implementation model can also be used to define multiple interfaces to the same ScriptX program. For example, a code library could have an interface for end users and an interface for programmers-without duplicating any code
This section describes how the interface/implementation model can be used to create a better structure for large ScriptX programs.
in module
expression
and should have no code associated with them at all. Interface
modules are used by other modules, but do not use any other
modules.
The module
BakeryInterface
exports the variable
rye
, but does not provide a definition for that
variable. BakeryInterface
is an interface module.
Note that BakeryInterface
does not use any other
modules (including the ScriptX module).module BakeryInterface
exports rye
end
Figure 9-4: Interface module
Bakery
, uses the
BakeryInterface
module and provides a definition
for the imported variable rye
.
Bakery
is the implementation module for
BakeryInterface
.module Bakery
uses BakeryInterface
end
in module Bakery
global rye := "rye bread"
Figure 9-5: Implementation modules
Bakery
module does not, and should not,
re-export the rye
variable. The purpose of the
Bakery
module is simply to provide an
implementation for variables exported elsewhere; it is not
used by any other modules.BakeryInterface
(clients of the BakeryInterface
module)
automatically receive the definitions of those variables from
Bakery
even though they were not explicitly
exported. For example, if the Delicatessen
module
uses BakeryInterface
, Delicatessen
has access to the definition of rye
in
Bakery
even though Bakery
didn't
export rye
and Delicatessen
didn't
use Bakery
. module Delicatessen
uses ScriptX, BakeryInterface
end
in module Delicatessen
print rye
"rye bread"
Figure 9-6: Client modules
Delicatessen
needs to use the
ScriptX module to have access to the print
function. Like other global functions, print
is a
part of the object system, and not of the ScriptX language
itself.ScriptX
,
Substrate
, and Scratch
modules. In
Figure 9-7, the diagram in Figure 9-6 has been relabeled to
demonstrate this relationship between system modules. The
ScriptX
modules acts as an interface module, and
the Substrate
module as an implementation module.
The Scratch
module, and any user-defined modules
that use the ScriptX
module, are clients of the
ScriptX
module.
Figure 9-7: The ScriptX, Substrate and Scratch
modules
Circular Module References
module DrawInterface
exports line, rectangle, circle
end
module PaintInterface
exports pencil, brush, fill
end
module DrawImplementor
uses ScriptX, DrawInterface, PaintInterface
end
module PaintImplementor
uses ScriptX, PaintInterface, DrawInterface
end
Figure 9-8: Circular module
references
DrawImplementor
module provides
definitions for the DrawInterface
module. It is
also a client of the PaintInterface
module, whose
definitions are, in turn, provided in
PaintImplementor
. Finally,
PaintImplementor
is a client of
DrawInterface
, which completes the
circularity. Combining Module Interfaces
Figure 9-9: Paint and draw interfaces and
implementations
GraphicsInterface
) that does nothing except use
the other two interface modules, and re-export the variables
it imported from those modules. Clients of
GraphicsInterface
have access to all the
variables in both the PaintInterface
and
DrawInterface
modulesFigure 9-10: Paint and draw interfaces and
implementations
Multiple Interfaces, One
Implementation
MusicModule
implementation, you could have
multiple interfaces, each of which provides access to only
some of the variables within that module. For example, a
ClassicalMusic
interface module would provide
access to violin
, flute
, and
harpsichord
; a RockNRoll
module
would include electricGuitar
and
drumKit
; and a Madrigals
module
would include access to voices such as altoVoice
,
and bassVoice
.Figure 9-11: Multiple interfaces, one
implementation
NewUser
, IntermediateUser
,
or AdvancedUser
. By providing separate interfaces
for each of those users, you could provide a subset of
features to the new user, more features to the intermediate
user, and a complete set to the advanced user.Figure 9-12: Pass-through
interface/implementation model
Using a Build Module
Figure 9-13: Using a build module to compile a
project
Defining an Accessory Protocol
module GidgetAccessoryInterface
exports instance variables accessoryProtocols
exports addToPresenter, GidgetClass
end
GidgetTitleImplementation
module, in turn,
uses both the ScriptX
and
GidgetAccessoryInterface
modules. Within this
module, the accessoryProtocols
instance variable,
the generic addToPresenter
, and the class
GidgetClass
are defined. Since they are defined
there, they are also saved there.module GidgetTitleImplementation
uses ScriptX, GidgetAccessoryInterface
end
GidgetAccessoryInterface
should define its own
module.module GidgetAccessoryImplementation
uses ScriptX, GidgetAccessoryInterface
end
ScriptX
module as the "accessory interface" for the ScriptX core
classes. Every module that uses the ScriptX
module is running as an accessory to ScriptX, which is
implemented in the Substrate
module. Just as the
substrate makes a portion of the names it defines visible in
the ScriptX
module, any user-defined module can
export some of the names it defines through its own interface
module.
This document is part of the ScriptX Language Guide, one of the volumes of the ScriptX Technical Reference Series. ScriptX is developed by the ScriptX Engineering Team at Apple Computer, successor to the Kaleida Engineering Team at Kaleida Labs, Inc.