어떤 함수가 실행되면 기본 작업공간과 별도로 그 함수만의 작업공간이 생성되어 함수 내부에서 사용되거나 생성된 객체가 저장되게 된다. 그리고 함수의 실행이 끝나면 그 작업공간은 소멸되므로 함수 내에서 초기화된 변수는 함수의 실행 끝나는 시점에서 소멸된다. 함수 내부에서 사용할 수 있는 외부 변수는 다음과 같은 세 가지 경로로 전달된다.
❶ 입력 변수
❷ global로 선언된 변수
❸ 함수 내부에서 초기화되지 않고 호출된 곳의 workspace에서 정의된 변수
여기서 ❶과 ❷는 MATLAB에서도 동일하지만 ❸의 경우는 그렇지 않다. 함수가 호출되면 호출된 곳의 작업공간과는 별도로 그 함수만의 분리된 작업공간이 생성된다. 편의상 호출된 곳의 작업공간을 기본 작업공간(base workspace, BWS)라고 칭하겠다. 만약 함수 내부에서 어떤 변수를 참조하려고 하면 먼저 자신의 작업공간을 먼저 검색해보고 만약 없다면 기본 작업공간에서 찾아본다. 두 곳 모두에서 없다면 에러가 발생될 것이다.
예를 들어서 다음과 같은 함수가 정의되었다고 가정하자.
function y=fA(x) w=(w+1)^2 // (a) y=x*w // (b) endfunction |
이렇게 정의한 후
이라고 호출하면 에러가 발생된다. 왜냐면 (a)의 우변에서 쓰이는 변수 w는 현재의 workspace에서도 없고 기본 작업 공간에서도 초기화되지 않았기 때문이다.
[그림 1] 작업 공간의 개념도
하지만
와 같이 변수 w를 먼저 초기화한다면 이제는 4라는 결과값이 표시될 것이다. 한 가지 정말로 혼동하기 쉬운 것은 (a)의 우변의 변수 w는 기본 작업 공간에서 참조하고 좌변의 w는 이 함수 자신의 작업 공간에 새로운 변수로 초기화된다는 것이다. 따라서 (b)의 변수 w는 이렇게 새롭게 생성된 변수가 참조된다. 기본 작업 공간의 변수 w가 아님에 주의해야 한다. 이 변수 w와 기본 작업 공간의 변수 w는 별개의 것이므로 기본 작업 공간에서는 여전히 1값을 유지한다. 이렇게 기본 작업 공간에서 이미 초기화되어 있는 변수를 함수 내부에서 다시 초기화한 경우 “shadowed” 되었다고 하며 이 경우 기본 작업 공간의 변수를 접근할 수는 없게 된다.
[그림 2] 함수의 작업공간과 기본 작업공간은 분리되어 있다.
만약 기본 작업 공간에서 변수 w를 global로 지정한 후 초기화했다면 어떤 일이 발생할까.
>> global w, w=1>> fA(1)>> disp(w) |
이 경우에도 변수 w는 여전히 1값을 유지하며 global로 지정했더라도 함수 내부에서 그 값을 변경할 수는 없다. 즉, 앞의 경우와 동일하게 동작한다는 것이다. 그렇다면 함수 내부에서 여전히 기본 작업공간의 변수를 접근할 수 있는데 global로 지정해주어야 하는 필요가 있을까하는 의문이 생긴다. 일견 아무런 차이점이 없어 보이기 때문이다. 함수 내부에서 상위 workspace의 변수값을 변경해주려면 함수의 내부에서도 global로 지정해 주어야 한다.
function y=fB(x) global w w=(w+1)^2 y=x*wendfunction |
이제
를 실행하면 변수 w는 4로 바뀐다. 즉, 상위 workspace의 변수 w가 fB()함수 내부에서 바뀐 것이다. 이와 같이 외부 변수의 값을 바꿀 필요가 있다면 외부에서뿐만 아니라 내부에서도 그 변수를 global로 지정해 주어야 한다.
[그림 3] 글로벌 변수의 동작 개념도
함수의 결과값을 기본 작업 공간으로 내보내는 데에도 다음과 같은 세 가지 방법이 있다.
❶ 출력 변수로 반환하는 방법
❷ global로 지정된 변수를 이용하는 방법
❸ resume 혹은 return 명령의 인수를 이용하는 방법
❶ 은 함수의 정의부에서 선언한 출력변수를 통해서 기본 작업 공간으로 값을 내보내는 것이고 ❷는 직전 절에서 기술한 바와 같이 함수의 내부에서 global로 지정한 변수를 통해서 기초 작업 공간에서 접근할 수 있는 전역 공간에 변수값을 내보내는 방법이다.
함수 내부에서 return 이나 resume을 만나면 그 즉시 함수가 종료되는데 보통은 단문으로 사용되어서 함수를 강제로 종료시키는 기능을 수행한다. 하지만 다음과 같은 문법도 가능하다.
[x1, x2, … xn] = return(a1, a2, … an)[x1, x2, … xn] = resume(a1, a2, … an) |
이러한 명령들은 함수 내부의 변수들 a1, a2, … , an 을 호출한 곳의 작업 공간에 변수 x1, x2, …, xn 으로 내보내는 기능을 수행한다. 예를 들면 다음과 같다.
function foo(a) a=a+1 b=resume(a) //(*) c=52 // (**)endfunction |
이 예제에서 (**)줄은 실행되지 않고 (*)줄에서 함수는 종료된다. 또한 기본 작업공간에 변수 b를 생성시켜서 함수 내부의 a변수 값을 넘겨주게 된다. 따라서
라고 함수를 실행시키면 workspace에 변수 b가 43값으로 생성된다.
그렇지만 Scilab 매뉴얼(도움말)에 의하면 이러한 용법은 쓸데없이 프로그램의 복잡도만 증가시키므로 출력 변수를 이용하는 것이 바람직하다고 기술되어 있다. 따라서 가급적 ❶번 방법을 주로 사용하고 필요시 ❷번 방밥을 사용하도록 하는 것이 좋다. 또한, resume명령은 pause명령에 의해서 실행이 멈춘 함수를 다시 시작시키는 데에도 사용되는 명령이다.