1

In our application, the .z.u function (which returns the username) was originally treated in a case-sensitive manner—so Test2001 and test2001 were considered two distinct users. We've recently decided to make usernames case-insensitive, which required updating all occurrences where .z.u was used (and there were quite a few).

Given this, I'm wondering what the best practice is for using functions like .z.u, and more generally, functions from the .z and .Q namespaces.

Would it make sense to define a wrapper function like: .util.extractUser:{lower .z.u} to centralize this behavior?

And if so, should we consider wrapping other commonly used .z or .Q functions as well, in case we need to modify their behavior later (e.g. due to changes in business logic or updates in kdb+ itself)?

0

2 Answers 2

1

.util namespaces are common. Items get added on case by case basis.

Example: https://github.com/BuaBook/kdb-common/blob/master/src/util.q#L80

/  @returns (Boolean) If the current process is in debug mode or not
.util.inDebugMode:{ :1i = system "e" };

/  @returns (Boolean) True if the process is bound to a port, false if not
.util.isListening:{ `boolean$system"p" };
Sign up to request clarification or add additional context in comments.

2 Comments

I understand, but what's best practice when using .z or .Q functions ? Using a function defined in .util namespace that's a wrapper around these functions or just using the actual .z function ? I mean I know they're not changing often, but what if they do? That would require many changes in any kdb app.
Only wrap when/if needed. Otherwise use them as supplied from the language.
0

In general, .z functions (not .z variables) are encouraged to be overwritten as is. For example .z.pg, .z.ps, .z.pc, .z.po etc. In fact you can't trigger such callbacks without modifying the vanilla functions. Your example of .z.u is a bad example, it's not a function so you can't replace it with a function/logic of your own and even if you could it ignores overwrites:

q).z.u
`tlynch
q).z.u:`ABC
q).z.u
`tlynch

For .Q functions it is possible to overwrite and/or create your own but it is usually discouraged.

In terms of how to handle a codebase which references a lot of these built-ins, personally my preference it to allow each individual script/user use the known built-ins rather than soulless .util functions. Otherwise reading the code becomes a tedious exercise of .util lookups (who needs .util.plus?!). Of course that then means that to control certain behaviour (particularly after it's already written) you need gain control of the primitive, with the alternative being to modify many scripts in many places. Again, it's often down to personal preference since in most cases it's possible to do it either way.

One final point to add, sometimes it can be useful to retain vanilla behaviour when gaining control over a built-in. One sensible way to do this is to pass the vanilla function into your custom function and applying the vanilla function within yours. For example

.z.pg:{[orig;x] myotherlogic[];orig x}[.z.pg;]

This essentially snapshots the existing .z.pg as "orig" and applies that built-in logic within your custom function. (just be careful if this override runs twice then you'll be snapshotting the custom logic, not the original)

2 Comments

indeed. I did not want to overwrite the .z.u I wanted to create a function .util.getUser:{lower .z.u} and I was wondering why isn't it best practice in kdb to do that for all functions rather then use them as they are for example .util.getTimeStamp:{.z.p}. This way if any future version of kdb changes the output, you'll just have to modify 1 function rather than modifying each instance of .z.p
You can do that for sure, as I said it's often personal preference. But unless you've rolled out these various utils from day 1 it would arguably be more work to replace all uses than it would be to gain control of the primitive, particularly if you don't have write/access to all code that could be executed on the instance

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.