Load q file relative to current script instead of relative to working directory

Viewed 171

I want to load a q script that is relative to the source file I am currently in regardless of where I was when the q process started.

So for example I have the following project:

- myproject/
    a.q
    b.q

In a.q I have the following line somewhere:

...
system"l b.q";
...

My problem is that this only works when I cd to myproject/ so that b.q is in the current working directory.

I want to be able to load b.q from a.q regardless of where I start the script without using absolute paths

(In python I could do this for example with the use of os.path.realpath())

3 Answers

one way you could achieve this is with environmental variables. You could set these up before launching a q session with the export command in bash. A quick example for you here:

$ export TABLE=/home/mclark/tab.q
$ q

q)getenv[`TABLE]
"/home/mclark/tab.q"

This way the absolute pathway of your files is saved, and you could load in your scripts in a similar manner.

If you don't want to use environmental variables, you could start to play around with .z.o and .z.f. Here is a quick example here where I am loading in a file that contains a dictionary dict:

$ q path/a.q
q)dict
'dict
  [0]  dict
       ^
q)loadfunc:{system"l ",(first system $[.z.o like "w*";"cd";"pwd"]),"/",(1_string first ` vs hsym .z.f),"/",x}
q)loadfunc"example.q"
q)dict
a| 1
b| 2

.z.f will print the name of the q script passed in upon starting the q process so `path/a.q in the above example. Hopefully a function like this could give you a bit more flexibility on this front.

You can do it using this bit of trickery that Charlie Skelton came up with on the k4 listbox:

thisFile:hsym`$(reverse value {})2;
thisPath:first` vs thisFile;
otherFile:` sv thisPath,`other.q;

Some caveats - it only works when the code is run as part of a script (i.e. it doesn't work if you run these lines manually in a session or IDE). Second caveat is that it doesn't work if you scramble your q scripts using \_. Third caveat is that the output of value may be subject to change between kdb versions

At the top of a.q, before you do anything else that could influence it:

startDir: ` sv (hsym `$system"cd";first ` vs .z.f);

That should give you a fully qualified path to the directory of a.q, which you can then use to load b.q:

system "l ", 1_ string ` sv (startDir;`b.q);
Related