Tcl: activate / deactivate namespace? - namespaces

In Tcl, namespace eval <ns> <script> can be used to execute the <script> in the given namespace <ns>, e.g. namespace eval ns1 {set x 123}.
Is there a way in Tcl to activate a namespace such that the subsequent commands are executed within this namespace, and maybe later deactivate it? Fictive code:
namespace activate ns1
set x 123
namespace deactivate ns1

No. Commands are always executed in the current namespace.
You could hack something together for interactive use (namespace is a built-in ensemble command so you can add to its map, and you can have your own REPL without too much work that wraps things in namespace eval at the right point) but that isn't going to be respected particularly by saved scripts.
If you just want this to make commands (including procedures and classes) in a namespace more conveniently available, you can set a namespace path, which is a list of namespaces to resolve command names in (after the current namespace and before the global namespace; at the global level it is effectively just "after the global namespace".) It doesn't change where the things you define are made by default, and doesn't affect the lookup or either variables or namespaces. The path works by setting up a command resolver; the fixed locations of the current and global namespaces in the path resulted in the greatest compatibility with existing code in manual testing...
For completeness... There are variable resolvers as a concept as well, but they're very hard to use (and deeply strange, and called at odd times) and really aren't recommended for anyone not diving very deep. They're not in the public language API except in one place in a very limited way that isn't helpful to your question. They mostly won't help you with where variables are created anyway.

Related

How to make a function file in Ocatve with multiple functions

I know that you can make a function file in Octave in which the file name is the same as the function which defines one function, but I would like to define multiple functions in one file. Is there any way to do this, or do I need a separate file for each function.
In this answer I will assume that your main objective is a tidy workspace rather than explicitly a one-file requirement.
Let's get the one-file approach out of the way. You can create a script m-file (not a function m-file), and define a number of command-line functions there. The octave manual has a section on this. Here's an example:
% in file loadfunctionDefinitions.m
1; % statement with side-effect, to mark this file as a script. See docs.
function Out = Return1(); Out = 1; end
function Out = Return2(); Out = 2; end
% ... etc
% in your main octave session / main script:
X = Return1() + Return2();
However, this is generally not recommended. Especially if you would require matlab compatible code, since matlab introduced 'script-local functions' much later than octave, and decided to do it in a manner incompatible to the existing octave implementation: matlab expects script-local functions to be defined at the end of the script; octave expects them to be defined before first use. However, if you use normal function files, everything is fine.
While I appreciate the "I don't like a folder full of functions" sentiment, the one-function-per-file approach actually has a lot of benefits (especially if you program from the terminal, which makes a wealth of tools twice as useful). E.g. you can easily use grep to find which functions make use of a particular variable. Or compare changes in individual functions from different commits, etc.
Typically the problem is more one of having such function files littering the directory, when other important files are present, e.g. data etc, and having so many files in one place makes finding what you want hard to spot, and feels untidy. But rather than have a single file with command-line definitions, there are a number of other approaches you can take, which are probably also better from a programmatic point of view, e.g.:
Simply create a 'helper functions' folder, and add it to your path.
Use subfunctions in your main functions whenever this is appropriate, to minimize the number of unnecessary files
Use a private functions folder
Use a 'package directory', i.e. a folder starting with the character '+', which creates a namespace for the functions contained inside. E.g. ~/+MyFunctions/myfun.m would be accessed from ~/ via MyFunctions.myfun(), without having to add +MyFunctions to the path (in fact you're not supposed to).
Create a proper class directory, and make your functions methods of that class
The last option may also achieve a one-file solution, if you use a newer-style classdef based class, which allows you to define methods in the same file as the class definition. Note however that octave-support for classdef-defined classes is still somewhat limited.

Include global .ocamlinit in local init

I'd like to include my global ~/.ocamlinit file when there is a project-local .ocamlinit as well, eg. in the local directory, since I do things like set my utop history file name in ~/.ocamlinit.
To that effect, I tried
#use (Filename.concat (Sys.getenv "HOME") ".ocamlinit");;
Of course that doesn't work, so I looked at toplevel directives, but they all appear to take string arguments. How best to do this?
I guess, more generally, the question is how pass non-constants to the top-level directives (not sure if the directives are preprocessed before any code is evaluated).
You can use the programmatical interface provided by the compiler-libs package. E.g.,
Topdirs.dir_use Format.err_formatter (Filename.concat (Sys.getenv "HOME") ".ocamlinit")
Should work without requiring any dependencies.

"package require" command doesn't work in a TCL Thread

I worked on a TCL script that takes a bit of time to execute. In order to to run it faster, I would like to use multi-threading using the Thread package. The problem is that I execute my TCL script in an engineering software called Hypermesh. It supports TCL scripting quite well since everything that can be done in the software has an associated TCL command.
For example if the user was to use Hypermesh to create a node at coordinate (x, y, z) then the same result can be obtained using the command *createnode $x $y $z.
Back to the multi-thread problem: I can create threads just fine but inside the thread, I cannot use the command *createnode because it is not recognized. I am guessing it is because some packages are not loaded inside the thread. I would like to load those missing packages with "package require" but no matter how I tried, it could not find any package.
I found out that inside a thread, the auto_path variable does not exist. I tried to create it, but it still would not work.
It looks like my thread can execute basic TCL buit-in commands and nothing else.
On the other hand, when I created a Thread using wish, I did not have this problem at all. All the packages "outside" the thread were also directly loaded "inside".
Here is how my code looks like:
package require Thread
package require Ttrace
set scriptToSend {
package require Trf
return 0
}
set t1 [thread::create]
thread::send -async $t1 $scriptToSend result
puts $result
Trf is just a random package that can be loaded just fine when "package require" is called outside of t1
Is there any way I could setup the thread to have all the commands that exist outside the thread? For example by making the use of package require possible?
EDIT:
I spent some more time on this problem and tried to use tpool instead of thread. The threads created in tpool seem "better". Unlike with thread, they do have an auto_path variable and I am able to use it to successfully load packages when using threads. However now I have more of an Hypermesh issue since it does not let me load all the necessary packages to use procs such as *createnode.
I will try to go around the problem by making my threads do as much as they can without using any Hypermesh function. It will still speed up the script quite a bit.
Tcl uses a limited version of the auto_path global in threads by default because it doesn't set it up in quite the same way (e.g., it doesn't evaluate your ~/.tclshrc). To use the same packages as in the main thread, you'll need to transfer a copy of that variable over.
thread::send $otherThread [list set ::auto_path $::auto_path]
Do that before sending other scripts to the subthread in order to synch things up.
On my system I'd see this sort of thing too:
bash$ tclsh8.6
% puts $::auto_path
/opt/local/lib/tcl8.6 /opt/local/lib /opt/local/lib/tcllib1.19
% package require Thread
2.8.4
% set otherThread [thread::create]
tid0x7000053ab000
% puts [thread::send $otherThread {set ::auto_path}]
/opt/local/lib/tcl8.6 /opt/local/lib
There's also the module path (controllable via the tcl::tm::path command) but that's the same for me in the subthread as in the main thread.

How to disable a modified tclsh interpreter interactive mode?

Run tclsh command without any tcl file, the interpreter will go into interactive mode.
Can I simply disable this feature by modifying the tclsh source code ?
I can't imagine why you would want to bother doing this, given that supplying any script file will turn off interactive mode. The script you supply will have full access to the additional arguments passed in (a list in the global argv variable) and the standard IO channels (stdin, stdout and stderr). It can exit when it is done. Literally anything you want can be done at that point; you've just got to write a script to do it.
If you're including Tcl in your own program, the behaviour of tclsh is implemented in the C function Tcl_Main. If you never call that — instead just using Tcl_FindExecutable, Tcl_CreateInterp and Tcl_Eval/Tcl_EvalFile — then you never get any of that interactive behaviour. While theoretically you could modify the Tcl source itself to do what you want — it's all open source — why would you bother when you could just not call that code in the first place?

Does RTLD_FIRST on mac do the job of RTLD_DEEP_BIND on linux?

My understanding of RTLD_DEEP_BIND on linux is that if you have a function A() in your main program, and two functions A() and B() in a dynamically linked library (call it lib) where B is defined as:
B()
{
A();
}
Then a call to B() would ALWAYS end up calling A from the library. Is this the job that RTLD_FIRST does on a mac? Sorry - I am confused by the docs.
What RTLD_DEEPBIND seems to do is the default on OS X. OS X uses something called two-level namespace for dynamic libraries, by default. (You can force the use of flat namespaces either at link time or load time.) With two-level namespace, symbol references record not only the symbol name but the library with which the symbol was resolved at link time. Then, at load time, the symbol is only resolved against that same library.
No. RTLD_FIRST is simply a flag that affects how dlsym behaves when called with the resulting handle, while RTLD_DEEPBIND affects how symbols are resolved when loading the library. They're both rather poorly documented, but that's the information I found base on the man pages for OSX and Linux.