Main Content

eval 함수의 대안

eval 함수 사용을 지양해야 하는 이유

eval 함수가 매우 강력하고 유연하기는 하지만, 항상 프로그래밍 문제 해결을 위한 최상의 솔루션은 아닙니다. eval을 호출하는 코드는 대개 다른 함수나 언어 구문을 사용하는 코드보다 효율성이 떨어지고, 읽고 디버그하기가 더 어렵습니다. 예를 들면 다음과 같습니다.

  • MATLAB®은 처음 실행할 때 코드를 컴파일하여 향후 실행 시 성능을 향상시킵니다. 그러나, eval 문의 코드는 런타임에 변경될 수 있으므로 컴파일되지 않습니다.

  • eval 문 내에 포함된 코드는 예기치 않게 변수를 생성하거나, 기존 데이터를 덮어써서 현재 작업 공간에 이미 있는 변수에 값을 대입할 수 있습니다.

  • eval 문 내에 있는 결합된 문자형 벡터는 읽기 어려울 때가 많습니다. 다른 언어 구문을 사용하여 코드의 구문을 단순화할 수 있습니다.

다음 예제에 나와 있는 것과 같이 대부분의 일반적인 eval 사용에 대해 권장되는 대체 접근 방법이 있습니다.

순차적 이름을 사용하는 변수

eval 함수는 A1, A2, ..., An과 같은 변수 세트를 생성하는 데 흔히 사용됩니다. 그러나 이러한 접근 방법은 MATLAB의 배열 처리 성능을 활용하지 않으므로 권장되지 않습니다. 권장되는 방법은 단일 배열에 관련 데이터를 저장하는 것입니다. 데이터 세트의 유형이나 크기가 서로 다른 경우에는 구조체나 셀형 배열을 사용하십시오.

예를 들어, 10개의 요소를 포함하는 셀형 배열을 생성하겠습니다. 여기서 각 요소는 숫자형 배열입니다.

numArrays = 10;
A = cell(numArrays,1);
for n = 1:numArrays
    A{n} = magic(n);
end

중괄호를 사용하여 인덱싱함으로써 셀형 배열의 데이터에 액세스합니다. 예를 들어, A의 다섯 번째 요소를 표시하겠습니다.

A{5}
ans =
    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9

대입문 A{n} = magic(n)eval 호출보다 훨씬 효율적입니다.

eval(['A', int2str(n),' = magic(n)'])     % Not recommended

자세한 내용은 다음을 참조하십시오.

순차적 이름을 사용하는 파일

관련 데이터 파일은 대개 myfile1.mat ~ myfileN.mat와 같이, 정수 인덱스가 붙은 공통된 루트 이름을 가집니다. eval 함수는 일반적으로 다음과 같은 명령 구문을 통해 각각의 파일 이름을 생성하여 함수에 전달하는 데 사용됩니다(권장되지 않음).

eval(['save myfile',int2str(n),'.mat'])     % Not recommended

모범 사례는 변수를 입력값으로 전달할 수 있는 함수 구문을 사용하는 것입니다. 예를 들면 다음과 같습니다.

currentFile = 'myfile1.mat';
save(currentFile)

eval을 사용하지 않고 sprintf 함수(대개 int2str보다 더 효율적임)를 사용하여 루프 내에서 파일 이름을 생성한 후 save 함수를 호출할 수 있습니다. 다음 코드는 현재 폴더에 10개 파일을 생성합니다.

numFiles = 10;
for n = 1:numFiles
   randomData = rand(n);
   currentFile = sprintf('myfile%d.mat',n);
   save(currentFile,'randomData')
end

자세한 내용은 다음을 참조하십시오.

변수 내의 함수 이름

eval은 일반적으로 함수 이름이 문자형 벡터 형식의 변수에 들어 있을 때 해당 함수를 실행하기 위해 사용됩니다. eval을 사용하는 것보다 더 효율적인 방법으로 변수에서 함수를 실행할 수 있는 두 가지 방법이 있습니다.

  • @ 기호나 str2func 함수를 사용하여 함수 핸들을 생성합니다. 예를 들어, 셀형 배열에 저장된 목록에서 함수를 실행합니다.

    examples = {@odedemo,@sunspots,@fitdemo};
    n = input('Select an example (1, 2, or 3): ');
    examples{n}()
  • feval 함수를 사용합니다. 예를 들어, 런타임에 지정하는 데이터를 사용하여 플롯 함수(예: plot, bar, pie)를 호출합니다.

    plotFunction = input('Specify a plotting function: ','s');
    data = input('Enter data to plot: ');
    feval(plotFunction,data)

변수 내의 필드 이름

필드에 대한 표현식을 괄호로 묶는 방식으로 변수 필드 이름을 사용하여 구조체의 데이터에 액세스합니다. 예를 들면 다음과 같습니다.

myData.height = [67, 72, 58];
myData.weight = [140, 205, 90];

fieldName = input('Select data (height or weight): ','s');
dataToUse = myData.(fieldName);

입력 프롬프트에서 weight를 입력하면 다음 명령을 사용하여 최소 weight 값을 구할 수 있습니다.

min(dataToUse)
ans =
    90

추가 예제는 변수에서 필드 이름 생성하기 항목을 참조하십시오.

오류 처리

MATLAB에서 오류를 처리하는 권장 방법은 try, catch 문을 사용하는 것입니다. 예를 들면 다음과 같습니다.

try
   B = A;
catch exception
   disp('A is undefined')
end

작업 공간에 변수 A가 포함되어 있지 않은 경우 이 코드는 다음을 반환합니다.

A is undefined

eval 함수에 대한 이전 버전의 문서에는 구문 eval(expression,catch_expr)이 포함됩니다. expression 입력값을 실행할 때 오류가 반환되는 경우 evalcatch_expr을 실행합니다. 그러나, 명시적인 try/catcheval 문의 묵시적인 catch보다 훨씬 더 명확합니다. 따라서 묵시적 catch를 사용하는 것은 권장되지 않습니다.