I want to auto-modify a function once it has executed itself (context is remote execution in a virtual runtime environment that shares a code-block which simulate stack of functions (because this stack is shared I want to reset everything each time for next command call) see http://askblogautomation.com/developers-guide/) like this for example ( for full context see http://askblogautomation.com/install-wordpress/):
install-wordpress
set 'install-wordpress func[][do read http://askblogautomation.com/install-wordpress/]
I want to genericize the above lines with
execute 'install-wordpress
Where execute is as below
execute: func[lit-word-command [lit-word!]][
do get lit-word-command
block-command: []
append block-command [do read]
append block-command to-url rejoin [http://askblogautomation.com/ lit-word-command]
set lit-word-command func[] block-command
]
But when I tried it, it gives error:
** Script Error: execute expected lit-word-command argument of type:
lit-word
How to fix this ?
Either change the invoking line:
execute to-lit-word 'install-wordpress
Or change the function spec:
execute: func[lit-word-command [word!]][
But not both!
Related
In Tcl, when an uncaught error occurs in the background in the event loop, the function bgerror will be called if one exists (or any function registered via interp bgerror).
When an unknown command is encountered, the unknown command will be called.
Is there a similar mechanism for uncaught errors outside of the event loop that make their way to the top level? The default behavior from tclsh is just to print the error on stderr, but I would like a specific proc to be called instead without having to put the entire code in one big catch.
The default behaviour, if a Tcl error makes it's way to the top of the main execution path, is to print the errorInfo trace to standard error and, if running as a script, exit with a non-zero result code. If you want to override this, you need to either write your own entry code/main loop in C (when you can do anything you want when Tcl_Eval() returns TCL_ERROR), or wrap your code in a catch or try. You can use uplevel #0 within such Tcl code to ensure that the trapping code doesn't appear to be on the stack as seen by the rest of your code.
For example:
proc printStackOnError {script} {
try {
uplevel "#0" $script
} on error {msg opt} {
set stackinfo [dict get $opt -errorinfo]
# remove last three uninteresting lines; they're just part of this procedure's machinery
puts stderr [join [lrange [split $stackinfo "\n"] 0 end-3] "\n"]
}
}
Demonstrating (interactively, with Tcl 8.6):
% printStackOnError {eval {error foo}}
foo
while executing
"error foo"
("eval" body line 1)
invoked from within
"eval {error foo}"
You're advised to make sure you either print or log the errorInfo when an error is trapped at that level. Otherwise any bugs in your code are going to be unreasonably difficult to fix.
I am a newbie to NS3. I want to understand the execution status of handover in the Randomwalk2d module and visualize it. The default is two Ue and two enb, but errors will always occur during execution. Can anyone help me solve the problem?
This is my code link:https://drive.google.com/file/d/163NQOyvs0bTh2J4P9_vpS4Y7iqocB3HJ/view?usp=sharing
When I execute the command : ./waf --run scratch/lte_handover --visualize, the following error appear
../scratch/lte_handover.cc:In funtion 'int main(int, char**)':
../scratch/lte_handover.cc:296:78: error: expected ')' before ';' token
"Bounds",RectangleValue (Rectangle (0,2000,0,2000)));
^
Build failed
->task in 'lte_handover' failed with exit status 1 (run with -v to display more information)
Follow the instructions to enter the command :./waf --run scratch/lte_handover -v, and the following information appears
Several tasks use the same identifier. Please check the information on
https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid
object 'SuidBuild_task'(
{task 139759060979784: SuidBuild_task -> }) defined in 'tap-creator'
object 'SuidBuild_task'(
{task 139759060980008: SuidBuild_task -> }) defined in 'tap-creator'
object 'SuidBuild_task'(
{task 139759065638504: SuidBuild_task -> }) defined in 'tap-creator'
Seems that you have an extra ) in that line above. You are not closing this command as you commented all the lines
ueMobility.SetPositionAllocator ("ns3::RandomRectanglePositionAllocator", // <-- close
ueMobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel","Bounds", RectangleValue (Rectangle (0,2000,0,2000)));
the code I have in my .zshrc is:
ytdcd () { #youtube-dl that automatically puts stuff in a specific folder and returns to the former working directory after.
cd ~/youtube/new/ && {
youtube-dl "$#"
cd - > /dev/null
}
}
ytd() { #sofar, this function can only take one page. so, i can only send one youttube video code per line. will modify it to accept multiple lines..
for i in $*;
do
params=" $params https://youtu.be/$i"
done
ytdcd -f 18 $params
}
so, on the commandline (terminal), when i enter ytd DFreHo3UCD0, i would like to have the video at https://youtu.be/DFreHo3UCD0 to be downloaded. the problem is that when I enter the command in succession, the system just tries to download the video for the previous command and rightly claims the download is complete.
For example, entering:
> ytd DFreHo3UCD0
> ytd L3my9luehfU
would not attempt to download the video for L3my9luehfU but only the video for DFreHo3UCD0 twice.
First -- there's no point to returning to the old directory for ytdcd: You can change to a new directory only inside a subshell, and then exec youtube-dl to replace that subshell with the application process:
This has fewer things to go wrong: Aborting the function's execution can't leave things in the wrong directory, because the parent shell (the one you're interactively using) never changed directories in the first place.
ytdcd () {
(cd ~/youtube/new/ && exec youtube-dl "$#")
}
Second -- use an array when building argument lists, not a string.
If you use set -x to log its execution, you'll see that your original command runs something like:
ytdcd -f 18 'https://youtu.be/one https://youtu.be/two https://youtu.be/three'
See those quotes? That's because $params is a string, passed as a single argument, not an array. (In bash -- or another shell following POSIX rules -- an unquoted string expansion would be string-split and glob-expanded, but zsh doesn't follow POSIX rules).
The following builds up an array of separate arguments and passes them individually:
ytd() {
local -a params=( )
local i
for i; do
params+=( "https://youtu.be/$i" )
done
ytdcd -f 18 "${params[#]}"
}
Finally, it's come up that you don't actually intend to pass all the URLs to just one youtube-dl instance. To run a separate instance per URL, use:
ytd() {
local i retval=0
for i; do
ytdcd -f 18 "$i" || retval=$?
done
return "$retval"
}
Note here that we're capturing non-success exit status, so as not to hide an error in any ytdcd instance other than the last (which would otherwise occur).
I would declare param as local, so that you are not appending url after urls...
You can try to add this awesome function to your .zshrc:
funfun() {
local _fun1="$_fun1 fun1!"
_fun2="$_fun2 fun2!"
echo "1 says: $_fun1"
echo "2 says: $_fun2"
}
To observe the thing ;)
EDIT (Explanation):
When sourcing shell script, you add it to you current environment, that is why you can run those function you define. So, when those function use variables, by default, those variable will be global and accessible from anywhere in your environment! Therefore, In this case param is defined globally for all the length of your shell session. Since you want to allow the download of several video at once, you are appending values to this global variable, which will grow all the time.
Enforcing local tells zsh to limit the scope of params to the function only.
Another solution is to reset the variable when you call the function.
I'm attempting to use the TProcess unit to execute ssh to connect to one of my servers and provide me with the shell. It's a rewrite of one I had in Ruby as the execution time for Ruby is very slow. When I run my Process.Execute function, I am presented with the shell but it is immediately backgrounded. Running pgrep ssh reveals that it is running but I have no access to it whatsoever, using fg does not bring it back. The code is as follows for this segment:
if HasOption('c', 'connect') then begin
TempFile:= GetRecord(GetOptionValue('c', 'connect'));
AProcess:= TProcess.Create(nil);
AProcess.Executable:= '/usr/bin/ssh';
AProcess.Parameters.Add('-p');
AProcess.Parameters.Add(TempFile.Port);
AProcess.Parameters.Add('-ntt');
AProcess.Parameters.Add(TempFile.Username + '#' + TempFile.Address);
AProcess.Options:= [];
AProcess.ShowWindow:= swoShow;
AProcess.InheritHandles:= False;
AProcess.Execute;
AProcess.Free;
Terminate;
Exit;
end;
TempFile is a variable of type TProfile, which is a record containing information about the server. The cataloging system and retrieval works fine, but pulling up the shell does not.
...
AProcess.ShowWindow:= swoShow;
AProcess.InheritHandles:= False;
AProcess.Execute;
AProcess.Free;
...
You're starting the process but not waiting for it to exit. This is from the documentation on Execute:
Execute actually executes the program as specified in CommandLine, applying as much as of the specified options as supported on the current platform.
If the poWaitOnExit option is specified in Options, then the call will only return when the program has finished executing (or if an error occured). If this option is not given, the call returns immediatly[sic], but the WaitOnExit call can be used to wait for it to close, or the Running call can be used to check whether it is still running.
You should set the poWaitOnExit option in options before calling Execute, so that Execute will block until the process exits. Or else call AProcess.WaitOnExit to explicitly wait for the process to exit.
When I run ANY test I get the same message. Here is an example test:
package require tcltest
namespace import -force ::tcltest::*
test foo-1.1 {save 1 in variable name foo} {} {
set foo 1
} {1}
I get the following output:
WARNING: unknown option -run: should be one of -asidefromdir, -constraints, -debug, -errfile, -file, -limitconstraints, -load, -loadfile, -match, -notfile, -outfile, -preservecore, -relateddir, -singleproc, -skip, -testdir, -tmpdir, or -verbose
I've tried multiple tests and nothing seems to work. Does anyone know how to get this working?
Update #1:
The above error was my fault, it was due to it being run in my script. However if I run the following at a command line I got no output:
[root#server1 ~]$ tcl
tcl>package require tcltest
2.3.3
tcl>namespace import -force ::tcltest::*
tcl>test foo-1.1 {save 1 in variable name foo} {expr 1+1} {2}
tcl>echo [test foo-1.1 {save 1 in variable name foo} {expr 1+1} {2}]
tcl>
How do I get it to output pass or fail?
You don't get any output from the test command itself (as long as the test passes, as in the example: if it fails, the command prints a "contents of test case" / "actual result" / "expected result" summary; see also the remark on configuration below). The test statistics are saved internally: you can use the cleanupTests command to print the Total/Passed/Skipped/Failed numbers (that command also resets the counters and does some cleanup).
(When you run runAllTests, it runs test files in child processes, intercepting the output from each file's cleanupTests and adding them up to a grand total.)
The internal statistics collected during testing is available in AFACT undocumented namespace variables like ::tcltest::numTests. If you want to work with the statistics yourself, you can access them before calling cleanupTests, e.g.
parray ::tcltest::numTests
array set myTestData [array get ::tcltest::numTests]
set passed $::tcltest::numTests(Passed)
Look at the source for tcltest in your library to see what variables are available.
The amount of output from the test command is configurable, and you can get output even when the test passes if you add p / pass to the -verbose option. This option can also let you have less output on failure, etc.
You can also create a command called ::tcltest::ReportToMaster which, if it exists, will be called by cleanupTests with the pertinent data as arguments. Doing so seems to suppress both output of statistics and at least most resetting and cleanup. (I didn't go very far in investigating that method.) Be aware that messing about with this is more likely to create trouble than solve problems, but if you are writing your own testing software based on tcltest you might still want to look at it.
Oh, and please use the newer syntax for the test command. It's more verbose, but you'll thank yourself later on if you get started with it.
Obligatory-but-fairly-useless (in this case) documentation link: tcltest