6. 스코프 시스템: 변수와 함수의 유효 범위
프로그래밍 언어에서 변수나 함수가 어디서 선언되었고, 어디까지 유효한지를 결정하는 규칙을 **스코프(Scope)**라고 합니다. '달빛 약속' 역시 자신만의 스코프 시스템을 가지고 있으며, 이는 코드의 예측 가능성과 안정성을 보장하는 핵심적인 요소입니다. 이번 장에서는 '달빛 약속'의 스코프 시스템이 어떻게 동작하는지 자세히 알아보겠습니다.
Scope
클래스의 역할
'달빛 약속'에서 스코프는 /core/executer/scope.ts
에 정의된 Scope
클래스에 의해 관리됩니다. Scope
인스턴스는 코드 실행 중 변수와 함수를 저장하고, 검색하며, 수정하는 역할을 담당합니다.
각 Scope
인스턴스는 다음과 같은 주요 속성을 가집니다.
variables
: 현재 스코프에 선언된 변수들을 저장하는 객체입니다.functions
: 현재 스코프에 선언된 함수들을 저장하는 Map 객체입니다.parent
: 부모 스코프를 참조합니다. 이parent
속성을 통해 스코프 체인이 형성됩니다.codeFile
: 이 스코프가 속한CodeFile
인스턴스를 참조합니다.
스코프 체인과 렉시컬 스코핑
'달빛 약속'의 스코프 시스템은 **스코프 체인(Scope Chain)**을 통해 **렉시컬 스코핑(Lexical Scoping)**을 구현합니다. 렉시컬 스코핑이란, 변수나 함수의 유효 범위가 코드가 작성된 위치(정적 위치)에 의해 결정된다는 의미입니다.
변수나 함수를 찾을 때, Scope
는 다음과 같은 규칙을 따릅니다.
- 현재 스코프 탐색: 먼저 현재
Scope
인스턴스의variables
또는functions
에서 해당 이름의 변수/함수를 찾습니다. - 부모 스코프 탐색: 현재 스코프에 없다면,
parent
속성을 통해 부모 스코프로 이동하여 다시 탐색합니다. 이 과정은 최상위 스코프(전역 스코프)에 도달할 때까지 재귀적으로 반복됩니다. - 오류 발생: 최상위 스코프까지 탐색했는데도 변수/함수를 찾지 못하면,
NotDefinedIdentifierError
와 같은 오류를 발생시킵니다.
이러한 스코프 체인 덕분에, 함수가 정의된 시점의 환경(스코프)을 기억하고, 나중에 호출될 때 그 환경에 접근할 수 있게 됩니다. 이는 **클로저(Closure)**와 같은 고급 기능을 구현하는 기반이 됩니다.
변수 = 10
약속 함수() {
변수 = 20 # 외부 스코프의 '변수'에 접근
새변수 = 30 # 새로운 스코프에 '새변수' 생성
보여주기(변수)
}
함수()
보여주기(변수) # 20이 출력됨
# 보여주기(새변수) # 오류 발생: '새변수'는 함수 스코프 내에서만 유효
스코프의 생성과 소멸
'달빛 약속'에서 새로운 스코프는 주로 다음과 같은 상황에서 생성됩니다.
- 전역 스코프: 프로그램이 시작될 때 가장 먼저 생성되는 최상위 스코프입니다.
- 함수 호출: 함수가 호출될 때마다 해당 함수의 실행을 위한 새로운 스코프가 생성됩니다. 이 스코프는 호출된 함수의 매개변수와 지역 변수를 담습니다.
- 블록 스코프:
반복
(loop) 블록 내부에서도 새로운 스코프가 생성됩니다.
스코프 시스템을 이해하는 것은 '달빛 약속' 코드의 동작 방식을 깊이 있게 파악하고, 변수 유효 범위와 클로저 같은 복잡한 개념을 이해하는 데 필수적입니다. 이는 또한 버그를 줄이고, 더 견고한 코드를 작성하는 데 도움을 줍니다.