I'd like to run several lines of code, but I'm unsure if any line will throw an error. If an error occurs however, I'd like the script to ignore that line and continue on.
One choice would be to have a try-catch-end block, that skips over a block of code that may throw errors. However, as soon as an error occurs, the rest of the code after the error in the try-statement is not executed.
TL;TR: Do I have another choice than writing a try-catch-end block for every individual line in the following example code?
Example code:
try
disp('1st line');
disp('2nd line');
PRODUCE_ERROR; %throws an error, variable/function does not exist
disp('3rd line'); %%%%%
disp('4th line'); % these lines I would like to keep executing
disp('5th line'); %%%%%
catch
disp('something unexpected happened');
end
Output:
1st line
2nd line
something unexpected happened
Output that would be preferred:
1st line
2nd line
something unexpected happened
3rd line
4th line
5th line
related: Why should I not wrap every block in "try"-"catch"?
One option is to put each section of code in a function and iterate over a cell array of the function handles. Here's an example with a list of anonymous functions:
fcnList = {#() disp('1'); ...
#() disp('2'); ...
#() error(); ... % Third function throws an error
#() disp('4')};
for fcnIndex = 1:numel(fcnList)
try
fcnList{fcnIndex}(); % Evaluate each function
catch
fprintf('Error with function %d.\n', fcnIndex); % Display when an error happens
end
end
And here's the output this generates, showing that functions are still evaluated even after one throws an error:
1
2
Error with function 3.
4
The above example works for the case when you have individual lines of code you want to evaluate sequentially, but you can't fit multiple lines into an anonymous function. In this case, I would go with nested functions if they have to access variables in the larger workspace or local functions if they can operate independently. Here's an example with nested functions:
function fcn1
b = a+1; % Increments a
fprintf('%d\n', b);
end
function fcn2
error(); % Errors
end
function fcn3
b = a.^2; % Squares a
fprintf('%d\n', b);
end
a = 2;
fcnList = {#fcn1 #fcn2 #fcn3};
for fcnIndex = 1:numel(fcnList)
try
fcnList{fcnIndex}();
catch
fprintf('Error with function %d.\n', fcnIndex);
end
end
And the output:
3
Error with function 2.
4
A simpler approach involves reading the script file line by line and evaluating each line in turn. This assumes that the script you want to run does not include any multi-line statements (such as e.g. a for with the end on a different line, or a statement broken onto multiple lines using ...). This is a strong limitation, as it is common to e.g. initialize a matrix using multiple lines of text.
This is the function:
function execute_script(fname)
fid = fopen(fname,'rt');
n = 0;
while ~feof(fid)
cmd = fgetl(fid);
n = n+1;
if ~isempty(cmd)
try
evalin('caller',cmd);
catch exception
disp(['Error occurred executing line number ',num2str(n),': ',exception.message]);
end
end
end
It does exactly as I described above: it reads in a line, then uses evalin to evaluate that line in the caller's workspace. Any variable created is created in the caller's workspace. Any variable used is taken from the caller's workspace.
For example, I create the file testscript.m with the following contents:
A = 1;
B = 2+C; % This line needs a variable not defined in the script!
D = 5;
Next, at the MATLAB command prompt:
>> execute_script('testscript.m')
Error occurred executing line number 2: Undefined function or variable 'C'.
>> whos
Name Size Bytes Class Attributes
A 1x1 8 double
D 1x1 8 double
The variable A and D were created. If I define C:
>> C=0;
>> execute_script('testscript.m')
>> whos
Name Size Bytes Class Attributes
A 1x1 8 double
B 1x1 8 double
C 1x1 8 double
D 1x1 8 double
With a variable C defined, the script runs without error, and defines B also.
Related
In a Matlab script I call a user-defined function (m-function). My function returns a value while printing the value to the command window using disp and/or fprintf calls.
When writing an expression or a statement, one puts ; at its end to suppress printing. When the expression calls my function, the ; can suppress the printing of the returned value. However, this does not effect the disp output from within the function called.
I want to eliminate the display output of the function when appropriate. Is there a way to determine whether a function call was made in an expression ending with ;?
I like the spirit of what you're trying to do, but I think that it probably goes against the common programming patterns in Matlab. As you correctly state, the purpose of the terminating semicolon is to supress printing of returned values. Trying to get it to incorporate your other feature might well require some deep hacking and ugly hard-to-maintain code. The standard way to implement what you describe is via property name-value pair arguments. For example, Matlab's optimization suite has a property called 'Display' that can be set to various values to indicate the desired level of verbosity (see optimset).
If you want to try looking for a way to check for terminating semicolons, you might look into the undocumented mint, mlintmex, and mtree functions – read more here. Unfortunately, using mlint to simply check for the "Terminate statement with semicolon to suppress output" warning (see this function on the MatlabCental File Exchange) won't work in all cases as a function call by itself doesn't produce this warning.
Update
Here's an attempt at code that could be inserted into a called function to determine if the line of the caller is terminated by a semicolon. You should be aware that this has not been thoroughly tested and is likely very fragile. I have not tested it with sub-functions or anonymous functions and I know that it fails if you wrap a line over multiple lines using ....
st = dbstack('-completenames'); % M-file of caller and line number
caller = st(2);
str = mlint('-lex',caller.file); % Struct containing parsed data
isSemicolon = false; % Assume no semicolon
for i = 1:length(str)
% Find end-of-line corresponding to function call
c = strsplit(str(i).message,'/');
if str2double(c{1}) == caller.line && strcmp(c{2}(end-5:end-1),'<EOL>')
% Check for comments
j = i-1;
if ~isempty(strfind(str(j).message,'%'))
j = j-1;
end
% Check for semicolon
if strcmp(str(j).message(end-2),';')
isSemicolon = true; % Semicolon found
break;
end
end
end
In other words, play around with this to learn, but I would not recommend actually using it.
I'm afraid that the answer to your question is no. That information is simply not passed on to the function being called.
You shouldn't think about adding the semicolon as a means to "suppress printing", but rather that the lack of a semicolon instructs MATLAB to call the display function on the output variables of the function call. In other words, MATLAB interprets this code:
y = myFunc(x)
as:
y = myFunc(x);
display(y);
I think adding a 'print' or 'verbose' parameter to your function is your best bet for achieving what you want.
I think the simplest method to achieve the results you want (i.e. whether or not disp's get displayed) is to add an extra function input or output. For example, adding an input (optional, you can set default behaviour):
function y=myFunc(a,displayResults)
if nargin==1
displayResults=true; %// set the default behaviour
end
%// if you want to print something
if displayResults
disp(a)
end
end
Or an extra output. In this case foo produces no output to the screen, but all the messages are saved into a cell array, which can be accessed if desired:
function [x,m] = foo(a)
m={}; %// initialise cell array of output messages
x=a;
m{length(m)+1}=a; %// some message
m{length(m)+1}='another message'; %// another message
end
I think the first option will be better, the second will not deal with fprintf well, and displaying elements of m could be tricky depending on what it contains. The first method is very simple, and does not even require you to change existing code, as you can make the displayResults input optional and set the default to be what you want.
You may suppress disp outputs by locally redefining it at the beginning of the function:
function [] = hideDisplay()
%[
% Override `disp` behavior
disp = #(x)doNothing;
% Next `disp` calls will no longer appear in matlab console
disp('Hello')
disp('World!')
%]
end
%% ---
function [] = doNothing()
%[
%]
end
Here's a possible workaround (to be clear - this is not a real answer to the question per-se, just a way to avoid the unwanted behaviour). Say my function is:
function y = prt_test(x)
y = x + 1;
disp('IN PRT_TEST')
end
Calling:
>> % Regular use - message and output are displayed:
>> y = prt_test(1)
IN PRT_TEST
y =
2
>> % Regular use w/ ";" - only message is displayed:
>> y = prt_test(2);
IN PRT_TEST
>> % Use "evalc()" - message and output are displayed:
>> evalc('y = prt_test(3)')
ans =
IN PRT_TEST
y =
4
>> % Use "evalc()" w/ func ";" - only message is displayed:
>> evalc('y = prt_test(4);')
ans =
IN PRT_TEST
>> % Use "evalc();" - no output:
>> evalc('y = prt_test(5)');
>> % Use "evalc();" w/ func ";" - no output:
>> evalc('y = prt_test(6);');
>>
I'd like to run several lines of code, but I'm unsure if any line will throw an error. If an error occurs however, I'd like the script to ignore that line and continue on.
One choice would be to have a try-catch-end block, that skips over a block of code that may throw errors. However, as soon as an error occurs, the rest of the code after the error in the try-statement is not executed.
TL;TR: Do I have another choice than writing a try-catch-end block for every individual line in the following example code?
Example code:
try
disp('1st line');
disp('2nd line');
PRODUCE_ERROR; %throws an error, variable/function does not exist
disp('3rd line'); %%%%%
disp('4th line'); % these lines I would like to keep executing
disp('5th line'); %%%%%
catch
disp('something unexpected happened');
end
Output:
1st line
2nd line
something unexpected happened
Output that would be preferred:
1st line
2nd line
something unexpected happened
3rd line
4th line
5th line
related: Why should I not wrap every block in "try"-"catch"?
One option is to put each section of code in a function and iterate over a cell array of the function handles. Here's an example with a list of anonymous functions:
fcnList = {#() disp('1'); ...
#() disp('2'); ...
#() error(); ... % Third function throws an error
#() disp('4')};
for fcnIndex = 1:numel(fcnList)
try
fcnList{fcnIndex}(); % Evaluate each function
catch
fprintf('Error with function %d.\n', fcnIndex); % Display when an error happens
end
end
And here's the output this generates, showing that functions are still evaluated even after one throws an error:
1
2
Error with function 3.
4
The above example works for the case when you have individual lines of code you want to evaluate sequentially, but you can't fit multiple lines into an anonymous function. In this case, I would go with nested functions if they have to access variables in the larger workspace or local functions if they can operate independently. Here's an example with nested functions:
function fcn1
b = a+1; % Increments a
fprintf('%d\n', b);
end
function fcn2
error(); % Errors
end
function fcn3
b = a.^2; % Squares a
fprintf('%d\n', b);
end
a = 2;
fcnList = {#fcn1 #fcn2 #fcn3};
for fcnIndex = 1:numel(fcnList)
try
fcnList{fcnIndex}();
catch
fprintf('Error with function %d.\n', fcnIndex);
end
end
And the output:
3
Error with function 2.
4
A simpler approach involves reading the script file line by line and evaluating each line in turn. This assumes that the script you want to run does not include any multi-line statements (such as e.g. a for with the end on a different line, or a statement broken onto multiple lines using ...). This is a strong limitation, as it is common to e.g. initialize a matrix using multiple lines of text.
This is the function:
function execute_script(fname)
fid = fopen(fname,'rt');
n = 0;
while ~feof(fid)
cmd = fgetl(fid);
n = n+1;
if ~isempty(cmd)
try
evalin('caller',cmd);
catch exception
disp(['Error occurred executing line number ',num2str(n),': ',exception.message]);
end
end
end
It does exactly as I described above: it reads in a line, then uses evalin to evaluate that line in the caller's workspace. Any variable created is created in the caller's workspace. Any variable used is taken from the caller's workspace.
For example, I create the file testscript.m with the following contents:
A = 1;
B = 2+C; % This line needs a variable not defined in the script!
D = 5;
Next, at the MATLAB command prompt:
>> execute_script('testscript.m')
Error occurred executing line number 2: Undefined function or variable 'C'.
>> whos
Name Size Bytes Class Attributes
A 1x1 8 double
D 1x1 8 double
The variable A and D were created. If I define C:
>> C=0;
>> execute_script('testscript.m')
>> whos
Name Size Bytes Class Attributes
A 1x1 8 double
B 1x1 8 double
C 1x1 8 double
D 1x1 8 double
With a variable C defined, the script runs without error, and defines B also.
I have created a function to execute the thomas algorithm. I'm trying to use my function to solve a system with the following arrays:
b = -4ε + 2αh^2
a = 2ε - h(1+α(n+1)h)
c = 2ε + h(1+αnh)
g = 4kπh^2sin(kπnh)
where α=1.2, k=2, ε=0.02, R=4
I've inserted my function (below), but I'm not completely sure how to enter in these parameters in the command window as I'm pretty new to Matlab. Any help would be much appreciated.
function y = ThomasAlgorithm(a,b,c,f)
% obtain values
m = length(f);
f(1) = f(1)/b(1);
% Forward Substitution
for j = 1:m-1
c(j) = c(j)/b(j);
b(j+1) = b(j+1) - a(j)*c(j);
f(j+1) = (f(j+1) - a(j)*f(j))/b(j+1);
end;
% Backwards Substitution
for k = m-1:-1:1
f(k) = f(k) - c(k)*f(k+1);
end;
% Output
y = f;
end
I tried to put this into the command window (below) but I got the error:
Error in ThomasAlgorithm (line 11)
b(j+1) = b(j+1) - a(j)*c(j);
I'm not really sure where I'm going wrong at the moment or how to solve it and I've kind of hit a wall.
>> m=10;
x0=0, xm=1;
y0=R, ym=0;
alpha=1.2;
k=2;
eps=0.02;
R=4;
h=xm-x0/m;
a=[2*eps-h*(1+alpha*((1:m-1)+1)*h)];
b=[-4*eps+2*alpha*h*h];
c=[2*eps+h*(1+(alpha*(1:m-1)*h))];
f=[4*k*pi*h*h*sin(k*pi*(1:m-1)*h)];
x=ThomasAlgorithm(a,b,c,f);
for ic=1:n
disp(x);
end
Put all of the stuff you've put in the command window into a separate script (.m file) instead, then run it. This allows you to get the actual full error message, and keeps the command window clutter free!
When running the script with your code in, you see the following error:
Undefined function or variable 'R'.
Error in myScript (line 3)
y0=R, ym=0;
Now your (first) problem is clear! You set y0=R when R doesn't exist.
It's good practise at times like this to run clear before you run your script, so your workspace is emptied and you know what you've not defined in the script.
So we add R = 1 or something to the start, then run it again. Now we have an indexing error!
Index exceeds matrix dimensions.
Error in ThomasAlgorithm (line 8)
b(j+1) = b(j+1) - a(j)*c(j);
This is because you defined b as
b=[-4*eps+2*alpha*h*h]; % a SCALAR not a vector!
Then passed it to ThomasAlgorithm and expected to be able to index it, when it isn't a vector.
Hopefully that points out the immediate problem, and how to better diagnose issues. Also when your code is in a script you can step through it to debug things.
To debug my Octave/MATLAB code, I want to be able to do something like:
A = magic(3);
b = 42;
describe(#A, #b);
and get output like:
filename.m line 3: "A" is a 3x3 matrix
filename.m line 3: "b" is a scalar of value: 42
For multiple variables, how can I print the:
Calling function's file and line
Name
Type
Dimensions
Overview
In this answer I list 3 subtly different versions of the function describe.
Takes any number of variables and creates an output string and displays it using fpritnf
Takes any number of variables and creates an output cell array and displays it using disp
Takes any number of variable names and creates an output string as in 1. This has the advantage of being able to deal with indexing like describe('myvar{1}').
Main functionality description and version 1.
You can use various standard functions to get the info you want:
varargin to accept variable number of input variables
dbstack to get the file name / current line
inputname to get the names of inputs as they are passed into describe
fprintf to display with new line characters
varargout to optionally return or display the result
So create your describe function like so:
function varargout = describe(varargin)
% varargin used to accomodate variable number of inputs
% By default, at least get functions stack (even if no variables are passed in)
st = dbstack;
% Convert cell output to string (excluding describe.m itself)
outstring = '';
% Loop backwards for more logical order (most recent last)
for ii = size(st, 1):-1:2
% new line character at end only works with fprintf, not disp
outstring = [outstring, st(ii).file, ' > ', st(ii).name, ...
', line ', num2str(st(ii).line), '\n'];
end
% Loop over variables and get info
for n = 1:nargin
% Use inputname to get name of input variables
outstring = [outstring, '"', inputname(n), '" is a ', ...
class(varargin{n}), ' of size ', mat2str(size(varargin{n})), '\n'];
end
% If output variable is requested then assign to output variable
% If not, just display output string to command window
if nargout
varargout{1} = outstring;
else
fprintf(outstring)
end
end
The only tweaking required here really is formatting, all of your requested functionality is here and hopefully enough flexibility is built in to handle your needs.
Example output:
% In myMainFunction.m, in the subfunction mySubFunction
% Could store output using 'd = describe(A,B);' and use 'fprintf' later
describe(A, B);
% In the command window
myMainFunction.m > myMainFunction, line 3
myMainFunction.m > mySubFunction, line 39
"A" is a double of size [1 3]
"B" is a double of size [1 5 9 7]
Tested in Matlab R2015b, all functions listed above existed since before R2006a according to documentation so I assume it's likely that they have Octave equivalents.
Version 2.
Cell instead of string with line separators.
This has a less pretty output but is also perhaps a less clunky method, assigning the strings to a cell array rather than having to rely on fprintf for new lines. It can be done easily using the following (uncommented for brevity) version.
function varargout = describe(varargin)
st = dbstack; outcell = {};
for ii = size(st, 1):-1:2
outcell{end+1} = [st(ii).file, ' > ', st(ii).name, ', line ', num2str(st(ii).line)];
end
for n = 1:nargin
outcell{end+1} = ['"', inputname(n), '" is a ', class(varargin{n}), ' of size [', size(varargin{n}), ']'];
end
outcell = outcell.'; % Transpose to make it a column cell array
disp(outcell)
end
Version 3.
Passing variable names as strings, so things like 'myvar(1)' are displayed.
This uses evalin to evaluate the variables in the caller workspace (where describe was called from). NOTE: This could be more memory intensive as you are recreating the variables in this describe function to get their attributes.
function varargout = describe(varargin)
% varargin used to accomodate variable number of input names
st = dbstack;
outstring = '';
for ii = size(st, 1):-1:2
outstring = [outstring, st(ii).file, ' > ', st(ii).name, ', line ', num2str(st(ii).line), '\n'];
end
% Loop over variables and get info
for n = 1:nargin
% Variables are passed by name, so check if they exist
try v = evalin('caller', varargin{n});
outstring = [outstring, '"', varargin{n}, '" is a ', class(v), ' of size ', mat2str(size(v)), '\n'];
catch
outstring = [outstring, 'Variable "', varargin{n}, '" not found!\n'];
end
end
fprintf(outstring)
end
Example use:
% This can be used with indexed variables too. MUST PASS STRINGS!
describe('C{1}', 'B(1:2, :)')
% In the command window
myMainFunction.m > myMainFunction, line 3
myMainFunction.m > mySubFunction, line 39
"C{1}" is a double of size [1 3]
"B(1:2, :)" is a double of size [2 5]
% Because you're passing strings, you can use command syntax if you want
% Gives same result but don't have to pass strings
% as that's how inputs are interpreted anyway for command syntax.
describe C{1} B(1:2, :)
I use something similar myself. Here's mine:
function describe(A)
fprintf(' Class : %s\n',class(A));
fprintf(' Num. Elems : %s\n',num2str(numel(A)));
fprintf(' Size : %s\n',num2str(size(A)));
fprintf(' Total Min : %s\n',num2str(min (A(:))));
fprintf(' Total Max : %s\n',num2str(max (A(:))));
fprintf(' Total Sum : %s\n',num2str(sum (A(:))));
fprintf(' Total Mean : %s\n',num2str(mean(A(:))));
fprintf('Total St.Dev : %s\n',num2str(std (A(:), 1)));
fprintf(' Unique vals : %s\n',num2str(length(unique(A))));
end
Edit: I'm aware this isn't a literal answer to what you ask, but I use this all the time and thought it might be useful to share. :)
PS. Having said that, it has never occurred to me that I might ever want to use such a function in a non-interactive way: if I need to inspect variables in this manner, I just put a breakpoint (or keyboard instruction) in the code and then inspect stuff in the terminal at the point where it's most relevant, so reporting a filename and a linenumber manually has never occurred to me! What is your use-case that you need to perform non-interactive debugging like this? If it's for post-mortem "testing" purposes, you really should be writing proper tests and sanity checks instead anyway!
Also, this is only for single variables, but I find that preferable; it's an extremely simple one-liner loop if you wanted more anyway.
You can use size to have the size of your variable, for the type use class and for the name use inputname.
For example:
function describe(a)
s = size(a); % Return the size of a
t = class(a); % Return the type of a
name = inputname(1); % Return the name of a
printf(['filename.m line 3: ''''' name ''''' size:' s(1) 'x' s(2) ' and type: ' t]);
end
I don't know how to use the name of file and the line, and if you want another way to display this you can can use if condition to seperate scalar from vector from matrix.
In a Matlab script I call a user-defined function (m-function). My function returns a value while printing the value to the command window using disp and/or fprintf calls.
When writing an expression or a statement, one puts ; at its end to suppress printing. When the expression calls my function, the ; can suppress the printing of the returned value. However, this does not effect the disp output from within the function called.
I want to eliminate the display output of the function when appropriate. Is there a way to determine whether a function call was made in an expression ending with ;?
I like the spirit of what you're trying to do, but I think that it probably goes against the common programming patterns in Matlab. As you correctly state, the purpose of the terminating semicolon is to supress printing of returned values. Trying to get it to incorporate your other feature might well require some deep hacking and ugly hard-to-maintain code. The standard way to implement what you describe is via property name-value pair arguments. For example, Matlab's optimization suite has a property called 'Display' that can be set to various values to indicate the desired level of verbosity (see optimset).
If you want to try looking for a way to check for terminating semicolons, you might look into the undocumented mint, mlintmex, and mtree functions – read more here. Unfortunately, using mlint to simply check for the "Terminate statement with semicolon to suppress output" warning (see this function on the MatlabCental File Exchange) won't work in all cases as a function call by itself doesn't produce this warning.
Update
Here's an attempt at code that could be inserted into a called function to determine if the line of the caller is terminated by a semicolon. You should be aware that this has not been thoroughly tested and is likely very fragile. I have not tested it with sub-functions or anonymous functions and I know that it fails if you wrap a line over multiple lines using ....
st = dbstack('-completenames'); % M-file of caller and line number
caller = st(2);
str = mlint('-lex',caller.file); % Struct containing parsed data
isSemicolon = false; % Assume no semicolon
for i = 1:length(str)
% Find end-of-line corresponding to function call
c = strsplit(str(i).message,'/');
if str2double(c{1}) == caller.line && strcmp(c{2}(end-5:end-1),'<EOL>')
% Check for comments
j = i-1;
if ~isempty(strfind(str(j).message,'%'))
j = j-1;
end
% Check for semicolon
if strcmp(str(j).message(end-2),';')
isSemicolon = true; % Semicolon found
break;
end
end
end
In other words, play around with this to learn, but I would not recommend actually using it.
I'm afraid that the answer to your question is no. That information is simply not passed on to the function being called.
You shouldn't think about adding the semicolon as a means to "suppress printing", but rather that the lack of a semicolon instructs MATLAB to call the display function on the output variables of the function call. In other words, MATLAB interprets this code:
y = myFunc(x)
as:
y = myFunc(x);
display(y);
I think adding a 'print' or 'verbose' parameter to your function is your best bet for achieving what you want.
I think the simplest method to achieve the results you want (i.e. whether or not disp's get displayed) is to add an extra function input or output. For example, adding an input (optional, you can set default behaviour):
function y=myFunc(a,displayResults)
if nargin==1
displayResults=true; %// set the default behaviour
end
%// if you want to print something
if displayResults
disp(a)
end
end
Or an extra output. In this case foo produces no output to the screen, but all the messages are saved into a cell array, which can be accessed if desired:
function [x,m] = foo(a)
m={}; %// initialise cell array of output messages
x=a;
m{length(m)+1}=a; %// some message
m{length(m)+1}='another message'; %// another message
end
I think the first option will be better, the second will not deal with fprintf well, and displaying elements of m could be tricky depending on what it contains. The first method is very simple, and does not even require you to change existing code, as you can make the displayResults input optional and set the default to be what you want.
You may suppress disp outputs by locally redefining it at the beginning of the function:
function [] = hideDisplay()
%[
% Override `disp` behavior
disp = #(x)doNothing;
% Next `disp` calls will no longer appear in matlab console
disp('Hello')
disp('World!')
%]
end
%% ---
function [] = doNothing()
%[
%]
end
Here's a possible workaround (to be clear - this is not a real answer to the question per-se, just a way to avoid the unwanted behaviour). Say my function is:
function y = prt_test(x)
y = x + 1;
disp('IN PRT_TEST')
end
Calling:
>> % Regular use - message and output are displayed:
>> y = prt_test(1)
IN PRT_TEST
y =
2
>> % Regular use w/ ";" - only message is displayed:
>> y = prt_test(2);
IN PRT_TEST
>> % Use "evalc()" - message and output are displayed:
>> evalc('y = prt_test(3)')
ans =
IN PRT_TEST
y =
4
>> % Use "evalc()" w/ func ";" - only message is displayed:
>> evalc('y = prt_test(4);')
ans =
IN PRT_TEST
>> % Use "evalc();" - no output:
>> evalc('y = prt_test(5)');
>> % Use "evalc();" w/ func ";" - no output:
>> evalc('y = prt_test(6);');
>>