Main Content

함수 완료 시 정리하기

개요

프로그래밍할 때는 다른 프로그램 코드에 방해가 되지 않도록 프로그램 환경을 정리하여 깔끔한 상태로 유지하는 것이 좋습니다. 예를 들어, 다음과 같이 할 수 있습니다.

  • 가져오기나 내보내기를 위해 열어 둔 파일을 모두 닫습니다.

  • MATLAB® 경로를 복원합니다.

  • 메모리를 잠그거나 잠금 해제하여 MATLAB 함수 또는 MEX 파일 삭제를 방지하거나 허용합니다.

  • 작업 폴더를 변경한 경우 다시 디폴트로 설정합니다.

  • 전역 변수와 영속 변수가 올바른 상태인지 확인합니다.

MATLAB은 이런 용도로 사용할 수 있는 onCleanup 함수를 제공합니다. 프로그램 내에서 이 함수를 사용하면 해당 함수에 대한 정리 루틴을 설정합니다. 함수가 종료되면, 정상적으로 종료되었든, 오류가 발생하여 종료되었든 또는 Ctrl+C에 의해 종료되었든 관계없이, MATLAB은 자동으로 정리 루틴을 실행합니다.

다음 명령문은 현재 실행 중인 프로그램에 대해 정리 루틴 cleanupFun을 설정합니다.

cleanupObj = onCleanup(@cleanupFun);

프로그램이 종료되면 MATLAB은 onCleanup 클래스의 모든 인스턴스를 찾은 다음, 관련 함수 핸들을 실행합니다. 함수 정리를 생성하고 활성화하는 절차는 다음의 단계를 거칩니다.

  1. 개발 중인 프로그램에 대해 하나 이상의 정리 루틴을 작성합니다. 지금 우선은 단 하나의 루틴으로 정리를 한다고 가정하겠습니다.

  2. 정리 루틴에 대한 함수 핸들을 만듭니다.

  3. 어떤 시점에 (일반적으로 프로그램 코드의 초반에) onCleanup 함수에 대한 호출을 삽입하여 함수 핸들을 전달합니다.

  4. 프로그램이 실행되면, onCleanup이 호출되어 1단계에서 만든 정리 루틴에 대한 핸들을 포함하는 정리 객체가 생성됩니다.

  5. 프로그램이 종료되면 MATLAB은 지역 변수인 객체 전체를 묵시적으로 지웁니다. 이때 4단계에서 생성된 정리 객체를 포함한, 프로그램의 각 로컬 객체에 대한 소멸자(Destructor) 메서드를 불러오게 됩니다.

  6. 이 정리 객체의 소멸자 메서드는 이 정리 루틴(있는 경우)을 불러옵니다. 그러면 프로그래밍 환경을 초기화하는 데 필요한 작업이 수행됩니다.

하나의 프로그램 파일에 대해 원하는 개수만큼의 정리 루틴을 선언할 수 있습니다. onCleanup이 호출될 때마다 반환된 각 정리 객체에 대한 별도의 정리 루틴이 설정됩니다.

어떤 이유로 인해, onCleanup에서 반환된 객체가 프로그램 종료 후에도 지속되는 경우, 함수가 종료되면 이 객체와 관련된 정리 루틴이 실행되지 않습니다. 대신, 이 정리 루틴은 (예를 들어 객체 변수를 지우는 등의 방법으로)객체가 소멸될 때마다 실행됩니다.

정리 루틴은 해당 루틴 외부에 정의된 변수에 종속되어서는 안 됩니다. 예를 들어, 여기에서 왼쪽에 표시된 중첩 함수는 오류 없이 실행되는 반면, 오른쪽의 이와 매우 비슷한 함수는 'k'은(는) 정의되지 않은 함수 또는 변수입니다(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

프로그램 종료 시 정리의 예제

예제 1 — 종료 시 열려 있는 파일 닫기

함수 openFileSafely가 종료되면 MATLAB은 식별자가 fid인 파일을 닫습니다.

function openFileSafely(fileName)
fid = fopen(fileName, 'r');
c = onCleanup(@()fclose(fid));

s = fread(fid);
     .
     .
     .
end

예제 2 — 선택한 폴더 유지하기

이 예제에서는 functionThatMayError가 오류를 반환하는지 여부에 관계없이, 현재 폴더를 유지합니다.

function changeFolderSafely(fileName)
   currentFolder = pwd;
   c = onCleanup(@()cd(currentFolder));

   functionThatMayError;
   end   % c executes cd(currentFolder) here.

예제 3 — Figure를 닫고 MATLAB 경로 복원하기

이 예제에서는 toolbox\images 폴더에 있는 파일을 포함하도록 MATLAB 경로를 확장한 다음, 이러한 폴더 중 하나에 속해있는 Figure를 표시합니다. Figure가 표시된 후에 정리 루틴 restore_env는 Figure를 닫고 경로를 원래 상태로 복원합니다.

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 속성을 사용하여 이 세부 정보에 액세스할 수 있습니다. (“% This is the cleanup routine.”이라는 주석 라인 바로 앞에 다음 코드를 추가하여 showImageOutsidePath 함수를 수정하십시오.)

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

onCleanup과 try/catch 사용 방법 비교

함수가 예기치 않게 종료될 때 정리 루틴을 실행할 수 있는 또 다른 방법은 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/catchonCleanup으로 대체한 것입니다.

function cleanupByFunc
obj = onCleanup(@()...
    disp('   Executing cleanup tasks'));
pause(10);

스크립트 내에서의 onCleanup

스크립트에서는 onCleanup이 함수에서처럼 동작하지 않습니다. 함수에서 정리 객체는 함수 작업 공간에 저장됩니다. 함수가 종료되면 이 작업 공간이 지워지므로 관련된 정리 루틴이 실행됩니다. 스크립트에서 정리 객체는 기본 작업 공간(즉, 명령 프롬프트에서 수행되는 대화형 방식의 작업에 사용되는 작업 공간)에 저장됩니다. 스크립트를 종료해도 기본 작업 공간에 아무런 영향을 미치지 않으므로, 정리 객체가 지워지지 않고 이 객체와 관련된 루틴도 실행되지 않습니다. 스크립트에서 이 유형의 정리 메커니즘을 사용하려면, 첫 번째 스크립트가 종료될 때 명령줄이나 다른 스크립트에서 정리 객체를 명시적으로 지워야 합니다.