Can functions be defined within a shebang executable GNU Octave file? - function

Given an Octave m file heading with #! /usr/bin/octave -q, can a function be defined inside this file?, or the only way to do it is to invoke functions defined in another file?

Yes, they can. The only thing is that the first Octave statement must not be a function definition which is why many Octave programs will start with 1;. However, my experience is that most Octave programs need a package so the first statements can be just the loading of said packages.
Here's an example Octave program:
#!/usr/bin/env octave
## Do not forget your license
pkg load foo;
pkg load bar;
1; # not really necessary because of the pkg load statements above
function foobar ()
## this function does something amazing
endfunction
function main (argv)
disp (argv);
endfunction
main (argv ());

Related

Is there a Tcl package init procedure?

Is there a way to define an initialization procedure that's automatically called when a Tcl package is loaded?
In this case, I need to parse a configuration file and set a namespace variable.
I originally had the code in the namespace, outside of a proc, but pkg_mkIndex tried to execute the code when it sourced the file and tossed an error "while sourcing". The package file sources just fine from tclsh, and I'm not sure why it wouldn't do so within pkg_mkIndex.
I can comment out the init routine for pkg_mkIndex's sake, if that's the proper way to do this, but I wondered if there's a built-in way to have init procedures executed automatically, a la C's main().
but I wondered if there's a built-in way to have init procedures
executed automatically
It is common practise to provide an initialisation script as part of your package ifneeded script, e.g.:
package ifneeded mypkg 1.0.0 "source [list [file join $dir mypkg.tcl]]; source [list [file join $dir myinit.tcl]]"
Using pkg_mkIndex turns out not particularly helpful in anything non-trivial, as it attempts to (partially) evaluate the source files with all their dependencies. Better handicraft the pkgIndex.tcl script and separate the concerns (pkg definition, pkg initialisation; see above).

Plotting with Gnuplot in Tk

I have seen a topic regarding to how we plot graphs with Gnuplot in Tk Canvas. Here are the simple code sample from Donal Fellows#Donal Fellows. Can someone help me on these two commands in Bold(set term tk;gnuplot .c)? I can not understand what does it mean.Thanks.
package require Tk
eval [exec gnuplot << "
**set term tk**
plot x*x
"]
pack [canvas .c]
**gnuplot .c**
When you run the gnuplot program with the terminal set to tk, it writes to its standard output a Tcl script that will create a procedure. That procedure is called gnuplot, and it takes a single argument which is the name of the canvas to plot onto. So we call the gnuplot program with the appropriate arguments to get it to tell you how to make a command that will actually do the plotting. We eval that result, make the canvas, and delegate to that newly-created gnuplot command the actual plotting on the canvas.
It's a little odd, and theoretically unsafe (what if the gnuplot is hacked?!?!?! Oh noes!) but actually works quite well in practice.
To see why it works, try doing:
puts [exec gnuplot << "
set term tk
plot x*x
"]
Instead of evaluating the code, that will print it out. You'll see that it's a procedure definition, and how exactly it all works. (Alas, I've not got gnuplot installed on this computer at the moment, so I can't do the check quite instantly for you…)
I'm not an expert of gnuplot, but as far as understand the 2 command are very simple.
set term tk
Assign the value string tk to the variable term.
gnuplot .c
Launch the command gnuplot with argument .c.
In your code the .c is just the name of the tk canvas widget.
More intriguing is the first [exec gnuplot <<...] that execute an external command called gnuplot that initialize the tk script and define the tk command gnuplot used to draw the plot on a canvas.
It looks like the external gnuplot command generate the tck code to define all what is needed.

call proc of another language in TCL if that proc is not found in TCL

Looking out for a perl's autoload equivalent in TCL. In autoload function, will try to check if in my perl library the function name is available and take action accordingly.
According to my understanding the perl Autoload functionality: If a particular function call is not finding the function, the interpreter should call the autoload function. When we write this autoload function code, this code gets executed
Regards
I'm not exactly sure what you're asking:
Tcl has auto_mkindex where you can create an index file of your Tcl libraries, and procedures can be invoked in your application without explicitly package require-ing the libraries.
Tcl has the unknown procedure that will be invoked upon "proc not found". See the wiki page for examples.

tcl - how to find the path of package loaded?

In tcl how does one find out the path of the package loaded?
% tclsh
% package require csv
I want to find out the path from which csv was loaded.
In python, one can find the path of a module using
>>> import os
>>> print os.__file__
'/a/b/python2.2.1/linux26_x86_64/lib/python2.2/os.pyc'
I am looking for a similar command in tcl
It's not that simple: a package in Tcl appears to be a more abstract thing than that in Python.
First, there are two kinds of packages: "classic" and "modules" which have different underlying mechanisms for finding what to load in response to the package require ... command.
Next, both kinds of packages are able to do whatever they wish to provide their functionality. It means they can be (but not limited to):
Pure Tcl packages, source'ing just one Tcl file or any number of files.
Packages implemented in C or another compiled language, which are in the form of dynamic library which gets loaded when the package is required.
A combination of the above, when there's a C library and a layer of Tcl code around it (usually providing helper/convenience commands).
Hence the question per se has little sense as only modules are represented by exactly one self-contained file but "classic" packages are free to implement themselves as they see fit.
On the other hand, each package normally provides (using one way or another) certain information to the package subsystem which can be retreived (and parsed) using the package ifneeded command. For instance, on my Windows system with ActiveState Tcl 8.5.x, I have:
% package require csv
0.7.2
% package ifneeded csv 0.7.2
package provide csv 0.7.2;source -encoding utf-8 {C:/Program Files/Tcl/lib/teapot/package/tcl/teapot/tcl8/8.3/csv-0.7.2.tm}
Note that what package ifneeded returns is just a Tcl script which is meant to be evaluated to get the package loaded, so parsing of this information is bound to be inherently ad-hoc and fragile.
For Tcl packages you can view list of all loadedable path dirs by command:
join $::auto_path \n
This manual addresses auto_path and other loadable library variables: https://www.systutorials.com/docs/linux/man/n-auto_path/
New or missing loadable package search directory can be added within tclsh:
lappend auto_path /new_directoty

Tcl - how to load Memchan linked statically?

I am trying to use Memchan package in my application. I was able to compile and link it statically. But unfortunately I don't know how to load this package in my application.
% rs
Internal error detected during start: can't find package Memchan
can't find package Memchan
while executing
"package require Memchan"
I traced this to the pkgIndex.tcl in Memchan2.3 directory:
% cat pkgIndex.tcl
package ifneeded Memchan 2.3 [list load [file join $dir libMemchan2.3.so]]
I have two questions:
How do I load the statically linked version libMemchan2.3.a ?
Is there a special syntax for calling package require Memchan when one calls a statically linked library?
You've got a statically linked memchan package? Well, that means you need a different package index, whose contents should be this:
package ifneeded Memchan 2.3 {load {} Memchan}
The load has an empty first argument so that statically-linked libraries are considered, but without the filename, a second argument is needed in order to locate the initialization function (which will be Memchan_Init with the above value).
Alternatively, just do this at the start of your script:
load {} Memchan
That will cause the internal package provide to be done anyway, so that any future package require Memchans will just succeed immediately on the grounds that the package is already in use.
[Background info]: As you can see, a package index file is actually very simple: it just provides some instructions to say that if you need a particular package of a particular version, here's a script to make it available. The only real nuance is that the $dir variable describes the location of the package index file while the file is being loaded.