-
Notifications
You must be signed in to change notification settings - Fork 16
ns.q
This library provides introspection functions and namespace query functions which can be particularly of use for testing libraries.
This function gets the contents of the specified namespace and returns them fully qualified (i.e. so they can be used with get
).
Example:
q) .ns.get `.ns
`.ns.get`.ns.flatten`.ns.resolveFunctionName`.ns.isSet`.ns.getFunctionArguments
This function returns the namespace contents and the contents of any child namespace recursively until no more namespaces are found.
q).ns.flatten `.os
`.os.type`.os.init`.os.run`.os.availableCommands`.os.w.mkdir`.os.w.rmdir`.os.w.pwd`.os.w.rm`.os.l.mkdir...
This function attempts to resolve the supplied function body back into the declared function name. Can be very useful when debugging.
Example:
q) .bb.testFunc:{1+`a}
q) .bb.testFunc[]
{1+`a}
'type
+
1
`a
q)) .ns.resolveFunctionName .z.s
`.bb.testFunc
This function determines if the namespace reference specified is exists or not in the current process (via protected execution).
Example:
q) .ns.isSet `.ref.does.not.exist
0b
q) .ref.does.exist:1b
q) .ns.isSet `.ref.does.exist
1b
This function returns the list of arguments the specified function expects to be executed. The function can be passed by reference or by value. It supports:
- lambda (
100h
) - unary primitive (
101h
) - operator (
102h
) - iterator (
103h
) - projection (
104h
)
Examples:
q) .func.argCount:{[arg1; arg2] arg1 + arg2 }
// Pass by reference
q).ns.getFunctionArguments `.func.argCount
`arg1`arg2
// Pass by value
q).ns.getFunctionArguments .func.argCount
`arg1`arg2
q).ns.getFunctionArguments (::)
,`x
q).ns.getFunctionArguments (+)
`x`y
q).ns.getFunctionArguments (')
`x`y
q).ns.getFunctionArguments {[x;y;z] z }[;1;]
`x`z
// If reference specified does not exist
q).ns.getFunctionArguments `.func.noFunction
'FunctionDoesNotExistException (.func.noFunction)
[0] .ns.getFunctionArguments `.func.noFunction
Performs a protected execution (try/catch) of the specified function (by value or reference) with the specified arguments.
If the execution is sucessful, the executed function result is returned. If the execution fails, a dictionary is returned:
-
isError
: Will be set to the constant symbol defined in.ns.const.pExecFailure
-
errorMsg
: Will be set to the exception string that caused the function to fail
If the version of kdb+ used is >= 3.5, the error dictionary will also include the error stack (in backtrace
).
The error stack collection can be disabled manually by setting .ns.cfg.protectExecWithStack
to 0b
.
Example:
q) .pe.example:{[x;y] x+y}
// OK execution returns result
q).ns.protectedExecute[`.pe.example; 1 2]
3
// Failed execution returns error dictionary
q).ns.protectedExecute[`.pe.example; (1;`a)]
isError | `PROT_EXEC_FAILED
backtrace| " [2] .pe.example:{[x;y] x+y}\n ^\n [.."
errorMsg | "type"
// 'backtrace' can be printed for additional detail
q)-1 .ns.protectedExecute[`.pe.example; (1;`a)]`backtrace
[2] .pe.example:{[x;y] x+y}
^
[1] /home/jas/git/kdb-common/src/ns.q:116: .ns.protectedExecute:
$[.ns.cfg.protectExecWithStack;
:-105!(get func; args; { `isError`backtrace`errorMsg!(.ns.const.pExecFailure; .Q.sbt y; x) });
^
/ else
[0] -1 .ns.protectedExecute[`.pe.example; (1;`a)]`backtrace
This function allows you to execute functions from an input dictionary of those arguments.
A good use case for this is a function that is exposed on a gateway process. Generally these require dictionary inputs (to allow arguments to be added by the gateway en-route to the underlying process). This function allows you to write the underlying function use standard arguments (e.g. myGatewayFunc:{[arg1;arg2;arg3]
) and accept arguments into the gateway and translate between them.
The function also validates that all arguments required by the underlying function are present in the dictionary before execution. It can also deal with functions that require no arguments. In this case an empty dictionary (()!()
) should be supplied.
Note that any elements on the dictionary that do not map to function arguments are ignored.
q) .jas.func:{[x1;x2] x1 + x2 }
q) .ns.executeFuncWithDict[`.jas.func; `x1`x2!4 5]
9
q) .jas.noArgFunc:{ -1 ".jas.noArgFunc ran" }
q) .ns.executeFuncWithDict[`.jas.noArgFunc;()!()]
.jas.noArgFunc ran
-1
q) .jas.func:{[x1;x2] x1 + x2 }
q) .ns.executeFuncWithDict[`.jas.func; enlist[`x1]!enlist 1]
'MissingFunctionArgumentException (,`x2)
Deletes the specified object reference from its namespace.
Additionally, if the object deleted is the last object in the namespace then the namespace is removed as well recursively up the namespace tree. However the root namespace is never deleted.
q) .a.b.c:123
q) .a.b.d:1 2 3!1 2 3
q).a.b
| ::
c| 123
d| 1 2 3!1 2 3
q) .ns.deleteReference `.a.b.d
q) .a.b
| ::
c| 123
// Delete empty sub-namespaces recursively when single element deleted
q) .ns.deleteReference `.a.b.c
q) .a.b.c.d.e.f:1
q) .a
| ::
b| ``c!(::;``d!(::;``e!(::;``f!(::;1))))
q).ns.deleteReference `.a.b.c.d.e.f
q).a
| ::
Provides a symbol reference to the function that called the function that calls this function.
q) .jas.callee:{ .log.info (".jas.callee was called by {} with arg {}"; .ns.getFunctionCaller[]; x); }
q) .jas.caller:{ .jas.callee 123 }
2022.10.29 09:09:18.882 INFO pid-2306 jas 0 .jas.callee was called by .jas.caller with arg 123
// Supports parent anonymous functions and calling from the q prompt directly
q) .jas.callee[]
2022.10.29 09:12:37.510 INFO pid-2687 jas 0 .jas.callee was called by q-prompt with arg ::
q) { .jas.callee[] } []
2022.10.29 09:12:42.432 INFO pid-2687 jas 0 .jas.callee was called by anon-func with arg ::
Copyright (C) Sport Trades Ltd 2017 - 2020, John Keys and Jaskirat Rajasansir 2020 - 2024