-
Notifications
You must be signed in to change notification settings - Fork 18
if.q
This library has been added to allow implementations of common logic to be implemented by an external system. This allows easier integration with an existing system.
An interface should be required if you do not want to define an implementation but expect the system that the library will run in to have the interface defined.
Interface definitions live within .if.cfg.interfaces
:
-
lib
: The library that the interface lives within -
ifFunc
: The interface that must be implemented -
implFunc
: The implementing function- This must be non-null at the time the interface binding is performed otherwise an exception will be thrown
- This can either be a function reference or a function body
If a library requires the interfaces to be implemented, it should call .if.bindInterfacesFor[bindLib; overwrite]
. This will ensure that the interface functions are set with the implementations defined at that point.
If any interfaces within the specified bindLib
are not defined at this point, an exception will be thrown.
Interface bindings can be changed at any point and re-initialised by ensuring overwrite
is set to 1b
.
Any interface bindings defined before the Interface library is initialised must have default implementations otherwise an exception will be thrown
The default interfaces that are defined by require.q
on initialisation are:
Library | Interface Function | Implementation Function |
---|---|---|
log | .log.if.trace |
.require.i.log |
.log.if.debug |
.require.i.log |
|
.log.if.info |
.require.i.log |
|
.log.if.warn |
.require.i.log |
|
.log.if.error |
.require.i.logE |
|
.log.if.fatal |
.require.i.logE |
When using require.q
, the interfaces above are defined. These do not need to re-bound on every library initalisation unless they have been changed.
// if.q is automatically loaded and initialised by require.q
// Log interfaces are defined and defaults to standard out and standard error are set
q) .require.init[]
...
Library initialisation function detected [ Func: .if.init ]
Binding implementations to library interfaces [ Library: log ] [ Interfaces: 6 ]
...
q) .if.cfg.interfaces
lib ifFunc | implFunc
-----------------| ----------------
| ::
log .log.if.trace| `.require.i.log
log .log.if.debug| `.require.i.log
log .log.if.info | `.require.i.log
log .log.if.warn | `.require.i.log
log .log.if.error| `.require.i.logE
log .log.if.fatal| `.require.i.logE
log.q
provided overrides for the default log interfaces defined above.
In this case, it overrides the implementing functions and re-binds the interfaces for other libraries to use.
// When the log library is loaded, it overrides these default implementations
q) .require.lib `log
...
Library initialisation function detected [ Func: .log.init ]
Binding implementations to library interfaces [ Library: log ] [ Interfaces: 6 ]
...
q) .if.cfg.interfaces
lib ifFunc | implFunc
-----------------| -----------
| ::
log .log.if.trace| `.log.trace
log .log.if.debug| `.log.debug
log .log.if.info | `.log.info
log .log.if.warn | `.log.warn
log .log.if.error| `.log.error
log .log.if.fatal| `.log.fatal
In this example, a library defines a function it requires but does not provide an implementation itself
// myLib.q
// This library requires the function '.extern.needThis' to be defined, but doesn't provide an implementation itself
.if.setImplementationsFor[`myLib; enlist `ifFunc`implFunc!(`.extern.needThis; `)];
.myLib.init:{
.if.bindInterfacesFor[`myLib; 0b];
};
In the case where no implementation is provided before library initialisation, an exception is thrown:
// No implementation provided
q) .require.init[]
...
q) .require.lib `myLib
Loading library: myLib
Loading /home/jas/git/kdb-common/src/myLib.q
Library initialisation function detected [ Func: .myLib.init ]
Interface Error: Missing implementations for library interfaces [ Library: myLib ]
Missing interfaces: .extern.needThis
Init function (.myLib.init) failed to execute successfully [ Lib: myLib ]. Error - MissingInterfaceImplementationException
Once defined prior to init, the library intialises OK:
// Provide an implementation
q) .require.init[]
...
q) .if.setImplementationsFor[`myLib; enlist `ifFunc`implFunc!(`.extern.needThis; { -1 "Implemented: ",.Q.s1 x })];
q) .require.lib`myLib
Library initialisation function detected [ Func: .myLib.init ]
Binding implementations to library interfaces [ Library: myLib ] [ Interfaces: 1 ]
Initialised library: myLib
q) .extern.needThis "Test"
Implemented: "Test"
Copyright (C) Sport Trades Ltd 2017 - 2020, John Keys and Jaskirat Rajasansir 2020 - 2024