Хорошая методика программирования состоит в том, чтобы убедиться, что вы оставляете окружение программы в чистом состоянии, которое не мешает никакому другому программному коду. Для примера, вы можете захотеть
Закройте все файлы, которые вы открыли для импорта или экспорта.
Восстановите MATLAB® путь.
Блокируйте или разблокируйте память, чтобы предотвратить или разрешить удаление функции MATLAB или файлов MEX.
Если рабочая папка изменена, установите ее значение по умолчанию.
Убедитесь, что глобальные и постоянные переменные находятся в правильном состоянии.
MATLAB обеспечивает onCleanup
функция для этой цели. Эта функция, при использовании в любой программе, устанавливает стандартную программу очистки для этой функции. Когда функция завершается, как обычно, так и в случае ошибки или Ctrl+C, MATLAB автоматически выполняет стандартную программу очистки.
Следующий оператор устанавливает стандартную программу очистки cleanupFun
для текущей выполняемой программы:
cleanupObj = onCleanup(@cleanupFun);
Когда ваша программа выходит, MATLAB находит любые образцы onCleanup
Класс и выполняет связанные указатели на функцию. Процесс генерации и активации очистки функции включает следующие шаги:
Написание одной или нескольких стандартных программ очистки для разрабатываемой программы. Предположим, что сейчас требуется только одна такая стандартная программа.
Создайте указатель на функцию для стандартной программы очистки.
В какой-то момент, обычно в начале вашего программного кода, вставьте вызов onCleanup
функция, передающая указатель на функцию.
Когда программа запускается, вызов на onCleanup
создает объект очистки, который содержит указатель на стандартную программу очистки, созданную на шаге 1.
Когда программа заканчивается, MATLAB неявно очищает все объекты, которые являются локальными переменными. Это вызывает метод деструктора для каждого локального объекта в вашей программе, включая объект очистки, созданный на шаге 4.
Метод деструктора для этого объекта вызывает эту стандартную программу, если она существует. Это выполняет задачи, необходимые для восстановления окружения программирования.
Можно объявить любое количество стандартных программ очистки для программного файла. Каждый вызов на onCleanup
устанавливает отдельную стандартную программу очистки для каждого возвращенного объекта очистки.
Если по какой-либо причине объект вернулся onCleanup
сохраняется за пределами жизни вашей программы, тогда стандартная программа очистки, связанная с этим объектом, не запускается, когда ваша функция прекращает работать. Вместо этого он будет запускаться каждый раз, когда объект будет уничтожен (например, путем очистки переменной объекта).
Ваша стандартная программа очистки никогда не должна полагаться на переменные, которые определены вне этой стандартной программы. Например, вложенная функция, показанная здесь слева, выполняется без ошибок, в то время как очень аналогичная функция справа терпит неудачу с ошибкой Undefined function or variable 'k'
. Это происходит из-за зависимости стандартной программы очистки от переменной k
который определяется вне вложенной стандартной программы очистки:
function testCleanup function testCleanup k = 3; k = 3; myFun obj = onCleanup(@myFun); function myFun function myFun fprintf('k is %d\n', k) fprintf('k is %d\n', k) end end end end
MATLAB закрывает файл с идентификатором fid
когда функция openFileSafely
завершает:
function openFileSafely(fileName) fid = fopen(fileName, 'r'); c = onCleanup(@()fclose(fid)); s = fread(fid); . . . end
Этот пример сохраняет текущую папку, functionThatMayError
возвращает ошибку или нет:
function changeFolderSafely(fileName) currentFolder = pwd; c = onCleanup(@()cd(currentFolder)); functionThatMayError; end % c executes cd(currentFolder) here.
Этот пример расширяет путь MATLAB, чтобы включить файлы в папки toolbox\images, а затем отображает рисунок из одной из этих папок. После отображения рисунка стандартная программа очистки restore_env
закрывает рисунок и восстанавливает путь в исходном состоянии.
function showImageOutsidePath(imageFile) fig1 = figure; imgpath = genpath([matlabroot '\toolbox\images']); % Define the cleanup routine. cleanupObj = onCleanup(@()restore_env(fig1, imgpath)); % Modify the path to gain access to the image file, % and display the image. addpath(imgpath); rgb = imread(imageFile); fprintf('\n Opening the figure %s\n', imageFile); image(rgb); pause(2); % This is the cleanup routine. function restore_env(fighandle, newpath) disp ' Closing the figure' close(fighandle); pause(2) disp ' Restoring the path' rmpath(newpath); end end
Запустите функцию как показано здесь. Можно проверить, что путь был восстановлен, сравнив длину пути до и после запуска функции:
origLen = length(path); showImageOutsidePath('greens.jpg') Opening the figure greens.jpg Closing the figure Restoring the path currLen = length(path); currLen == origLen ans = 1
В примере 3, показанном выше, стандартная программа очистки и данные, необходимые для ее вызова, содержатся в указателе анонимной функции:
@()restore_env(fig1, imgpath)
Детали этого указателя затем содержатся в объекте, возвращенном onCleanup
функция:
cleanupObj = onCleanup(@()restore_env(fig1, imgpath));
Получить доступ к этим данным можно используя task
свойство объекта очистки, как показано здесь. (Измените showImageOutsidePath
функция путем добавления следующего кода непосредственно перед строкой с комментариями, которая говорит "% This is the cleanup routine.
”)
disp ' Displaying information from the function handle:' task = cleanupObj.task; fun = functions(task) wsp = fun.workspace{2,1} fprintf('\n'); pause(2);
Запустите измененную функцию, чтобы увидеть выход functions
команда и содержимое одного из workspace
камеры:
showImageOutsidePath('greens.jpg') Opening the figure greens.jpg Displaying information from the function handle: fun = function: '@()restore_env(fig1,imgpath)' type: 'anonymous' file: 'c:\work\g6.m' workspace: {2x1 cell} wsp = imageFile: 'greens.jpg' fig1: 1 imgpath: [1x3957 char] cleanupObj: [1x1 onCleanup] rgb: [300x500x3 uint8] task: @()restore_env(fig1,imgpath) Closing the figure Restoring the path
Другой способ запуска стандартной программы очистки, когда функция неожиданно прекращает работать, - это использовать try, catch
оператор. Однако существуют ограничения на использование этого метода. Если пользователь заканчивает программу, вводя Ctrl+C, MATLAB немедленно выходит из try
блок, и стандартная программа очистки никогда не выполняется. Очистка стандартной программы также не запускается, когда вы обычно выходите из функции.
Следующая программа очищается, если происходит ошибка, но не в ответ на Ctrl+C:
function cleanupByCatch try pause(10); catch disp(' Collecting information about the error') disp(' Executing cleanup tasks') end
В отличие от try/catch
оператор, onCleanup
функция реагирует не только на нормальный выход из программы и любую ошибку, которая может быть выдана, но и на Ctrl+C. Этот следующий пример заменяет try/catch
с onCleanup
:
function cleanupByFunc obj = onCleanup(@()... disp(' Executing cleanup tasks')); pause(10);
onCleanup
не работает в скриптах, как в функциях. В функциях объект очистки хранится в рабочей области функции. Когда функция выходит, эта рабочая область очищается, таким образом, выполняя связанную с ней стандартную программу очистки. В скриптах объект очистки хранится в базовом рабочем пространстве (то есть рабочей области, используемом в интерактивной работе, выполненной в командной строке). Поскольку выход из скрипта не имеет эффекта в базовом рабочем пространстве, объект очистки не очищается, и стандартная программа, связанная с этим объектом, не выполняется. Чтобы использовать этот тип механизма очистки в скрипте, вам придется явным образом очистить объект из командной строки или другого скрипта, когда первый скрипт завершится.