8. 모든 동작은 메시지 보내
기로 한다는 것
객체를 사용하는 사람은 그 객체가 무엇을 할
수 있을 지 모르는 상태에서 명령을 한다(메시
지를 보낸다).
객체는 그 메시지를 이해할 수도 이해하지 못
할 수도 있다.
메시지의 실행은 객체의 클래스와 그 상위클
래스에 있는 메서드 사전을 찾아보고 판단
10. 시범: 실행하면서 코딩한다.
• 여러 개의 Flasher를 화면에 띄운다.
• 클래스 브라우저에서 상위클래스를 RectangleMorph로 바꾼다.
• 인스턴스 변수offColor를 추가하고, 반짝임을 “onColor와 어둡게한 onColor”가
아니라, “onColor offColor 교대로 쓰게” 바꾸자.
11. 코드가 실행되면 그곳에
는 객체가 있다.
void리턴이 없다.
반드시 리턴값이 있다.
스몰토크의 모든 것은 객체다.
따라서, 모든 부분 코드(표현)는 객체로 간주
할 수 있다.
12. 나쁜 것은 금지,
좋은 것은 강제
public member variable
설계에 시간소모
언제나 통합
13. 스몰토커는 구글을 쓰지
않아!
코딩하다 말고 구글링을 하는 이유
API가 바이너리라서 사용법을 공부해야 한
다. ☞☞ 코드가 모두 노출
에러가 발생했는데, 이유를 알 수 없다.
☞☞ 코드가 모두 노출
무언가 하려고 하는데, 예제가 없다. ☞☞
맘만 먹으면 따라할 수 있다
39. 마침표(.)
문장의 끝임을 나타내는 문자
두 개 이상은 문장이 연속 실행될 때 문장과
문장을 구분한다.
한 문장을 여러 줄에 걸쳐서 작성할 수 있다!
World canvas fillColor: Color red.
Display restore.
20 + 3.
40. 세미콜론(;)
연속된 문장의 주어객체(receiver)가 같을 때,
주어객체의 언급을 생략할 수 있게 한다.
myObj doWork1.
myObj add: 1.
myObj doWork2.
myObj
doWork;
add: 1;
doWork2
41. 리턴 기호 ^
^로 시작하는 문장의 실행결과가 되돌려진다.
이하 코드는 실행되지 않는다.
↑
42. void리턴이 없다
리턴을 하지 않으면 self가 자동 리턴된다.
^self
코드(표현)이 실행되면 그곳에는 객체가 남는
다.
43. 대입
a := 3.
b := 4.
c := a+b.
:= _
a _ 3.
b _ 4.
c _ a+b.
a ← 3.
b ← 4.
c ← a+b.
a := 3.
b := 4.
c := a+b.
44. 블록
리터럴 중 하나
참았다가 실행하는 객체
suspend상태로 생성된 쓰레드와 비슷
하나 이상의 문장을 포함할 수 있음
마지막 문장의 값이 블록의 값
45. 블록
[ ]
[ daliot join: party. altlang add: party ]
[ | pos | pos := altlang location. pos nation ]
[ :person :party | party includes: person ]
[ :x| | y | y := x * x ]
46. 실습: 블록은 참았다가 실행하는 객체
• a := 10.
bl := [ a:= 0 ].
a. “이 때 a의 값은 얼마일까?”
bl value.
a “이 때 a의 값은 얼마일까?”
47. 실습: 블록은 간이 메서드
• 다음을 실행했을 때, 공은 어느 컵에 있을까요?
• cups := #(nil ball nil).
m1 := [cups swap: 1 with: 2].
m2 := [cups swap: 2 with: 3].
m3 := [cups swap: 1 with: 3].
m2 value.
m3 value.
m1 value.
m2 value.
m3 value.
cups.
• 그 공을 원래 위치로 놓으려면 어느 블록에 #value 를 해야 할까요?
48. 실습: 블록은 유연한 설계의 수단
• 문자열 ‘alonzo’ ‘seal’ ‘morning’ 을 세 가지 기준으로 정렬하라.
• 알파벳 순서
• 길이 순서
• 문자 o의 개수
49. 변수의 종류
임시 변수
인스턴스 변수
전역 변수
클래스 변수
클래스 인스턴스 변수
공유 사전(pool dictionary)
50. 임시 변수
| 변수들 |
소문자로 시작
| pig cow total |
pig := 3.
cow := 4.
total := pig+cow.
51. 인스턴스 변수
멤버변수 혹은 필드라고 부르는 바로 그것
객체마다 값이 다를 수 있는 변수
소문자로 시작
클래스 정의에 포함
PasteUpMorph subclass: #ZoomAndScrollMorph
! instanceVariableNames: 'sourceRectangle usingBalloon panAndTiltFactor zoomFactor'
! classVariableNames: ''
! poolDictionaries: ''
! category: 'MorphicExtras-Demo'
53. 클래스 변수
대문자로 시작
클래스 정의문에 선언된다
클래스와 인스턴스가 접근할 수 있다.
상위클래스는 접근할 수 없다.
Object subclass: #AsyncFile
! instanceVariableNames: 'name writeable semaphore fileHandle'
! classVariableNames: 'Busy ErrorCode'
! poolDictionaries: ''
! category: 'Files-Kernel'
54. 클래스 인스턴스 변수
대문자로 시작
클래스 정의문에 선언된다
클래스와 인스턴스가 접근할 수 있다.
클래스 자신과 하위클래스 모두 변수가 생긴
다. 각 클래스마다 자신만의 변수를 소유
55. 공유 사전
(pool dictionary)
대문자로 시작
클래스 정의문에 선언된다
클래스와 인스턴스가 접근할 수 있다.
정체는 Dictionary인데, 사용한다고 선언하면,
그때부터는 그것의 키가 변수처럼 사용된다.
56. 괄호
( ) paranthsis 소괄호 표현계산 우선순위
[ ] block 블록
실행될 수 있는 코
드 뭉치
{ } curly braces 중괄호
표현식의 나열로
배열을 만든다(스
퀵에서만 쓰임)
57. 메서드 정의
머리, 임시 변수 선언, 몸통으로 이루어짐
머리는 sigature라고 불리며, 메서드의 이름과
인자들의 이름이 나타난다.
임시 변수 선언은 머리 다음에서만
몸통에는 문장들이 있으며, 마침표(.)로 구분되
어 순서대로 실행된다.
하나 이상의 리턴 ^
58. 메서드는 이렇게 생겼다
exampleWithNumber: x
“This is a small method that illustrates every part of Smalltalk method syntax
except primitives, which aren’t very standard. It has unary, binary, and key
word messages, declares arguments and temporaries (but not block temporaries),
accesses a global variable (but not and instance variable), uses literals (array,
character, symbol, string, integer, float), uses the pseudo variable true false,
nil, self, and super, and has sequence, assignment, return and cascade. It has both
zero argument and one argument blocks. It doesn’t do anything useful, though”
| y |
true & false not & (nil isNil) ifFalse: [self halt].
y := self size + super size.
#( $a #a ‘a’ 1 1.0)
do: [: each | Transcript
show: (each class name);
show: (each printString);
show: ‘ ‘].
^ x < y
주석
인자
특수변수
임시변수
클래스
블록변수
59. 소스코드에서 객체를
알아보는 방법
표현의 시작은 반드시 객체다.
다음 기호들 뒤에 따라 나오는 것은 객체
비법
:= 대입기호
^ 리턴기호
. 문장구분
: 콜론
( [ { 괄호
63. 다음의 스몰토크 코드에서
객체와 메서드를 찾아라
evaluateSelection
"Treat the current selection as an expression; evaluate it and return the result"
| result rcvr ctxt |
self lineSelectAndEmptyCheck: [^ ''].
(model respondsTo: #doItReceiver)
ifTrue: [FakeClassPool adopt: model selectedClass. "Include model pool vars if any"
rcvr _ model doItReceiver.
ctxt _ model doItContext]
ifFalse: [rcvr _ ctxt _ nil].
result _ [
rcvr class evaluatorClass new
evaluate: self selectionAsStream
in: ctxt
to: rcvr
notifying: self
ifFail: [FakeClassPool adopt: nil. ^ #failedDoit]
logged: true.
]
on: OutOfScopeNotification
do: [ :ex | ex resume: true].
FakeClassPool adopt: nil.
^ result
64. 다음의 스몰토크 코드에서 객체와 메서드를 찾아
라
evaluateSelection
"Treat the current selection as an expression; evaluate it and return the result"
| result rcvr ctxt |
self lineSelectAndEmptyCheck: [^ ''].
(model respondsTo: #doItReceiver)
ifTrue: [FakeClassPool adopt: model selectedClass. "Include model pool vars if any"
rcvr _ model doItReceiver.
ctxt _ model doItContext]
ifFalse: [rcvr _ ctxt _ nil].
result _ [
rcvr class evaluatorClass new
evaluate: self selectionAsStream
in: ctxt
to: rcvr
notifying: self
ifFail: [FakeClassPool adopt: nil. ^ #failedDoit]
logged: true.
]
on: OutOfScopeNotification
do: [ :ex | ex resume: true].
FakeClassPool adopt: nil.
^ result
객체
메서드
블록은
객체다
72. 실습: 루비의 후위 if를 구현하자
• 루비의 후위 if는 영어 가정법 문장과 같은 꼴
• 자연스럽게 읽히는 장점
• x>10 ifTrue: [ x := x-5 ] 를
• [ x := x-5 ] if x>10 로
73. while은...
다 라이브러리야! ^^
블록객체의 메서드일 뿐
[ x = 1 ] whileFalse: [ x := x // 2 ].
[ str size < 100 ] whileTrue: [ str := str , str ].
74. 실습: 무한루프 방지 while 문
• while문은 자칫 무한루프로 빠지기 쉽다
• 무한루프에 빠질 것 같으면, 중단시키는 while문이 있다면 좋지 않을까?
• x := 10.
[ x > 0 ]
whileTrue:
[ x := x / 2 ] 를
• x := 10.
[ x > 0 ]
whileTrue:
[ x := x / 2 ]
loopLimit: 100 로 바꾸자
75. for은...
다 라이브러리야! ^^
(1 to: 10) do:
[:num|
Transcript
show: num ;
show: ‘ little indian boy’;
cr ]
Interval 객체, #do: 를 쓴다.
80. 생성자는...
따로 없다.
initialize라는 것이 있긴한데, 반드시 정의해줘야 하거
나, 반드시 불린다거나하는 보장은 없다.
initialize가 불리는 이유는 new메서드에서 불리기 때
문
다만, 스퀵에서는 initialize가 반드시 불린다.
다 라이브러리야! ^^
81. 파괴자는...
따로 없다.
finalize라는 것이 있긴 한데, 이것도 반
드시 불리는 것은 아니다.
beFinalizable 를 당했을 때만 불린다.(돌
핀)
스퀵은? 모름...
다 라이브러리야! ^^
104. 실습: 클립보드 해킹
• Clipboard 모프를 연다.
• 이 모프의 step메서드를 열어 보자.
• self halt 를 걸어보자.
• cmd + c 혹은 copy메뉴로
텍스트복사를 하고, step에서
벌어지는 일을 디버거로 지켜보자.
• Clipboard 클래스를 쓰는 법을
깨달았다면, 응용해보자.
105. 날린 코드 복구하기
이미지 저장하지 않으면 모든 것을 잃는다.
스몰토크는 실행하거나 컴파일한 모든 것
을 .changes 파일에 항상 기록하고 있다.
File List 로 .changes 파일을 열면 그 내용을 복구
할 수 있다.
간단한 실습 ^^
108. 솟수(prime number)
2~N 사이의 모든 솟수(prime number)를 구하라
에라토스테네스의 체
배울 수 있는 것들
배열의 사용법, collect:, select:의 사용법
변수 대입, 나머지, 블록
109. 실습: 2~N 사이의 모든 솟수를 구하라
• 2, 3, 4, 5, ... , 18, 19, 20의 배열을 만든다.
• 2를 솟수로 등록한다
• 2로 나누어 떨어지는 수는 모두 버린다.
• 3을 솟수로 등록한다
• 3으로 나누어 떨어지는 수는 모두 버린다.
• ... 반복 ...
110. 실습: 대소문자 뒤집기
• 문자열의 대문자는 소문자로, 소문자는 대문자로 바뀐 문자열을 생
성하는 메서드를 만들자.
• 'Smalltalk is born from Palo Alto LAB' caseReversed 하면...
• 'sMALLTALK IS BORN FROM pALO aLTO lab' 가 만들어지도록
111. 실습: isRedundant 메서드 만들기
• 배열의 모든 객체들이 한 번만 등장하는 지 확인하는 메서드
• ‘abc’ isRedundant --> false
• ‘abca’ isRedundant --> true
• #(3 3 3) isRedundant --> true
• #(10 20 30) isRedundant --> false
112. 실습: 모프 감추기 그리고 보이기
• 아무 모프나 인스펙터로 연다.
• 그 인스펙터에서 self 에 hide 메시지를 보내본다.
• show 메시지를 보내본다.
• 도전: 모든 모프를 hide시켜보자. 또, show 시켜보자.
• 힌트: allSubInstances
114. 실습: 창 닫는 버튼 만들기
• 모프 객체의 인스펙터를 연다.
• 인스펙터에서 SimpleButtonMorph 객체를 만들되, 그것의 target,
action, arguments를 잘 지정한다.
• 버튼을 눌러본다.
• 힌트: 창닫는 메시지 delete
115. 실습: TextMorph 내용 바꾸는 버튼 만들기
• TextMorph 객체를 만든다.
• 이 모프의 인스펙터를 연다.
• 인스펙터에서 SimpleButtonMorph 객체를 만들되, 그것의 target,
action, arguments를 잘 지정한다.
• 버튼을 눌러본다.
• 힌트: contents:
116. 실습: TextMorph 내용 뒤집는 버튼 만들기
• TextMorph 객체를 만든다.
• 이 모프의 인스펙터를 연다.
• 인스펙터에서 SimpleButtonMorph 객체를 만들되,
#reverseContents 가 actionSelector로 되도록 한다.
• 버튼을 눌러본다.
117. 실습: Big Bang
• 모프의 영역을 바꾸는 메서드를
알아내자. (힌트: 인스펙터)
• 모프의 영역을 좁게 만드는 문장
을 만들자.
• 모프의 영역을 넓게 만드는 문장
을 만들자.
• 두 문장을 번갈아 실행 해보자.
• 욕심: 두 동작을 하는 버튼을 만
들 수 있을까?
118. 실습: 빠르게 자라는 숲
• Trees 객체를 여러 개 만든다.
• 나무 그림을 초기화하는 메서드
를 알아낸다.
• 나무 그림을 완성하는 메서드를
알아낸다.
• 모든 Trees 모프에게 위에서 알
아낸 메서드를 불러준다.
• 배경색을 투명하게 바꾸자.
(힌트) Color black을 찾자
119. 실습: 부풀어 오르는 풍선
• 0.1초 마다 조금씩 커지는 풍선
을 만들자
• EllipseMorph를 상속 받은 클
래스를 하나 만들자.
• 인스펙터로 실행해보면서 적
절한 코드를 찾아보자.
• step, stepTime
• 너무 커지거나 클릭 당하면 팡
터지게!!
• 욕심: 풍선은 작을 때는 불투명
하지만, 클 때는 속이 비춰 보인
다.
120. 실습: 색 뽑기 만들기
• 마우스 커서가 있는 위치의 픽셀의 색깔을
자신의 색깔로 만드는 모프를 만들자.
• step을 구현
• 알아야 할 것
• 마우스의 위치(돋보기 참고)
• 특정 좌표의 색깔
힌트:
ColorPickerMorph>>pickColorAt:
• 모프의 색깔 바꾸는 방법
121. addMorph:
두 모프를 addMorph: 하면, 한 모프가 다른쪽
모프에 종속된다.
상위 모프의 submorphs 배열에 추가
하위 모프의 owner 가 설정
상위 모프 삭제시, 하위 모프 함께 삭제 됨
122. 실습: addMorph:
• m1 := Morph new openInHand.
m2 := Morph new openInhand.
m1 addMorph: m2.
m1 delete.
123. 실습: 춤추는 창들
• Bouncing Atoms 모프를 만든다.
• 익스플로러로 이 모프의
submorphs를 관찰하자.
• 한 원자모프가 열려 있는 다른
창을 addMorph: 한다면?
• 열려있는 다른 창
World submorphs
124. 클래스 만들기
스몰토크의 클래스 만들기는 이미 존재하는 클
래스에게 아기를 만들라고 말하면 된다.
상위클래스 subclass: #만들클래스이름
! instanceVariableNames: 인스턴스변수나열문자열
! classVariableNames: 클래스변수나열문자열
! poolDictionaries: 풀사전나열문자열
! category: 카테고리이름
125. 실습: 100개의 클래스
• MyFoo라는 클래스를 만들자
• MyFoo 의 하위 클래스 100개를 만들자
• 하위 클래스의 이름은 Foo와 숫자
• Foo0, Foo1, Foo2, Foo3, Foo4 , ... , Foo98 , Foo99
• MyFoo클래스를 삭제하자
126. 실습: do it 의 정체를 밝혀라!
• “do it” 메뉴로부터 디버깅에 들어간다.
• step into 버튼으로 속으로 속으로 들어가 보자.
• 두 개의 클래스를 찾으면 성공!
• C로 시작하는 클래스
• P로 시작하는 클래스
127. 실습: 줄줄이 돋보기
• Rows 모프를 꺼낸다.
• Magnifier모프를 꺼낸다.
• 그걸 3개 복사해서 Rows모프에 넣는다.
• 4개의 돋보기의 배율을 순서대로 1.5 , 2 , 4 , 8 로 맞춘다.
• 손으로 만든 이 모프를 생성하는 코드를 작성해보자.
128. 숫자야구
두 명의 플레이어가 각자 자기의 비밀수를 결정한
다. 비밀수는 0 외 9개의 숫자로 된 4자리의 수다.
한 플레이어가 다른 플레이어에게 4자리 숫자를
물어본다.
다른 플레이어는 그 수를 자신의 비밀수와 비교,
자리와 수가 일치하는 것이 몇개, 자리는 틀리지만
같은 수가 몇개 있다고 답한다.
다른 플레이어가 묻고, 한 플레이어가 답한다.
어느 한 쪽이 비밀수를 맞출 때까지 이것을 반복
129. 실습: 숫자야구
• TestRunner로 단위테스트를 작성하며 모델을 만들자.
• 모프를 만들어 모델을 끼워넣자. (모델의 수정이 필요하다면 고친다)
• 두 사람이서 게임을 해보자.
• 1:1 네트웍 게임으로 만들어보자.
• 서버 클라이언트 다대다 네트웍 게임으로 만들어보자. (아이디와 패스워드)
• 대결 기록을 서버에 남기도록 하자.
• 자동 결투를 하면, 서버가 실력이 비슷한 사람끼리 싸움을 붙이게 하자.