| 목차 | 레슨6 | 레슨8 |
|
|
여태까지 Workspace에서 기존의 Smalltalk 객체나 메서드를 사용해 실행해왔습니다. 하지만 진정한 의미에서 코드를 이용가치가 있게끔 만들고, Smalltalk 개발환경의 장점을 음미하기 위해서는 자신의 객체나 메서드를 작성할 필요가 있습니다.
|
|
이 레슨에서는 자신의 패키지, 클래스, 프로토콜, 메서드를 작성하기 위한 시스템 브라우저의 사용법을 설명하겠습니다. 이 레슨에서 작성한, 디렉토리 지정된 로그파일에서 웹Hit를 표시하는 코드는 앞서 레슨에서 기술한 작업과 같습니다. 하지만 이번 코드는 보다 효율적으로 재이용 가능한 코드입니다.
|
|
코드를 Workspace에서 System Browser(자신의 클래스나 메서드를 작성하는 곳)으로 이행시키기 위해서는, 몇 가지 기술이 필요합니다. 코드를 적절히 실행시키기 위해 필요한 기술입니다. 이 레슨에서는 그 기술에 대해 설명하겠습니다.
|
|
1. VisualWorks 런쳐화면에 있는 툴바에서 네 번째 버튼을 클릭, 혹은 브라우저>>시스템 메뉴를 선택합니다.
System Browser라는 타이틀 화면이 표시됩니다. 아직 이 화면을 모르실 것이라 생각합니다만, Smalltalk 개발환경 가운데 자유롭게 사용할 수 있는 매우 강력할 도구 중 한 가지입니다. 닮지 않았을지도 모르겠습니다만, System Browser는 IDE(Integrated Development Environment : 통합개발환경)이라 불리우며, 기타 다른 개발언어의 환경과 동등한 기능을 가집니다. 이것은 Smalltalk 개발자의 메인 툴로 사용됩니다. 매우 강력하고 다양한 기능을 지닌 툴이기에 전부 설명할 수 없으므로 다음 스텝으로 진행합시다. 만약 System Browser에 대해 자세히 알고싶은 분은 System Browser 입문서를 참고해주십시오.
|
|
입문서 : 시스템 브라우저
간단하게, System Browser화면구성에 대해 설명하겠습니다.
그림 7-3. System Browser 화면 구성-순서대로 패키지(핸들), 클래스, 프로토콜, 메서드, 메서드코드영역
패키지나 프로토콜은 클래스나 메서드의 시스템을 구축(합치는)하는 구조입니다. 클래스가 어느 패키지에 속해있는지, 메서드가 어느 프로토콜에 속해있는지 익히기 위해서는 시간이 필요하니, 여기서 그런 걱정은 하지 맙시다. 이미 코딩할 준비는 되어있습니다만, 그 전에 또 한 가지 이해해야 할 구조가 있습니다. 그것은 네임스페이스(Namespace)입니다.
|
|
네임스페이스란?
네임스페이스는 어려운 개념이기에 예를 들어 설명하겠습니다. 이곳에 빌딩이 있다고 가정하십시오.(이 빌딩에는 사람들이 요구하는 모든 것이 있습니다. 즉, Smalltalk 메서드의 라이브러리인 Smalltalk 이미지를 표현하고 있습니다.) 이 빌딩엔 사람이 들어갈 수 있습니다. 하지만 같은 이름을 가진 사람은 한 명밖에 못들어갑니다. 예를 들어, "타로 씨"가 빌딩에 들어갈 수 있도록 허가를 받았습니다. 하지만 또 다른 "타로 씨"는 들어갈 수 없습니다. 두 번째 "타로 씨"가 빌딩에 들어가면 문제가 발생합니다. 왜냐하면 "하나코 씨"가 빌딩에 들어와서 말했습니다. "타로 씨! 점심 먹으러 가요." 그녀는 어떤 "타로 씨"를 말한 것일까요?
여기서 해결책을 제시하겠습니다. 이 빌딩에는 필요한 만큼 방을 만들 수가 있습니다. 지금, 하나코 씨는 다음과 같이 타로 씨에게 권유할 수 있습니다. "101호실에 계신 타로씨. 점심 먹으러 가요." 이로써 충돌을 피할 수 있게 됩니다.
그러면 실제로 Smalltalk에 이미지(클래스 라이브러리)에서는 어떻게 구성 될까요. 기존(제공된) 클래스나 새로운 클래스를 전부 지니고 있는 것이 아닌, 같은 빌딩(방 한 개)에 거실을 만들고, 분할된 방(네임스페이스)에 분리합니다. 자신의 클래스를 생성할 때, 방(네임스페이스)를 분할해서 작성 하는 것을 강력히 권장합니다. 그 이유는 간단합니다. 클래스에 독자적인 이름이 붙기 때문에, 다른 프로그램이 전혀 다른 동작을 할지도 모르는 클래스와 같은 이름을 사용하고 있을 가능성이 있습니다. 이것을 충돌이라 부릅니다. 때문에 옛날에는 충돌을 피하기 위해 "접두어" 네이밍 규약을 사용했습니다. 이러면 재이용에 지장을 초래하기 때문에 네임스페이스가 발명되었습니다.
그렇기에, 클래스를 작성하기 전에, 작성한 클래스가 속한 네임스페이스를 맨 처음 작성할 필요가 있습니다. 이 튜토리얼에서는 범위 밖이므로 네임스페이스는 작성하지 않습니다. 기존의 네임스페이스에 클래스를 추사합니다. 그것을 사용하는 네임스페이스는 Smalltalk입니다.
|
|
2. System Browser를 닫았을 경우엔 열어주십시오. 우선 작성한 클래스나 메서드를 포함하게될 패키지를 작성합니다. 패키지 창에서 적당한 패키지 이름을 클릭합니다. 카테고리 일람의 적당한 카테고리를 클릭해주십시오. 그리고 <오퍼레이트 클릭>후 신규 패키지...를 선택해주십시오.
그림 7-4. System Browser와 패키지 작성 메뉴
3. 표시된 패키지명 작성 다이얼로그에 WebLogStats를 입력합니다. 그리고 OK 버튼을 클릭합니다.
4. 작성이 완료되면 자동적으로 WeWLogStats 카테고리가 선택됩니다. 선택되지 않은 경우에는 선택해주십시오. System Browser가 아래 그림과 같이 표시된 것을 확인해주십시오.
그림 7-6. System Browser와 WebLogStats 패키지
5. 다음은 클래스를 작성하겠습니다. 메서드 코드 에리어를 수정해서 클래스를 작성할 수 있습니다만, 여기서는 새롭게 추가된 클래스 작성 툴을 사용하겠습니다. 우선, WebLogStats 패키지가 선택된 것을 확인합니다. 그리고, 클래스 창에서 <오퍼레이트 클릭>후 신규 클래스...를 선택합니다.
그림 7-7. System Browser와 신규 클래스 템플레이트
6. 클래스 작성 도구가 표시됩니다. 클래스명, 인스턴스 변수를 기술합니다. 아래쪽 체크박스는 체크된 상태로 둡니다.
7. OK를 클릭해주십시오.
OK를 선택한 경우, 타이핑 미스가 없으면 입력한 값이나 설정(클래스 작성 코드)가 "컴파일"되어 WebLogClass가 WebLogStats 패키지 일람에 표시됩니다. 아래 그림과 같이 표시됩니다.
그림 7-9. 새로운 패키지(WebLogStats)와 새로운 클래스 WebLogClass
클래스명과 패키지명을 살짝 다른 이름으로 한 것은 구분하기 쉽게 하기 위함입니다. WebLogClass를 클래스로 인식할 필요는 없습니다.(WebLog를 사용하면 일부러 클래스라는 것을 확인할 필요가 없습니다.)
instanceVariableNames 행을 주목해주십시오. 클래스 작성 툴에서 지정한 인스턴스 변수가 있습니다. 변수에 값을 설정하면 객체가 존속되는 동안은 값이 영구히 유지됩니다.
8. WebLogClass(클래스)를 클릭후 반전시키고, 프로토콜 창 위에 있는 클래스 탭을 클릭해주십시오.
9. 그리고 프로토콜 창에서 instance creation을 선택 후 메서드 창에서 new를 선택합니다.
아래 그림처럼 된 것을 확인해주십시오. 앞서 툴에서 initializer가 체크되어 있었기 때문에, 인스턴스 생성 메서드가 자동적으로 작성되었습니다.
|
|
"^super new initiaize"는 무슨 의미인가요? 입문서 : super
|
|
10. 프로토콜 창 위에 있는 instance 탭을 클릭해주십시오.
클래스 정의 텍스트가 표시됩니다.
11. 프로토콜 창에서 initialize-release를 선택하고, 메서드 창에서 initialize를 선택합니다.
아래 그림과 같이 된 것을 확인해주십시오. 이 메서드도 앞서 툴에서 initializer가 체크되어 있었기 때문에, 인스턴스 초기화 메서드가 자동적으로 작성되었습니다.
그림 7-11. 자동 생성된 initialize 메서드
12. 메서드 코드 뷰의 텍스트를 다음과 같이 바꿔주십시오.
initialize
"initialize the WebLogClass. Set the logDirectory variable."
logDirectory := 'c:\vw7.7\image'.
Initialize 메서드는 initialize-relrease에 속해있는 인스턴스 초기화용 공통 메서드 중 하나입니다. 때문에, 로그파일이 존재하는 디렉토리를 인스턴스 변수 값으로 설정하는 딱 좋은 메서드입니다.(이 코드는 다른 곳에서는 올바르게 동작하지 않습니다.)
13. 사용환경에 따라서 c:\vw7.7\image 문자열을 실제 로그파일이 격납되어있는 디렉토리로 변경할 필요가 있을 수 있습니다. 코드 뷰에서 <오퍼레이트 클릭>후 Accept를 선택해주십시오. 타이핑 미스가 없다면 입력한 코드가 "컴파일"되서 initialize 메서드가 메서드 창에 표시됩니다.
아래 그림에서 디렉토리 문자열을 제외한 나머지 부분이 같은지 확인해주십시오.
그림 7-12. 브라우서에 표시된 메서드(initialize)
14. 프로토콜 창 위에 있는 Instance 탭이 다시 선택되어 있는 것을 확인해주십시오. 그리고 프로토콜 창에서 <오퍼레이트 클릭>을 해주십시오. 신규...를 선택합니다. 새로운 프로토콜 이름 입력을 요구하는 다이얼로그가 표시됩니다. testing을 입력하고 OK를 클릭해주십시오.
메서드를 생성하기 위한 "템플릿"이 표시됩니다.
15. 메서드 코드 뷰의 텍스트를 다음과 같이 바꿔주십시오.
viewDirectory
| workingDir contents |
workingDir := logDirectory asFilename.
contents := workingDir directoryContents.
contents do: [ :each | Transcript show: each printString; cr. ]
16. 코드 뷰에서 <오퍼레이트 클릭>후 Accept를 선택해주십시오. 입력 미스가 없다면 입력된 코드가 "컴파일" 되어서 viewDirectory 메서드가 메서드 창에 표시됩니다.
아래 그림과 같은지 확인해주십시오.
그림 7-13. 브라우저에 표시된 새로운 메서드(viewDirectory)
|
|
17. Workspace를 열고 WebLogClass new viewDirectory를 입력하고 실행을 선택해주십시오. 이전에 했던 것 과 같이 Transcript 표시가 가능한 것을 확인해주십시오.
|
|
18. 프로토콜 창 위에 있는 Instance 탭이 선택되어 있는 것을 확인해주십시오. 그리고 프로토콜 창에서 <오퍼레이트 클릭>을 해주십시오. 신규...를 선택합니다. 새로운 프로토콜명 입력을 요구하는 다이얼로그가 표시됩니다. Private를 입력하고 OK를 클릭해주십시오.
메서드를 생성하기 위한 "템플릿"이 표시됩니다.
19. 메서드 코드 뷰의 텍스트를 다음과 같이 바꿔주십시오.
showHits: aFile
| myFile myStream myLine addrIP mySet |
mySet := Set new.
myFile := (logDirectory, '\', aFile) asFilename.
myStream := myFile readStream.
[ myStream atEnd ] whileFalse:
[myLine := myStream upTo: Character cr.
addrIP := myLine copyUpTo: $,.
mySet add: addrIP.].
myStream close.
^mySet size.
20. 코드 뷰에서 <오퍼레이트 클릭>후 Accept를 선택해주십시오. 입력 미스가 없다면 입력된 코드가 "컴파일"되서 showHits 메서드가 메서드 팡에 표시됩니다.
아래 그림과 같은지 확인해주십시오.
그림 7-14. 브라우저에 표시된 새로운 메서드(showHits)
|
|
Smalltalk의 메서드는 다른 언어에서 말하는 서브 루틴이나 함수와 같은 것입니다. COBOL 언어에서는 "프로시저"라 불리우며, BASIC에서는 "SUB 등"입니다. 하지만 "함수"라는 용어는 루틴이 리턴되거나 값을 되돌리거나 할때에 일반적으로 사용됩니다. Smalltalk에서 무언가 "반환"하고 싶을 때 캐럿 기호(^)(원고 등에서 사용되는 탈자기호)를 사용합니다.
캐럿리턴을 사용하는 식이 있는 경우, 항상 맨 처음에 식 전체가 평가되는 것을 기억해 두십시오. 실제 "반환"되는 것은 맨 마지막에 평가된 것입니다. 따라서 ^mySet size와 같은 식에서 Smalltalk는 mySet size(아마 Smallinteger 인스턴스를 생성)를 평가하고, 이 메서드가 호출된 객체에 그 결과를 돌려줍니다.
|
|
Smalltalk에서는 정해진 코드(인덴트, 개행, 코드블록 등)의 포맷이 없습니다. 자유로운 포맷으로 쓸 수 있습니다. 하지만 VisualWorks를 사용함에 있어, 사실상 표준은 존재합니다. 브라우저는 자동포맷 기능을 가지고 있습니다.
코드 뷰에서 <오퍼레이트 클릭>후 Format을 선택해주십시오. 사실상 표준 포맷에 따라 코드를 "포맷"합니다.
그림 7-15. <오퍼레이트 메뉴>에서 포맷 항목
그림 7-16. Smalltalk 표준 포맷의 코드
|
|
21. private프로토콜이 선택된 상태에서 코드 뷰의 텍스트를 다음과 같이 바꿔주십시오.(showHits 메서드를 덮어써도 문제는 없습니다. 이미 코드는 메모리에 보존되어 있습니다.)
getLogFiles
| workingDir contents xFound count |
workingDir := logDirectory asFilename.
contents := workingDir directoryContents.
contents do: [ :each |
xFound := each findString: filter startingAt: 1.
xFound > 0
ifTrue:[ count := self showHits: each.
Transcript show: each, ' . . . ', (count printString); cr. ].
].
단순한(합성되지 않은) "필터"로직으로 되돌렸습니다. ws00으로 시작하는 파일만 로그파일이기 때문에, ws00으로 시작하는 파일을 검색하도록 해야 합니다. Filter가 초기화될 때, 어떻게 해야 좋을지 아실겁니다.
22. 코드 뷰에서 <오퍼레이트 클릭>후 Accept를 선택해주십시오. 입력미스가 없다면 입력된 코드가 "컴파일"되어서 getLogFiles 메서드가 메서드 창에 표시됩니다.
아래 그림과 같은지 확인해주십시오.
그림 7-17. 브라우저에 표시된 새로운 메서드(getLogFiles)
|
|
잠시 기다려주십시오. 코드 가운데 여태껏 본 적 없는 새로운 것이 있습니다. – self, 대체 무엇일까요?
self를 자세히 알아보기.
|
|
23. private 프로토콜이 선택된 상태에서 다음과 같이 코드 뷰에 있는 텍스트(getLogFiles 메서드)를 바꿔주십시오.
start
filter := (Dialog request: 'フィルタを入力してください: ' initialAnswer: 'ws00').
(filter size) > 0
ifTrue: [self getLogFiles]
24. 코드 창에서 {{HighlightBold|<오퍼레이트 클릭>}후 Accept를 선택해주십시오. 입력 미스가 없다면 입력된 코드가 "컴파일"되어 start 메서드가 메서드 창에 표시됩니다.
아래 그림과 같은지 확인해주십시오.
그림 7-18. 브라우저에 표시된 새로운 메서드(start)
25. Workspace을 열고 다음과 같이 입력해주십시오.
모든 텍스트를 반전시키고 <오퍼레이트 클릭>후 실행을 선택해주십시오.
이 코드는 이전 레슨에서 실행했던 내용과 같은 실행결과를 얻을 수 있습니다.
|
|
잠시 기다려주십시오. 코드 가운데 여태껏 본 적 없는 새로운 것이 있습니다. - self, 대체 무엇일까요?
self를 자세히 알아보기.
|
|
정리
기나긴 워크샵이었습니다만, 그만한 가치가 있었다고 생각합니다. 카테고리 및 공통 프로토콜을 작성하기 위해서 "사전준비"작업을 해야했기 때문에 길다고 느끼셨을 겁니다.
다음 레슨에서는 작업을 보존하기 위한 방법을 배우겠습니다. 다음 레슨 후에 기능적인 클래스를 추가하겠습니다. 그 클래스는 인기가 많은 웹페이지를 카운트 합니다.(즉, 매우 많은 Hit를 얻은 웹 페이지)
아래와 같은 내용을 학습하였습니다
- 새로운 카테고리, 클래스, 프로토콜, 메서드를 생성하기 위한 System Browser의 사용법
- 두 가지 메서드 타입(클래스와 인스턴스)
- Smalltalk에서 사실상 표준 코드 포맷
- 작업공간에서 객체의 테스트
|
| 목차 | 레슨6 | 레슨8 |
|