Skip to content

Commit

Permalink
feat(defmulti): allow .add() to overwrite existing impl, add logger
Browse files Browse the repository at this point in the history
- update .add() to log warning msg when overwriting existing impl
- add LOGGER, setLogger()
- update tests / readme
  • Loading branch information
postspectacular committed Oct 20, 2019
1 parent 2044583 commit e387622
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 5 deletions.
3 changes: 2 additions & 1 deletion packages/defmulti/README.md
Expand Up @@ -46,7 +46,8 @@ varargs solution.
The function returned by `defmulti` can be called like any other
function, but also exposes the following operations:

- `.add(id, fn)` - adds new implementation for given dispatch value
- `.add(id, fn)` - adds/overrides implementation for given dispatch
value
- `.remove(id)` - removes implementation for dispatch value
- `.callable(...args)` - takes same args as if calling the
multi-function, but only checks if an implementation exists for the
Expand Down
8 changes: 7 additions & 1 deletion packages/defmulti/src/api.ts
Expand Up @@ -8,7 +8,9 @@ import {
Fn7,
Fn8,
FnAny,
IObjectOf
ILogger,
IObjectOf,
NULL_LOGGER
} from "@thi.ng/api";

export const DEFAULT: unique symbol = Symbol();
Expand Down Expand Up @@ -303,3 +305,7 @@ export interface MultiFn8O<A, B, C, D, E, F, G, H, I, T>
MultiFnBase<Implementation8O<A, B, C, D, E, F, G, H, I, T>> {}

export type AncestorDefs = IObjectOf<Iterable<PropertyKey>>;

export let LOGGER: ILogger = NULL_LOGGER;

export const setLogger = (logger: ILogger) => (LOGGER = logger);
5 changes: 4 additions & 1 deletion packages/defmulti/src/defmulti.ts
Expand Up @@ -21,6 +21,7 @@ import {
DispatchFn8,
DispatchFn8O,
Implementation,
LOGGER,
MultiFn,
MultiFn1,
MultiFn1O,
Expand Down Expand Up @@ -105,7 +106,9 @@ export function defmulti<T>(f: any, ancestors?: AncestorDefs) {
: unsupported(`missing implementation for: "${id.toString()}"`);
};
fn.add = (id: PropertyKey, g: Implementation<T>) => {
if (impls[<any>id]) return false;
if (impls[<any>id]) {
LOGGER.warn(`overwriting '${id.toString()}' impl`);
}
impls[<any>id] = g;
return true;
};
Expand Down
10 changes: 8 additions & 2 deletions packages/defmulti/test/index.ts
@@ -1,9 +1,11 @@
import { ConsoleLogger } from "@thi.ng/api";
import * as assert from "assert";
import {
DEFAULT,
defmulti,
defmultiN,
implementations
implementations,
setLogger
} from "../src/index";

// prettier-ignore
Expand All @@ -26,10 +28,14 @@ describe("defmulti", () => {
assert(exec.add("+", ([_, ...args]) => args.reduce((acc: number, n: any) => acc + exec(n), 0)));
assert(exec.add("*", ([_, ...args]) => args.reduce((acc: number, n: any) => acc * exec(n), 1)));
assert(exec.add("number", (x) => x));
assert(!exec.add("number", (x) => x));
assert(exec.add(DEFAULT, (x) => { throw new Error(`invalid expr: ${x}`); }));

assert.equal(exec(["+", ["*", 10, ["+", 1, 2, 3]], 6]), 66);

setLogger(new ConsoleLogger("defmulti"));
assert(exec.add("number", (x) => x * 2));
assert.equal(exec(["+", ["*", 10, ["+", 1, 2, 3]], 6]), ((1*2 + 2*2 + 3*2) * 10*2) + 6*2);

assert.throws(() => exec(""));
});

Expand Down

0 comments on commit e387622

Please sign in to comment.