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
입력값을 실행할 때 오류가 반환되는 경우 eval
은 catch_expr
을 실행합니다. 그러나, 명시적인 try/catch
는 eval
문의 묵시적인 catch보다 훨씬 더 명확합니다. 따라서 묵시적 catch를 사용하는 것은 권장되지 않습니다.