最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

kdb+ - Should I create a wrapper around `.z` function when I use them in my app? - Stack Overflow

programmeradmin3浏览0评论

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)?

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)?

Share Improve this question asked Mar 31 at 11:01 user06931912user06931912 495 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 1

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

Example: https://github/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" };

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)

发布评论

评论列表(0)

  1. 暂无评论