Get name of matlab file one step up in stack - matlab

I'm writing a matlab script where I'd like to know the name of the script which is one step up in the stack. The reason I need this is that I'm writing a helper script to be called to assert some basic facts about the workspace before engaging in heavier calculations, and the helper script should be able to give error messages when calling the calculation scripts.
I've tried using mfilename and dbstack, but I do not manage to get anything but the name of the helper script from them.
To explain further, I have the following scripts:
verify_base_conditions: the helper script, called on one of the first lines in
heavy_stuff_calculation and
sweet_mother_of_algorithms.
general_entry_point: a script where I gather common workflows in cells
I try to keep the entry point script as small as possible, and refactor heavier calculations (or anything that needs more than a few lines, really) into task-based, re-usable scripts. If I, from the entry point script, call sweet_mother_of_algorithms and the basic conditions for this script to run are not fulfilled, I want to see an error message like
Error: this_cool_var must be defined when running sweet_mother_of_algorithms
general_entry_point line 15
I tried using
error(['this_cool_var must be defined when running ' mdfilename])
and other similar constructs, but I couldn't make the error message say anything but verify_base_conditions.
How do I find the name of the script running one level up in the stack?
(Note: I'm not interested in finding the script running at the bottom of the stack - that will almost always be general_entry_point. I'm just interested in getting the name of the script that called verify_base_conditions.)

dbstack should work for this. I think this is an analogous set-up to yours:
a.m:
b;
b.m:
c;
c.m:
stack = dbstack;
for i=1:3
disp(stack(i));
end
When I run a;, this prints out the whole stack, including b (which I think it was you want - the second-top item on the call stack.
Alternatively, although this probably gives exactly the same result, you could throw and catch an error and look at its stack:
c.m:
try
error('What is on the call stack?');
catch e
for i=1:3
disp(e.stack(i));
end
end

Related

How do I make a dtrace probe only execute when a certain function is in the stack

OK, this is "fun." I'm trying to figure out a weird thread timeout in a program, and need to look at what is happening when pthread_cond_timedwait() returns on Solaris... But... Only when a certain wrapper function or functions are being called (call them foo_lock and foo_unlock)...
I don't think I can use this answer because the function I'm looking at is at least 2-3 hops up in the stack: dtrace execute action only when the function returns to a specific module
One of the weird behaviors is that I see the right parent in tracing entry, but not exit, when I use a return probe... This could be a buffering issue though. Have to dig...

Can a matlab function called within a script cause the script to break?

I am running a script which calls a function, and if a certain condition is met, inside the function, I want the whole thing just to terminate (and by that I do not mean I want to close matlab using exit). Is that possible? I know I can use return or break to return to the script, however I want the script to stop as well if this condition is met.
The only function I know of that does this is error. This throws an exception, and, if no exception handlers with try and catch are installed in the calling script, will terminate and return to command prompt. Which is what you want, as far as I understand. It prints an error message though. This could be suppressed if you guard all code in the top-level script with a try catch handler. However this will have to be specific to the one error and it makes debugging ("stop-on-error") much more difficult.
The thing is that the only use case I see for this behavior (termination of whole program on certain event) is when a non recoverable error occurs, and in that case printing an error message is indeed appropriate.
In case the script is successful termination of the whole program is not really the right way. All functions should return to give the upper layers of the code to perform some clean-up action, like saving the output data or so.

What's up with CHECK and INIT blocks?

I have a circular dependency problem with Perl modules: say package X uses Y and wants to hold a static reference to an Y instance, and package Y uses X and wants to hold a static reference to an X instance.
Simply saying our $x_instance = new X will give Can't locate object method "new" in the module that was not loaded first.
I figured something like
our $x_instance;
INIT { $x_instance = new X }
would make sense, so I read everything about the specially named blocks.
Well, this works in a simple test I made, but in my real application it systematically shows Too late to run INIT block. The same happens with CHECK blocks.
The only explanation I found was from Perl Monks and I'm afraid I couldn't make much sense of it.
Does someone have an explanation about how Perl goes about executing CHECK and INIT block that goes beyond what is in perlmod, and would help me understand why my blocks and sometimes executed and sometimes not?
By the way, I just want to understand this—I am not specifically asking a solution to my original circular dependency problem, as I have a workaround that I am reasonably happy about:
our $x_instance;
sub get_x_instance {
$x_instance //= new X;
return $x_instance;
}
INIT blocks are executed immediately before the run time phase is started in the order the compiler encountered them during the compilation phase.
If you use use require (or do) at run time to compile a Perl file that includes an INIT block then the block won't be executed.
It is rare that there is a real reason to use require in preference to use.
Despite your confidence, there must be a place where you are attempting to load a module at run time that contains an INIT block. I suggest you install and use Carp::Always so that the Too late to run INIT block message is accompanied by a stack backtrace that will help you find the erroneous call.

Where Does create_custom_level() Need to Be Declared (log4perl)?

I'm trying to create a custom message level 'alert' (between warn and error) in Perl, but consistently get the error message:
create_custom_level must be called before init or first get_logger() call at /usr/share/perl5/Log/Log4perl/Logger.pm line 705.
My declaration of the custom level looks like this:
use Log::Log4perl qw(get_logger);
use Log::Log4perl::Level;
Log::Log4perl::Logger::create_custom_level("ALERT", "ERROR");
As far as I can tell from the documentation putting this at the top of any file which intends to use the custom level should be enough. So I can't tell what I'm doing wrong. Looking in the file Logger.pm where the error is thrown from shows that logger is being initialized before the custom level is being declared. Does anyone know how this could be happening?
P.S. I assure you creating a custom level is the right choice here, even if it's frowned upon.
EDIT: Question Answered! The top answer was more a guide to debugging, so I wanted to copy my solution from the comment section so that future readers would be more likely to see it.
I found that there were two steps to fixing my problem:
I needed to put create_custom_level in a BEGIN { ... } statement so that it would run at compile time, since it was apparently being beaten by a logger initialization that was being called at compile time.
I realized that putting the same create_custom_level line in both the main script (.pl) and its modules (.pm) is redundant and caused part of my problems. Depending on the order in which you've put your statements that execute at compile time (like 'use' and 'BEGIN'), calling create_custom_level in multiple files could lead to the sequence: 'create custom level', 'initialize logger', 'create custom level', across multiple files. I didn't figure out where the logger was being initialized early, but I was able to circumvent that by just creating my custom level as early as possible (for other inexperienced coders, using the perl debugger can be key in understanding the order in which lines and files are executed). Best to put create_custom_level in the original script or the first module it uses.
Hope this helps someone else!
The code you provided doesn't produce an error.
Perhaps you have some other code later in your script that is evaluated at compile time -- a module loaded in a use statement or some code in a BEGIN { ... } block -- that initializes a Logger.
If it's not obvious where this might be happening, you can use the Perl debugger to find out where the Logger call could be coming from. First, put this line in your file right after the use Log::Log4perl; and use Log::Log4perl::Level; statements:
BEGIN { $DB::single=1 }
This statement will get the debugger to stop at this line during the compile time phase, and allow you to stop at breakpoints during the rest of the compile phase. Then fire up a debugger
$ perl -d the_script.pl
set breakpoints on the critical Log::Log4perl functions
DB<1> b Log::Log4perl::init
DB<2> b Log::Log4perl::get_logger
begin executing the code
DB<3> c
and when the code stops, get a stack trace
Log::Log4perl::get_logger(/usr/local/lib/perl5/site_perl/5.18.1/Log/Log4perl.pm:371):
371: my $category;
DB<4> T

Is it possible to print to console during evalc in Matlab?

I have a testing framework where each test is an M file (for instance, test_featureX.m) that makes assertions to an instance of a special (custom) AssertionCollection class. Users will run tests individually when developing their features and may want to print useful information to the console during the test that will help them debug their problems. I also have a routine testAll that runs all tests for the entire repository and prints results in a standardized way. During this latter usage, I don't want any extraneous information printed to the console, so the test executions are wrapped in evalc (evalc('test_featureX(ac);')) which hides any console writes test_featureX makes.
Now, I would like testAll to print to screen in real time every time an assertion is made. I want to do this by adding a callback function to the AssertionClass instance (ac) before passing it to test_featureX, and having that callback function print an update on each assertion that passes. The problem is that the callback function is executed from within the call stack that originates in the evalc command, so its output is routed to the evalc string rather than the console.
Is there any way to force output to the console, even during an evalc evaluation, so that my callback can print statuses to the console while testAll rejects most standard writing to the console?
I'm hoping a result might look like:
s = evalc('testFunction();')
function testFunction()
disp('line 1');
fprintf('line 2\n');
fprintf(TO_THE_CONSOLE, 'line 3\n');
end
...and the resulting output would be
line 3
s =
line 1
line 2
I do not think it is possible. evalc captures everything except errors. Your best bet would be to add a return argument to testFunction and display that if needed.