The new MException object for try catch expressions is very nice. Unfortunately I still have to support Matlab 6.5. Does anybody use a workaround, such that catch ME is still valid in the historic Matlab versions?

 채택된 답변

Walter Roberson
Walter Roberson 2012년 1월 14일

2 개 추천

If you have a mechanism for defining a function or not depending on the version, then you could try:
...
catch ME
ME_TOO = ME; %the copy is important
...
disp(ME_TOO.message); %for example
end
%only build this in if MException is not supported
function Exception = ME
persistent LastException
if nargout == 0
LastException = lasterror();
LastException.cause = {};
end
Exception = LastException;
So when ME appears on the 'catch' statement then the function recognizes it was called with no outputs and records the lasterror. When the function appears in the assignment, it sees the output exists and copies out the remembered exception.
Copying a normal MException object is not a problem. Copying with this replacement gives you a struct whose fields can be accessed (whereas you cannot directly access the fields of a structure returned by a function.)

댓글 수: 5

Jan
Jan 2012년 1월 14일
Thanks, Walter. I've stuck at a function, which tries to create a struct called ME using ASSIGNIN('caller'). But overwriting the function name by a dynamically created variable is not clean and cannot applied repeatedly in a function. The thoughts about ASSIGNIN let fall me into panic, obviously.
Yes, I have a function for initialization, which includes a folder specific to the Matlab version to the PATH.
Walter Roberson
Walter Roberson 2012년 1월 14일
For repeated application, "clear ME" . Doesn't hurt if ME is an MException object, since that's just a variable.
I wonder if MathWorks is going to ever provide defining local scope for variables?
Jan
Jan 2012년 1월 15일
When I understand it correctly, a timer callback can invalidate the persistently stored object, if it it called between "catch ME" and "ME_too = ME". Some time measurements let me assume, that timer callbacks get a chance to execute *after* each line, so perhaps it is more stable to move the function call and the copy to a single line:
catch ME, ME_TOO = ME;
Walter Roberson
Walter Roberson 2012년 1월 15일
Yes, that is a good point.
Jan
Jan 2012년 1월 15일
I've asked the support for a suggestion.
See: http://www.mathworks.com/matlabcentral/answers/21537-what-thread-do-timers-operate-in
and http://www.mathworks.com/matlabcentral/answers/22180-timers-and-thread-safety

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Jan
Jan 2012년 1월 28일

2 개 추천

According to an exhaustive answer from the technical support:
The following code does have a racing condition:
try
command;
catch ME_, ME = ME_; % RACING CONDITION in Matab 6.5
disp(ME.message);
end
% For Matlab < 7.4 only include this in the PATH:
function ME = ME_;
persistent LastException
if nargout == 0
LastException = lasterror();
LastException.cause = {};
end
Exception = LastException;
The following applies to Matlab < 7.4 only:
In the line "catch ME_, ME = ME_;" the pressing of Ctrl-C is checked after the semicolon only (according to my investigations), but timer callbacks can be started at the comma also. If the timer-callback catchs an error using the ME_ also, thet persistent variable is overwritten. A possible solution would be using a LIFO stack for the persistently stored exception object. The better solution is to upgrade from Matlab 6.5 - but this might have further consequences.
While under modern Matlab versions the bove code is safe, the workaround for Matlab 6.5 contains a very unlikely chance to get a wrong error message due to the racing condition.

댓글 수: 7

Walter Roberson
Walter Roberson 2012년 1월 28일
Thanks. Can timer callbacks be started at comma in >= 7.4 ?
Daniel Shub
Daniel Shub 2012년 1월 28일
When did timers start working asynchronously? I am pretty sure that at one point timers operated in the main thread and waited patiently for drawnow (or something else to flush the event queue). I first became aware of the asyncronus timer from slide 31 here: http://www.scottgorlin.com/wp-content/uploads/2008/01/day2.pdf
It seems to suggest the change was between 7.4 and 7.6.
Walter Roberson
Walter Roberson 2012년 1월 28일
Interesting slides.
Jan
Jan 2012년 1월 29일
It would be essential to have snychronous *and* asynchronus timers e.g. to get the necessary control over a complicated error handling. As long as we cannot create "critical sections" in Matlab (sections which cannot be interrupted from any callbacks), the lack of control means a serious source of "unexpected behaviour". Multi-threading is a hard enough, ir it is fully documented. So, please, TMW, publish the necessary instructions.
Daniel Shub
Daniel Shub 2012년 1월 29일
@Jan, can you confirm that the timers in 6.5 are asynchronus
Jan
Jan 2012년 1월 30일
편집: Jan 2019년 4월 13일
@Daniel: No, I will avoid to speculate. But I observe this:
I start a timer, which displays the current time every second in the fixedRate mode. Then I run this function:
function test
for i = 1:20
for k = 1:1e7
d = sin(k);
end
% Callback runs here
fprintf('%d\n', i);
end
Then the callback is executed in the marked position only in Matlab 6.5. Without FPRINTF the timer callback does not run inside the function test().
Daniel Shub
Daniel Shub 2012년 1월 30일
@Jan, Thank you for that. I keep learning new things about how badly behaved timer objects are.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Exception Handling에 대해 자세히 알아보기

질문:

Jan
2012년 1월 14일

편집:

Jan
2019년 4월 13일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by