Smalltalk80LanguageImplementationKor:Chapter 17
- 제 17 장 프로그래밍 인터페이스
프로그래밍 인터페이스
본 장에서는 프로그래머가 시스템으로 새로운 클래스를 추가한 후 Smalltalk-80 프로그래밍 환경을 이용해 행위를 테스트하고 디버깅하는 방법을 보여준다. 또 프로그래머가 FinancialHistory 클래스를 시스템으로 추가하는 시나리오를 제시한다. FinancialHistory는 본 서적의 1부에서 클래스 예제로 사용한 바 있다. 그 프로토콜과 구현 설명은 본 저서의 앞 표지 안쪽에서 찾을 수 있다. 해당 시나리오 예제를 소개하는 이유는 Smalltalk-80 프로그래밍 인터페이스를 철저하게 연구하기 위해서가 아니다. 이는 뒷장에 설명된 여러 유형의 그래픽 지원에 대한 동기 부여가 되는 개요 역할을 한다.
사용자와 Smalltalk-80 프로그래밍 환경은 비트맵 디스플레이 화면, 키보드, 지시 장치를 통해 상호작용한다. 디스플레이는 사용자에게 정보의 그래픽 및 텍스트 뷰를 제시하는 데에 사용된다. 키보드는 시스템으로 텍스트 정보를 제시하는 데에 사용된다. 지시 장치는 디스플레이 화면에서 정보를 선택 시 사용된다. Smalltalk-80은 마우스라는 간접 지시 장치를 사용한다. 화면에 있는 커서는 마우스가 현재 가리키는 위치를 표시한다. 마우스에는 세 개의 버튼이 있으며 각기 다른 유형의 선택을 실행한다.
뷰(Views)
디스플레이 화면에는 "views"(뷰)라고 불리는 직사각형 영역을 하나 또는 그 이상 포함한다. 뷰는 회색 배경에 표시되고 겹쳐지기도 한다. 각 뷰는 상단 좌측 모서리에 제목을 표시한다. 그림 17.1은 Smalltalk 화면에 두 개의 뷰를 겹쳐 표시한다. 제목은 Workspace와 System Browser이다. 두 개의 뷰는 텍스트만 포함하며, 그 외의 경우 사진 아니면 텍스트와 그림을 한꺼번에 포함할 수 있다.
그림의 상단 뷰는 워크스페이스다. 여기에는 편집 또는 평가 가능한 텍스트가 포함되어 있다. 그림의 하단에 있는 뷰는 시스템 브라우저다. 이는 시스템 내 클래스 설명을 보고 편집하도록 해준다. 브라우저 하단 우측 부분에 있는 화살표는 커서다. 이것은 마우스의 현재 위치를 표시한다. 본 장에 설명된 각 그림의 하단 우측 모서리에는 작은 직사각형이 표시되어 있는데, 여기에는 세 개의 타원형이 나란히 포함되어 있다. 타원형은 세 개의 마우스 버튼을 나타낸다. 그 중 하나를 누르면 그에 해당하는 타원형이 채워진다. 버튼은 왼쪽, 중간, 오른쪽 버튼을 차례로 나타내는데 일부 마우스에서는 나란히 배열되어 있지 않을지도 모른다.
Smalltalk-80 디스플레이 화면에는 다양한 정보가 표시된다. 액션을 취하기 위해 사용자는 시각적 정보의 어떤 부분이 영향을 받아야 하는지 나타낸다. 특정 정보 조각으로 주의를 돌리는 일반적인 활동을 선택(selection)이라고 부른다. 시스템은 현재 선택을 나타내기 위해 시각적 피드백을 제공한다. 대부분은 화면에서 직사각형 영역을 보완하고 흑백을 백색으로, 백색을 흑색으로 변경하는 공통된 피드백 메커니즘을 가진다. 시스템의 사용을 시작하기 위해 하나의 뷰가 선택된다. 선택된 뷰는 그 제목만 보완함으로써 표시된다. 선택된 뷰가 완전히 표시되고, 나머지 다른 뷰의 겹치는 부분을 흐릿하게 만든다. 그림 17.1에서는 브라우저가 선택된 뷰에 해당한다.
다른 뷰와 겹치지 않은 직사각형 틀 부분으로 커서를 이동시켜 마우스 왼쪽 버튼을 누르면 다른 뷰를 선택할 수 있다. 그림 17.2에서는 워크스페이스가 선택되었다. 왼쪽 버튼을 누른 상태임을 주목한다. 이제 워크스페이스가 브라우저의 겹치는 부분을 흐릿하게 만든다.
텍스트 선택(Text Selections)
Smalltalk-80 텍스트 에디터는 텍스트를 선택하고 선택된 텍스트에 편집 동작을 수행하는 기능을 제공한다. 예를 들어, standard 문자의 시퀀스를 워크스페이스에서 my special로 대체하기 위해서는 기존 문자를 선택한 후 새 문자를 입력한다.
문자는 왼쪽 마우스 버튼을 이용해 선택한다. 커서는 선택내용의 한쪽 끝에 위치하고 마우스 버튼은 눌러져 있다 (그림 17.3).
텍스트 선택영역이 비어 있고 어떤 문자도 포함하지 않는다. 빈 선택영역의 위치는 캐럿기호("v"를 거꾸로 한 기호)로 표시된다. 그림 17.3에서 캐럿은 커서 때문에 부분적으로 흐릿하게 되어 있다. 마우스 버튼을 누른 채로 커서는 선택할 문자의 다른 끝으로 이동한다. 선택된 문자는 보완된(complemented) 직사각형에 표시된다 (그림 17.4).
마우스를 놓으면 선택영역이 완성된다 (그림 17.5). 키보드로 문자를 타이핑하면 선택된 문자를 대체한다. 새 문자를 타이핑하고 난 후 선택영역은 비어지고 새 문자의 끝에 위치한다 (그림 17.6).
메뉴 선택(Menu Selections)
사용자 인터페이스에서 또 다른 유형의 선택으로 메뉴 선택이 있다. 마우스의 중간 및 오른쪽 버튼을 이용해 두 메뉴 중 하나에서 각각 명령을 선택한다. 이 버튼 중 하나를 누르면 커서의 위치에 메뉴가 나타난다. 중간 버튼을 눌러서 생긴 메뉴는 선택된 뷰의 내용과 관련된 명령을 포함한다. 워크스페이스처럼 뷰가 편집 가능한 텍스트를 포함하면 이러한 명령은 텍스트 조작과 연관된다. 오른쪽 버튼을 눌러 얻은 메뉴는 선택된 뷰 자체와 연관된 명령을 포함한다. 중간 버튼 메뉴는 뷰마다 다를 수 있지만 오른쪽 버튼 메뉴는 항상 동일하다.
문자를 선택한 후 중간 버튼 메뉴에서 cut 명령을 호출하면 텍스트에서 문자를 삭제할 수 있다. 다음에 제시된 그림에서는 문자 special이 선택된 후 중간 버튼을 누른 모습이다. 뷰의 내용과 관련된 명령 메뉴가 나타났다. 버튼을 누른 상태에서 커서가 이동하여 메뉴 중 cut 명령을 선택한다 (그림 17.7). 누르고 있던 버튼을 놓으면 선택된 명령이 실행된다. 이번 예제에서는 선택된 텍스트가 제거된다 (그림 17.8).
텍스트 선택은 Smalltalk-80 표현식으로 취급하고 평가할 수 있다. 그러한 연산을 실행할 수 있는 명령은 중간 버튼 메뉴에서 두 개가 있는데, 바로 doIt과 printIt이다. doIt을 선택하면 선택된 표현식을 단순히 평가하고 결과 값을 파기한다. printIt을 선택하면 선택된 표현식을 평가하고 표현식 다음에 그 값을 출력한다. 가령, Time now 표현식을 입력 및 선택한 후 printIt을 실행하면 Time의 새로운 인스턴스를 출력할 것이다 (그림 17.9). 출력된 결과는 현재 텍스트 선택내용이 된다 (그림 17.10).
버튼 누름을 해제하기 전에 커서를 메뉴 밖으로 이동시키면 어떤 명령도 실행되지 않는다.
브라우저(Browsers)
브라우저는 Smalltalk-80 시스템에서 클래스의 뷰에 해당한다. 기존 클래스는 브라우저를 이용해 연구되고 변경된다. 새로운 클래스는 브라우저를 이용해 시스템으로 추가된다. 브라우저는 5개의 직사각형 하위뷰로 구성된다. 상단을 따라 리스트를 표시하는 4개의 하위뷰가 있다. 각 리스트에는 하나의 항목이 선택되어 있기도 하고 그렇지 않기도 하다. 각 리스트에서는 선택된 항목이 보완된다. 리스트의 내용은 뷰를 통해 편집이 불가하며 선택만 가능하다. 4개의 리스트 하위뷰 아래에는 일부 텍스트만 표시하는 하위뷰가 있다. 하위뷰는 워크스페이스와 비슷하여 텍스트의 편집을 허용한다. 4개의 리스트 내 선택영역은 아래 하위뷰에 어떤 텍스트를 표시할 것인지 결정한다. 4개 리스트에서 모두 선택영역이 만들어지고 나면 하단에 하위뷰가 Smalltalk-80 메서드를 표시한다. 메서드는 좌측 2개의 리스트에서 선택된 영역이 결정한 클래스에서 발견된다. 해당 클래스 내에 존재하는 메서드는 우측 2개의 리스트 내 선택영역으로 결정된다. 그림 17.11에 실린 브라우저는 center 메시지에 응답하기 위해 Rectangles가 사용하는 메서드를 표시한다.
시스템 내 클래스는 범주로 조직된다. 브라우저에서 가장 왼쪽의 리스트는 시스템 내 클래스의 범주를 보여준다. 범주를 선택하면 해당 범주 내에 클래스가 오른쪽의 다음 리스트에 표시된다. 예제에서는 Graphics-Primitives 범주가 선택되었다. 해당 범주 안에는 4개의 클래스가 있다. 그 중 하나를 선택하면 클래스의 메시지 범주가 오른쪽 다음 리스트에 표시된다.
Rectangle이 선택되었기 때문에 그 인스턴스 프로토콜에 있는 범주가 표시된다. 두 번째 리스트 하단에 2개의 직사각형 영역에 instance와 class라는 이름이 붙여져 있다. 항상 둘 중 하나가 선택되어 있을 것이다. class가 선택되면 오른쪽 리스트에 클래스 메시지의 범주가 표시되고, instance가 선택되면 인스턴스 메시지의 범주가 표시될 것이다. 메시지 범주가 선택되면 해당 범주 내 메시지의 선택자들이 가장 오른쪽 리스트에 표시된다. 메시지 선택자 중 하나를 선택하면 해당하는 메서드가 브라우저 하단에 있는 하위뷰에 표시된다. 표시되는 메서드는 편집 가능하며, 필요 시 오래된 버전은 편집된 버전으로 교체될 수 있다.
리스트 선택(List Selections)
리스트 선택은 리스트에서 항목 위에 커서를 위치시킨 후 왼쪽 마우스 버튼을 눌렀다가 해제하면 실행된다. 그림 17.2에서는 브라우저의 제일 오른쪽 리스트에 또 다른 항목이 선택되어 있다. 따라서 하단 텍스트 하위뷰에 또 다른 메서드가 제시된다.
이미 선택된 항목 위에 커서가 있을 때 왼쪽 버튼을 눌렀다 놓으면 그 항목의 선택이 해제된다 (그림 17.13).
메시지 범주가 선택되었지만 제일 오른쪽 리스트에서 선택된 메시지 선택자가 없다면 하단 하위뷰는 메서드의 다양한 구문적 부분들을 설명하는 텍스트를 포함한다. 이러한 텍스트는 시스템에 추가될 새로운 메서드로 대체할 수 있다. 선택된 범주로 새로운 메서드가 추가될 것이다.
클래스 범주가 선택되었지만 선택된 클래스가 없다면 하단 하위뷰는 클래스 정의의 다양한 부분을 설명하는 텍스트를 어느 정도 포함한다. 이러한 텍스트는 클래스로 전송되는 메시지 형태로 되어 있으며 (이번 사례의 경우 Object), 클래스의 새로운 서브클래스를 생성하도록 요청한다 (그림 17.14).
스크롤링(Scrolling)
뷰는 모든 정보를 표시할만큼 충분히 크지 않을지도 모른다. 가령, 브라우저가 표시하는 다수의 리스트는 너무 길어서 이용 가능한 공간에 완전히 표시되지 않을 수도 있다. 뷰는 “scroll bar”(스크롤 바)를 이용해 리스트의 다른 부분에 위치시킬 수 있다. 스크롤 바는 직사각형 모양의 영역으로, 커서를 포함하는 하위뷰의 왼쪽에 표시된다. 스크롤 바 안에 회색 상자는 총 리스트 중 어떤 부분이 뷰에 표시되는지를 나타낸다. 스크롤 바의 높이는 전체 리스트의 길이를 표현한다. 회색 상자가 차지하는 스크롤 바의 부분은 표시되는 리스트 부분을 나타낸다.
마우스를 스크롤 바 안으로 이동시키면 리스트의 또 다른 부분을 표시할 수 있다. 이것을 "scrolling"(스크롤링)이라고 부른다. 커서가 스크롤 바의 오른쪽 절반 부분에 있으면 상향을 가리키는 화살표 모양을 취한다. 왼쪽 마우스 버튼을 누르면 리스트 내 항목이 하위뷰에서 상향으로 이동하는 듯 보이고 새로운 항목이 하단에 표시된다. 커서가 스크롤 바 중간을 기준으로 왼쪽에 있으면 그 모양은 아래를 가리키는 화살표가 되고, 왼쪽 버튼을 누르면 리스트의 이전 부분이 표시된다. 예를 들어, 브라우저의 가장 왼쪽 리스트를 스크롤하면 리스트에서 이전 범주를 표시할 수 있다 (그림 17.15).
뷰가 작아서 모든 텍스트를 표시할 수 없다면 텍스트를 포함하는 뷰 또한 스크롤할 수 있다.
클래스 정의(Class Definitions)
클래스 범주를 선택하고 클래스 정의 부분들을 설명하는 텍스트를 설명하면 시스템에 새로운 클래스를 추가할 수 있다. FinancialHistory 예제를 New Projects라는 범주로 추가해보겠다.
하단 하위뷰에서 텍스트를 변경하는 동안에는 클래스 정의 또는 메서드를 올바로 표현하지 못할지도 모른다. 중간 버튼 메뉴에서 accept 명령을 이용하면 편집이 완료되었고 클래스 정의 또는 메서드가 시스템으로 추가되었음을 나타낼 수 있다 (그림 17.16과 17.17).
중간 버튼을 누를 때 나타나는 메뉴는 브라우저의 하위뷰마다 다르다. 범주 내 클래스를 표시하는 하위뷰에서는 메뉴가 definition이라는 항목을 포함한다. 이 명령을 사용하면 기존 클래스의 클래스 정의가 표시된다 (그림 17.18과 17.19).
이러한 클래스 정의는 표준 텍스트 편집 연산으로 수정할 수 있다. 텍스트를 변경하고 나면 중간 버튼 메뉴에서 다시 accept를 선택해야 한다. 가령, 인스턴스 변수의 이름을 클래스 정의에서 적절한 위치로 추가하면 인스턴스 변수를 모든 Rectangles로 추가할 수 있겠다.
중간 버튼 메뉴에서 클래스 리스트와 관련된 또 다른 항목은 categories다. 이것을 선택하면 메시지 범주화가 하단 하위뷰에 표시된다 (그림 17.20과 17.21).
새 클래스에는 As yet unclassified라는 하나의 빈 메시지 범주가 있다.
텍스트를 편집하고 accept를 선택하면 범주화를 변경할 수 있다 (그림 17.22와 17.23). 그림 17.23의 좌측에서 세 번째 하위뷰에 어떤 변화가 일어났는지 주목하라. 이제 세 개의 범주, transaction recording, inquiries, private이 있다.
새로운 클래스를 시스템으로 추가하고 나면 범주를 선택하고 메서드 템플릿을 편집하여 메서드를 추가 가능하다 (그림 17.24와 17.25).
그림 17.25의 제일 오른쪽 하위뷰에 일어난 변화를 주목하자. 새로운 메서드의 선택자가 (이전에 비었던) 리스트에 추가되고 현재 선택영역이 되었다.
검사하기(Testing)
5장에 표시된 메서드를 FinancialHistory로 추가하고 난 후 메시지를 전송하여 인스턴스를 생성하고 검사할 수 있다. 먼저 Smalltalk라는 이름으로 된 전역 변수의 사전에 at:put: 메시지를 전송하여 시스템으로 새로운 전역 변수가 추가될 것이다. at:put: 의 첫 번째 인자는 전역 변수의 이름이고, 두 번째 인자는 초기 값이다. 해당 전역 변수는 검사하는 인스턴스를 참조하는 데에 사용될 것이다 (그림 17.26).
워크스페이스에 표현식을 타이핑하고 doIt 또는 printIt 명령을 호출하여 평가하면 HouseholdFinances로 메시지가 전송된다 (그림 17.27). 한 번에 여러 개의 표현식을 선택하여 평가할 수 있다. 표현식은 마침표로 구분된다 (그림 17.28).
doIt 대신 printIt을 선택하면 다음 표현식과 같은 결과가 표시된다 (그림 17.29와 17.30).
인스펙터(Inspectors)
인스펙터는 객체의 인스턴스 변수에 대한 뷰다. 인스펙터는 표시할 인스턴스 뷰를 가진 객체로 inspect를 전송하여 생성된다 (그림 17.31).
inspect를 전송하고 나면 사용자는 인스펙터를 표시할 직사각형 영영을 지정하라는 요청을 받는다. 직사각형 영역의 상단 좌측 모서리를 명시해야 한다는 사실을 나타내기 위해 커서의 모양이 변경된다 (그림 17.32).
커서는 바람직한 위치로 이동하고 왼쪽 마우스 버튼은 누른 상태로 유지된다. 커서의 모양이 다시 변경되어 이제 직사각형 영역의 하단 우측 모서리가 명시되어야 함을 나타낸다. 왼쪽 마우스를 계속 누르고 있는 한 예상되는 새 직사각형 틀이 표시된다 (그림 17.33).
버튼을 놓으면 선택영역에 인스펙터가 표시된다 (그림 17.34).
인스펙터의 제목은 검사한 객체의 클래스 이름이 된다.
인스펙터에는 두 개의 하위뷰가 있다. 왼쪽 하위뷰는 self와 객체의 인스턴스 변수명을 포함하는 리스트를 표시한다. 리스트 요소 중 하나를 선택하면 해당하는 값이 오른쪽 하위뷰에 출력된다 (그림 17.35와 17.36). 오른쪽 하위뷰에 표시되는 텍스트는 선택된 객체로 printString을 전송한 결과로 얻을 수 있다. 리스트 제일 위에 self 요소를 선택하면 검사 중인 객체를 출력한다 (그림 17.37).
오류 보고(Error Reporting)
오류에 직면하면 오류가 발생한 프로세스가 보류되고 그 프로세스에 대한 뷰가 생성된다. 보류된 프로세스는 두 가지 방식으로 살펴볼 수 있는데, "notifiers"(알림기)와 "debuggers"(디버거)를 들 수 있겠다. 알림기는 오류가 발생할 당시 프로세스에 대한 간단한 설명을 제공한다. 디버거는 좀 더 상세한 뷰와 함께, 보류된 프로세스를 재개하기 전에 상태를 변경하는 기능을 제공한다.
오류 보고의 예로 FinancialHistory에서 새로운 메서드 몇 가지를 추가하고 디버깅해보겠다. 아래 메서드는 테스트 프로세스에서 "발견될" 몇 가지 오류를 포함한다. 이러한 새로운 메서드를 사용하는 이유는 FinancialHistory가 그 상태에 대한 요약 보고를 제공하도록 허용하기 위함이다.
report
| reportStream |
reportStream ← WriteStream on: (String new: 10).
reportStream cr.
reportStream nextPutAll: 'Expenses'.
reportStream cr.
self expenseReasons do:
[ :reason | reportStream tab.
reportStream nextPutAll: reason.
reportStream tab.
reportStream nextPutAll: (self totalSpentFor: reason).
reportStream cr].
reportStream nextPutAll: 'Incomes'.
reportStream cr.
self incomeSources do:
[ :source | reportStream tab.
reportStream nextPutAll: source.
reportStream tab.
reportStream nextPutAll: (self totalReceivedFrom: source).
reportStream cr].
↑reportStream contents
incomeSources
↑incomes keys
expenditureReasons
↑expenditures keys
새로운 범주가 추가되고 새 메서드가 입력 및 수용된다 (그림 17.38).
새로운 메서드를 추가하고 나면 워크스페이스에서 표현식을 평가함으로써 FinancialHistory의 인스턴스에게 보고를 요청할 수 있다 (그림 17.39). 보고를 출력하는 대신 화면에 알림기가 나타난다 (그림 17.40).
알림기(Notifiers)
알림기는 오류가 발생한 후 보류되는 프로세스에 대한 간단한 뷰다. 알림기의 제목은 오류의 특성을 나타낸다. 알림기는 객체에 error: 메시지를 전송하여 생성된다. 메시지의 인자는 알림기의 제목이 된다. 그림 17.40에 표시된 알림기는 expenseReasons 메시지가 그것을 이해하지 못하는 객체로 전송되었음을 나타낸다. 알림기에 보이는 리스트는 보류된 프로세스의 부분적 상태를 표시한다.
이러한 오류의 원인은 알림기의 제목에서 분명히 알 수 있다. FinancialHistory에 추가된 메시지는 expenseReasons가 아니라 expenditureReasons였다. 알림기와 오류가 있는 프로세스는 오른쪽 마우스 버튼을 클릭하면 생기는 메뉴에서 close 명령을 선택해 중단할 수 있다 (그림 17.41).
report에 잘못된 철자는 브라우저에서 수정할 수 있다 (그림 17.42와 17.43).
브라우저에 틀린 철자를 수정하고 나면 워크스페이스에서 원본 표현식을 다시 평가할 수 있다 (그림 17.44와 17.45).
이는 또 다른 알림기를 생성한다. 이 오류의 원인은 분명하지 않다. do: 메시를 이해하지 못하는 객체로 메시지가 전송되었다. 오류에 관해 더 알고 싶다면 중간 버튼 메뉴에서 debug 명령을 선택해 보류된 프로세스에 대한 상세한 뷰를 확인할 수 있다.
디버거(Debuggers)
디버거는 알림기보다 보류된 프로세스에 대해 더 세부적인 내용을 보여주는 뷰다. 알림기의 중간 버튼 메뉴에서 debug를 선택하면 알림기가 보여준 것과 동일한 프로세스를 보여주는 디버거가 생성된다 (그림 17.46). debug를 선택하고 나면 사용자는 디버거를 표시하는 직사각형 영역을 제공할 것을 요청 받는다. 직사각형은 새로운 인스펙터의 직사각형 틀이 표시되는 것과 동일한 방식으로 명시된다 (그림 17.47).
디버거에는 6개의 하위뷰가 있다. 젤 위의 하위뷰는 알림기를 통해 볼 수 있는 것과 동일한 리스트를 표시한다. 이러한 리스트는 오류가 발생한 프로세스의 부분적 히스토리를 제공한다. 각 항목은 전송되었으나 응답이 아직 완료되지 않은 메시지에 해당한다. 항목은 수신자의 클래스명과 메시지의 선택자를 포함하는데, 각각 ">>"로 구분되어 있다. 리스트에 표시되는 마지막 항목인 FinancialHistory>> report는 FinancialHistory의 인스턴스가 report 메시지를 수신하였음을 나타낸다. 해당 메시지는 표현식 HouseholdFinances report가 텍스트 선택영역일 때 중간 버튼 메뉴 명령인 printIt을 선택 시 전송되었다. 디버거의 상단 리스트 항목 중 하나를 선택하면 해당하는 메시지가 호출한 메서드가 바로 아래 하위뷰에 표시된다.
메서드가 표시되면 프로세스가 보류되기 전 마지막 메시지가 보완된다. 그림 17.48은 self expenditureReasons 표현식의 결과로 do: 메시지가 전송되었음을 보여준다. 리스트에서 다음 항목인 Set>>do: 는 do: 의 수신자가 Set의 인스턴스였음을 나타낸다. 호출된 메서드는 목록에서 Set>>do: 을 선택함으로서 확인할 수 있다.
그림 17.49는 이 메서드가 객체 1로 메시지를 전송하였음을 보여준다. 리스트의 다음 항목인 SmallInteger(Number)>> to:do: 은 수신자가 SmallInteger의 인스턴스였음을 표시한다. 메시지가 호출한 메서드가 수신자 클래스의 슈퍼클래스에서 발견되었다면 해당하는 슈퍼클래스의 이름은 수신자의 직접 클래스 다음에 괄호 안에 표시된다. 예제에서는 to:do: 에 대한 메서드가 Number 클래스에서 발견되었다.
리스트에서 제일 위에 위치한 항목인 SmallInteger(Object) >> doesNotUnderstand: 은 프로세스가 보류되기 전에 마지막으로 발생했던 일을 보여주는데, 바로 SmallInteger의 인스턴스가 doesNotUnderstand: 메시지를 수신한 일이다. 이 메시지는 SmallInteger 또는 그 슈퍼클래스 어디에서도 do: 메시지를 찾을 수 없자 시스템이 전송한 메시지다. doesNotUnderstand: 메시지는 메서드를 호출하여 프로세스를 보류시키고 그것을 표시하는 알림기를 생성하였다. 리스트 위에서 두 번째 항목인 WriteStream(Stream)>>nextPutAll: 은 Stream 클래스에서 nextPutAll: 에 대한 메서드로부터 잘못 이해된 do: 메시지가 전송되었음을 나타낸다. 표시된 메서드는 nextPutAll: 의 인자로서 제공된 aCollection 이란 객체로 do: 메시지가 전송되었음을 보여준다.
하단에 있는 디버거의 하위뷰 4개를 이용해 메서드에서 사용되는 변수의 값을 찾는다. 이들은 두 개의 인스펙터와 같은 기능을 한다. 가장 왼쪽의 하위뷰는 수신자(self)와 그 인스턴스 변수명의 리스트를 보여준다. 왼쪽에서 세 번째 하위뷰는 인자명과 임시 변수명을 표시한다. 이러한 리스트 중 하나에서 이름을 선택하면 연관된 변수의 값이 오른쪽 하위뷰에 표시된다. 그림 17.50에서는 do: 메시지의 수신자를 표시하기 위해 aCollection이 선택되었다.
이러한 오류는 Stream이 요소들의 컬렉션이 nextPutAll: 의 인자일 것으로 예상했는데 대신 700 이란 숫자를 얻었기 때문에 발생한 것으로 보인다. 최상위 리스트에서 다음 항목을 선택하면 인자가 어디서 비롯되었는지 보여준다. 인자는 표현식을 (self totalSpentFor: reason) 평가한 결과였다. 그림 17.51에서는 인스턴스 변수 expenditures와 인자 reason의 값을 표시하기 위해 하단 하위뷰에서 선택이 이루어졌다.
텍스트를 선택하여 브라우저에 표시된 메서드에서 평가를 실행하면 해당 컨텍스트에서 변수명이 해석된다. 따라서 nextPutAll: 에 대한 인자는 표현식을 (self totalSpentFor: reason) 재실행하고 결과를 출력하여 찾을 수 있다 (그림 17.52).
결과는 예상대로 700이다 (그림 17.53).
report 메서드는 reportStream 뒤에 700에 대한 문자 표현을 추가하기 위한 것이었으나 숫자 자체를 대신 추가하였다. 이러한 버그(bug)는 숫자로 printString 메시지를 전송하면 수정된다. 수정은 디버거에서 가능하다 (그림 17.54). 이제 표현식을 다시 평가할 수 있다. 이제 워크스페이스에 보고가 성공적으로 출력되었다 (그림 17.55).
이로써 Smalltalk-80 프로그래밍 인터페이스에 대한 개요는 끝이 났다. 앞으로 소개할 장에서 논하게 될 많은 그래픽 클래스의 특성은 바로 사용자와 이러한 유형의 상호작용을 지원하는 기능으로 인한 것이다.