SqueakByExample:9.4

From 흡혈양파의 번역工房
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

주요 클래스에 대한 예제

지금부터 일반적이거나 중료한 컬렉션 클래스를 이용한 간단한 예제를 제시할 것입니다. 컬렉션의 주요 프로토콜들은 -구성요소에 접근하기 위한 at:, at:put: 이 있으며, -구성요소를 추가하거나 제거하기 위한 add:, remove:가 있고, -컬렉션에서 몇가지 정보를 얻기 위한 size, isEmpty, include: 가 있으며, -컬렉션의 반복을 위한 do:, collect:, select:가 있습니다. 각 컬렉션은 이런 프로토콜들을 실행하거나 실행하지 않을 수 있으며, 실행하는 경우에는 컬렉션의 의미에 맞게 프로토콜은 해석됩니다. 특정 프로토콜 및 좀 더 고급의 프로토콜을 식별하고싶다면 클래스 자체를 탐색하는것이 좀더 좋은 방법입니다.

여기서는 가장 일반적인 컬렉션 클래스들인 OrderedCollection, Set, SortedCollection, Dictionary, Interval 과 Array 를 집중적으로 살펴보겠습니다.


일반 생성 프로토콜(Common creation protocol) 컬렉션의 인스턴스를 만드는 데에는 몇가지 방법이 있습니다. new: 와 with: 를 사용하는 것이 가장 일반적인 방법입니다. new: anInteger 는, 크기가 anInteger 이며 모든 요소가 nil 인 컬렉션을 만듭니다. with: anObject 는 컬렉션을 만들고, 만들어진 컬렉션에 anObject 를 추가합니다. 다른 컬렉션들은 이런 동작을 다르게 인식할 것입니다.


사용자는 초기 요소를 가지는 콜렉션을 만들기 위해 with:, with:with: 등의 메서드를 사용할 수 있습니다. 최대 6 개의 요소를 지정할 수 있습니다.

Array with: 1        #(1)
Array with: 1 with: 2        #(1 2)
Array with: 1 with: 2 with: 3        #(1 2 3)
Array with: 1 with: 2 with: 3 with: 4        #(1 2 3 4)
Array with: 1 with: 2 with: 3 with: 4 with: 5        #(1 2 3 4 5)
Array with: 1 with: 2 with: 3 with: 4 with: 5 with: 6        #(1 2 3 4 5 6)


또한 어느 콜렉션의 모든 요소를 다른 종류의 콜렉션에 모두 추가하려면 addAll: 을 사용할 수 있습니다.

(1 to: 5) asOrderedCollection addAll: '678'; yourself        an OrderedCollection(1 2 3 4 5 $6 $7 $8)


addAll: 은 그 자체의 인수를 반환합니다만, 수신자를 반환하지는 않는다는것에 주의해주세요.

또한 많은 컬렉션에서 withAll: 또는 newFrom: 을 이용하여 만들수도 있습니다.

Array withAll: #(7 3 1 3) ⇒ #(7 3 1 3)
OrderedCollection withAll: #(7 3 1 3) ⇒ an OrderedCollection(7 3 1 3)
SortedCollection withAll: #(7 3 1 3) ⇒ a SortedCollection(1 3 3 7)
Set withAll: #(7 3 1 3) ⇒ a Set(7 1 3)
Bag withAll: #(7 3 1 3) ⇒ a Bag(7 1 3 3)
Dictionary withAll: #(7 3 1 3) ⇒ a Dictionary(1-->7 2-->3 3-->1 4-->3 )


Array newFrom: #(7 3 1 3) ⇒ #(7 3 1 3)
OrderedCollection newFrom: #(7 3 1 3) ⇒ an OrderedCollection(7 3 1 3)
SortedCollection newFrom: #(7 3 1 3) ⇒ a SortedCollection(1 3 3 7)
Set newFrom: #(7 3 1 3) ⇒ a Set(7 1 3)
Bag newFrom: #(7 3 1 3) ⇒ a Bag(7 1 3 3)
Dictionary newFrom: {1 --> 7. 2 --> 3. 3 --> 1. 4 --> 3} ⇒ a Dictionary(1-->7 2-->3 3-->1 4-->3 )
Dictionary withAll: #(7 3 1 3) ⇒ a Dictionary(1-->7 2-->3 3-->1 4-->3 )


이 두 개의 메서드들(withAll 과 newFrom:)은 같지 않다는 것에 주의해 주세요.

Dictionary class>>newFrom: 은 인수로 관련된(비슷한) 컬렉션을 요구하지만, 이와는 다르게 Dictionary class>>withAll: 은 인수를 값(value)의 컬렉션으로 해석합니다.


배열

Array(배열)는, 고정 크기 컬렉션으로서 정수의 첨자(Integer indices)로 접근할 수 있습니다. C 언어의 관례와는 반대로, 스몰토크 배열의 첫 번째 구성요소는 1 번 위치에 있으며 0 번 위치에서 시작하지 않습니다. 메서드 at: 과 at:put: 은 배열의 구성요소에 접근하기 위한 메인 프로토콜 입니다. at: anInteger 는 anInteger 의 내용이 의미하는 index 내 위치의 요소를 반환합니다. at: anInteger put: anObject 는 anObject 를 anInteger 에 해당하는 index 에 집어넣습니다. 배열은 고정된 크기의 컬렉션이므로, 사용자는 배열의 끝부분에서 추가나 제거를 진행할 수 없습니다. 다음 코드는 5 의 크기를 가지는 배열을 만들어, 처음부터 세번째까지 3 개의 요소에 값들을 집어넣고 index 의 첫번째 요소(index 1)를 반환합니다.

anArray := Array new: 5.
anArray at: 1 put: 4.
anArray at: 2 put: 3/2.
anArray at: 3 put: 'ssss'.
anArray at: 1      4


Array 클래스의 인스턴스를 만드는데에는 몇가지 방법이 있습니다. 인스턴스를 만드는 작업을 위해서 new:, with:, 그리고 #( ) 구문과 { } 구문등을 사용할 수 있습니다.


new: 를 이용한 배열의 생성 new: anInteger 는 anInteger 크기의 배열을 만듭니다. Array new: 5 는 크기 5 의 배열을 만듭니다.


with 를 이용한 배열의 생성 with: 메서드는 배열내 요소들의 값을 인수로 사용할 수 있습니다. 아래의 코드는 숫자 4, 분수 3/2 그리고 문자열 'lulu' 로 구성된 3 개의 요소를 가지는 배열을 생성합니다.

Array with: 4 with: 3/2 with: 'lulu'        {4 . (3/2) . 'lulu'}


#() 로 리터럴 생성. #() 문법은 정적static인(또는 "literal") 요소를 가지는 리터럴 배열을 생성하는데, 이 정적static 이라고 하는 특성은 요소의 값이 실행시점이 아닌 컴파일되었을때 이미 값을 가지고있어야 한다는 의미를 가집니다. 아래의 코드에서, 첫 번째 구성요소가 (literal) 숫자 1 이고 두 번째 요소는 (literal) 문자열 'here' 가 되는 크기 2 의 배열을 생성합니다.

#(1 'here') size        2


이제, 만약 #(1+2) 를 처리하셨다면, 3 이라는 숫자값을 요소로 가지는 배열을 얻는것이 아니라, 대신 3 개의 구성요소: 숫자 1, 심볼 #+ 그리고 숫자2 의 3개 요소를 가지는 #(1 #+ 2) 라는 배열을 얻게됩니다.

#(1+2)        #(1 #+ 2)


이런 결과가 발생하는 이유는 #() 구문이 컴파일러로 하여금, 배열에 포함된 표현식을 그대로(literal로) 해석하도록 지시하기 때문입니다. 인수로 주어지는 표현식은 조사되며 결과적으로 요소들은 새로운 배열로 수용됩니다. 리터럴 배열은 숫자, nil, true, false, symbol 그리고 문자열string을 포함합니다.


{ }로 동적 배열 만들기. 마지막으로 알아볼 {} 문법을 이용해서 동적배열을 만들 수 있습니다. { a . b } 는 : Array with: a with: b 와 같은 의미가 됩니다. 그리고 특수한경우 { 기호와 } 기호로 둘러쌓인 표현식을 실행한다는 의미도 됩니다.

{ 1 + 2 }        #(3)
{(1/2) asFloat} at: 1        0.5
{10 atRandom . 1/3} at: 2        (1/3)


요소 접근(Element Access). 모든 순차가능 컬렉션들의 요소들은 at: 과 at:put: 으로 접근이 가능합니다.

anArray := #(1 2 3 4 5 6) copy.
anArray at: 3        3
anArray at: 3 put: 33.
anArray at: 3        33


리터럴 배열을 수정하는 코드를 다룰 때 주의하십시오. 컴파일러는 리터럴 배열에 대해 공간할당을 단 한번만 진행합니다. 사용자가 배열을 복사하지 않는 한, 두 번째 코드를 평가하면 "리터럴" 배열은 예상하는 값을 가지고 있지 않을 수 있습니다. (객체복사를 하지 않았다면, 두 번째 단계에서, 리터럴 #(1 2 3 4 5 6) 은 실제로 #(1 2 33 4 5 6) 의 값을 가지게 됩니다!) 동적 배열들은 이런 문제를 갖고 있지 않습니다.


OrderedCollection

OrderedCollection 은 크기변경이 가능한 컬렉션들 중의 하나이며, 이 컬렉션에서 요소는 순차적으로 추가할 수 있습니다. 이 컬렉션은 add:, addFirst:. addList:, 그리고 addAll: 등과 같은 다양한 메서드를 제공합니다:

ordCol := OrderedCollection new.
ordCol add: 'Seaside'; add: 'SqueakSource'; addFirst: 'Monticello'.
ordCol        an OrderedCollection('Monticello' 'Seaside' 'SqueakSource')


요소의 제거(Removing Elements). 메서드 remove: anObject 는 컬렉션내의 요소중 anObject 와 일치하는걸 찾은후 첫번째 결과에 해난하는 요소를 제거합니다. 만약 컬렉션에 이러한 객체(anObject)가 포함되어 있지 않다면, 에러를 발생시킵니다.

ordCol add: 'Monticello'.
ordCol remove: 'Monticello'.
ordCol        an OrderedCollection('Seaside' 'SqueakSource' 'Monticello')


remove:ifAbsent: 라는 remove: 의 변형메서드가 있는데, 이 remove:ifAbsent: 메서드의 두번째 인수에는 삭제하려고 시도한 요소가 콜렉션에 없는경우의 동작을 블록으로 넣을 수 있습니다.

res := ordCol remove: 'zork' ifAbsent: [33].
res        33


변환(Conversion) asOrderedCollection 이라는 메시지를 을 발송함으로써, 배열 또는 다른 컬렉션으로부터 OrderedCollection 을 얻어내는 것이 가능합니다.

#(1 2 3) asOrderedCollection        an OrderedCollection(1 2 3)
'hello' asOrderedCollection        an OrderedCollection($h $e $l $l $o)


Interval

Interval 이라는 클래스는 숫자의 범위를 제공합니다. 예를 들면, 숫자 1 에서 100 까지의 인터벌은 다음과 같이 정의됩니다.

Interval from: 1 to: 100        (1 to: 100)


이 인터벌 객체의 printString 결과를 보면, Number 클래스에 to: 라고 하는 편리한 메서드가 있고 이것을 사용해서 Interval 객체를 생성할 수 있다는걸 알 수 있습니다.

(Interval from: 1 to: 100) = (1 to: 100)        true


다음과 같이 2 개의 숫자들 사이의 단계를 지정하기 위해 Interval Class>>from:to:by: 또는 Number>>to:by: 를 사용하는것도 가능합니다.

(Interval from: 1 to: 100 by: 0.5) size        199
(1 to: 100 by: 0.5) at: 198        99.5
(1/2 to: 54/7 by: 1/3) last        (15/2)


Dictionary

Dictionary 는 키(keys)를 사용해서 요소에 접근하는 중요한 컬렉션 입니다. Dictionary 에서 가장 일반적으로 사용되는 메시지는 at:, at:put:, at:ifAbsent:, 그리고 keys 와 values 가 있습니다.

colors := Dictionary new.
colors at: #yellow put: Color yellow.
colors at: #blue put: Color blue.
colors at: #red put: Color red.
colors at: #yellow        Color yellow
colors keys        a Set(#blue #yellow #red)
colors values        {Color blue . Color yellow . Color red}


Dictionary 는 키를 비교하는것으로 동일성을 검사합니다. 만약 = 를 사용하여 비교할 때, true 가 리턴되면 2 개의 키는 동일한 것으로 간주합니다. 찾기힘든 버그중 제일 많이 일어나는 상황은, Key 로서 사용되는 객체에 = 메서드를 재정의했지만, hash 메서드를 재정의하지 않는 경우입니다.

Dictionary 클래스는 콜렉션 계층이 서브클래스subclass에 기초하며 서브타이핑subtyping 은 아니라는것을 명확하게 보여줍니다. 심지어 Dictionary 가 Set 의 서브클래스 입니다만, 일반적으로 Dictionary 를 Set 와 같이 사용하려고 하지는 않습니다. Dictionary 는 -> 메시지를 이용해서 만들어진 key-value 연관성associations의 세트로 구성된것이 분명합니다. 그렇기때문에 Dictionary 는 연관성을 가지는 콜렉션으로부터 만들어질 수도 있으며, Dictionary 를 연관성을 가지는 배열로 변환할 수고 있습니다.

colors := Dictionary newFrom: { #blue-->Color blue. #red-->Color red. #yellow-->Color yellow }.
colors removeKey: #blue.
colors associations        {#yellow-->Color yellow . #red-->Color red}


IdentityDictionary. Dictionary 에서 2 개의 키가 동일한지를 판단하기 위해 메시지 = 와 hash 의 결과를 사용하는 반면에, 클래스 IdentityDictionary 는 이런 값들 대신에, 키의 identity(메시지==)를 사용합니다. IdentityDictionary 는 2 개의 키가 동일한 객체일 경우만, 동일한 것으로 판단합니다.

Symbol 들은 자주 Key 로서 사용됩니다만, 이런경우 IdentityDictionary 를 사용하는 것은 자연스러운 일이며, 왜냐하면 Symbol 은 global 에서 고유하게 보증되기 때문입니다. 한편, Key 가 String 인 경우라면, Dictionary 클래스를 그대로 사용하는 것이 좋습니다. 그렇게 하지 않는다면 작업에서 문제가 생기겠지요:

a := 'foobar'.
b := a copy.
trouble := IdentityDictionary new.
trouble at: a put: 'a'; at: b put: 'b'.
trouble at: a        'a'
trouble at: b        'b'
trouble at: 'foobar'        'a'


위의 예에서 a 와 b 는 다른 객체이기 때문에, 다른 객체로서 취급됩니다. 흥미로운 부분이 있는데, 리터럴 'foobar' 는 단지 한번만 할당되므로, a 와 실제로 동일한 객체가 됩니다. 대부분 이런 명확하지 않는 동작에 의존하는 코드를 만들려고 싶어하지는 않겠죠! 일반적으로 Dictionary는 'foobar' 와 같은 Key 에 대해서는 동일한 값을 반환합니다.

IdentityDictionary Key 로서는 global 하게 고유한 객채(Symbols 또는 SmallIntegers 등)만을 사용해주시길 바라며, String (또는 다른 객체)은 일반적으로 Dictionary 의 Key 로서 사용해주세요..

global 변수인 SmalltalkIdentityDictionary 의 서브클래스인, SystemDictionary 의 인스턴스인것에 주의해주시길 바라며, 이런 이유때문에 모든 Key 는 Symbol(실제로는 8 비트 문자밖에 가질 수 없는 ByteSymbol 입니다) 이 됩니다.

Smalltalk keys collect: [ :each | each class ]        a Set(ByteSymbol)


keys 또는 values 메시지를 Dictionary 에 보내면 결과는 Set 가 됩니다만, Set 클래스에 대해서는 이제부터 다시 설명하도록 하겠습니다.


Set

Set 클래스는, 수학에서 말하는 집합처럼 작동하는 컬렉션이며, 중복요소를 가지지 않고, 요소간에 순서를 가지지 않습니다. Set 에 요소를 추가하려면 add: 메시지를 이용하지만, at: 메시지를 이용해서 요소에 접근하는건 불가능합니다. Set 에 집어넣어진 객체들은, 메서드 hash 와 메서드 = 을 가지고 있어야 합니다.

s := Set new.
s add: 4/2; add: 4; add:2.
s size        2


Set 을 만들때에는 Set class>>newFrom: 또는 변환 메시지 Collection>>asSet: 를 사용하면 됩니다.

(Set newFrom: #( 1 2 3 1 4 )) = #(1 2 3 4 3 2 1) asSet        true


컬렉션으로부터 중복된 사본들을 제거하는 편리한 방법으로서 asSet 을 사용할 수 있습니다.

{ Color black. Color white. (Color red + Color blue + Color green) } asSet size        2

red + blue + green = white 가 되는것에 주의해 주세요.


Bag은 중복된 것들을 허용한다는 것을 제외하면 Set 와 매우 비슷합니다:

{ Color black. Color white. (Color red + Color blue + Color green) } asBag size        3


Set 연산들인 union, intersection 그리고 membership test 는 컬렉션 메시지 union:, intersection: 그리고 includes:. 에 의해 실행됩니다. 수신자는 Set로 먼저 변환되므로, 이 연산들은 모든 종류의 컬렉션들을 위해 작동됩니다!

(1 to: 6) union: (4 to: 10)         a Set(1 2 3 4 5 6 7 8 9 10)
'hello' intersection: 'there'         'he'
#Smalltalk includes: $k               true


이후에 설명하겠습니다만, Set 의 각 요소는 iterators(9.5장 참조) 를 사용해서 접근할 수 있습니다.


SortedCollection

OrderedCollection 과는 반대로, SortedCollection 은 보유하고있는 요소들의 정렬순서를 유지합니다. 기본적으로 SortedCollection 은 정렬 순서를 정하는 작업에 = 메시지를 사용하므로, 비교 객체들(<, =, >, >=, between:and:...)의 프로토콜을 정의하는 (8장을 보십시오)추상 클래스 Magnitude의 서브클래스의 인스턴스들을 정렬할 수 있습니다.

SortedCollection 을 만들기 위해서는, 새로운 인스턴스를 만들고 요소들을 그 인스턴스에 추가하면 됩니다.

SortedCollection new add: 5; add: 2; add: 50; add: -10; yourself.        aSortedCollection(-10 2 5 50)


좀 더 일반적인 경우를 보자면, 사용자가 asSortedCollection 이라는 변환메시지를 현존하는 컬렉션에 전송하는 방법도 있습니다.

#(5 2 50 --10) asSortedCollection        a SortedCollection(-10 2 5 50)


다음 FAQ(질답)에 대한 답변으로는 아래의 예제가 답이 될거같군요:

FAQ: collection 의 내부를 어떻게 정렬하나요?
ANSWER: asSortedCollection 메시지를 전송하면 됩니다.

'hello' asSortedCollection        a SortedCollection($e $h $l $l $o)


위의 예제로부터 정렬을 진행한 결과를 String 으로 되돌리기 위해서는 어떻게 하면 좋을까요? 불행하게도 asString 이 반환하는 printString 은 우리 예상대로 되지는 않습니다.

hello' asSortedCollection asString        'a SortedCollection($e $h $l $l $o)'


위의 내용에 대한 정확한 답은 String class>>newFrom:, String class>>withAll: 또는 Object>>as: 등을 사용하는게 되겠습니다.

'hello' asSortedCollection as: String                      'ehllo'
String newFrom: ('hello' asSortedCollection)        'ehllo'
String withAll: ('hello' asSortedCollection)            'ehllo'


모든 요소가 서로 비교가 가능하다는 전제하에, SortedCollection 은 다른종류의 요소를 가지는게 가능합니다. 예를들어 정수(integers), 부동소수점수(floats), 분수(fractions) 와 같은 비교가능한 다양한 종류의 숫자들을 요소로 가질 수 있다는 의미입니다.

{ 5. 2/-3. 5.21 } asSortedCollection        a SortedCollection((-2/3) 5 5.21)


메서드 <= 를 정의하지 않고있는 객체들을 정렬하려하거나, <= 이외의 다른 기준으로 정렬을 하려고 한다고 생각해 보도록 하겠습니다. 사용자는 이 경우 sortblock 이라고 불리는 2 개로 내부가 나뉜 상태로 구성된 블록을 전달하는것으로 정렬은 가능해집니다. 예를들면 Color 클래스는 Magnitude 가 아니고 <= 메서드를 가지고 있습니다만, 아래처럼 sortblock 을 지정하는것으로, 색에 대한 값을 명도(밝기에 대한 기준)에 의해서 정렬할 수 있습니다.

col := SortedCollection sortBlock: [:c1 :c2 | c1 luminance <= c2 luminance].
col addAll: { Color red. Color yellow. Color white. Color black }.
col        a SortedCollection(Color black Color red Color yellow Color white)


String

스몰토크 에서 String(문자열)은 Chracter 의 컬렉션으로 표현됩니다. 이렇게 되어있는 컬렉션은 순차가능sequenceable, 색인가능indexable, 수정가능mutable 그리고 혼합가능homogeneous 하며 같은종류의 요소, 즉 Chracter 의 인스턴스만 가질 수 있습니다. String 은 일반적으로 String 리터럴을 '(single quote)로 둘러싸는것으로 생성하며, Array 처럼 String 은 전용 문법을 가지고 있습니다만, 일반적인 컬렉션 메서드도 잘 작동합니다.

'Hello'        'Hello'
String with: $A        'A'
String with: $h with: $i with: $!        'hi!'
String newFrom: #($h $e $l $l $o)    ⇒    'hello'


사실, String 은 추상클래스입니다. String 을 인스턴스화 하는경우 실제로 얻는것은 8-bit ByteString 또는 32-bit WideString 입니다. 설명을 간단하게 하기위해서, 이런 차이는 무시하고 String 의 인스턴스에 관해서만 알아보도록 하겠습니다.

String 형태의 2 개의 인스턴스는 ,(comma-쉼표)로 연결될 수 있습니다.

s := 'no', ' ', 'worries'.
s        'no worries'


String 은 수정가능mutable한 컬렉션이기 때문에, 사용자는 메서드 at:put: 을 사용하여 내용을 변경할 수 있습니다.

s at: 4 put: $h; at: 5 put: $u.
s        'no hurries'


쉼표 메서드는 Collection 에서 정의되어 있기 때문에, 모든 종류의 컬렉션에 대해서 동작이 가능하다는 것을 주의해 주십시오!

(1 to: 3) , '45'        #(1 2 3 $4 $5)


아래의 예제에서 볼 수 있듯이, 이미 존재하는 문자열을 replaceAll:with: 또는 replaceFrom:to:with: 등을 사용해서 변경하는것도 가능합니다. 인수로 주어지는 문자수와 지정하는 간격의 길이가 같아야 하는것에(replaceFrom의 경우) 주의해주세요[1].

s replaceAll: $n with: $N.
s        'No hurries'
s replaceFrom: 4 to: 5 with: 'wo'.
s        'No worries'


위에서 언급된 메서드들과는 다르게도, copyReplaceAll: 메서드는 새로운 문자열을 생성합니다.(신기하게도 이 메서드의 인수는 개별의 문자보다는 부분문자열로 취급되기 때문에 크기가 같아야할 필요는 없습니다)

s copyReplaceAll: 'rries' with: 'mbats'        'No wombats'


이 메서드의 구현내용을 살펴보면, 사실 String 전용으로 정의된것이 아니고 어떤 종류의 SequenceableCollection 에서도 사용이 가능하다는것을 알 수 있습니다. 따라서 아래의 내용도 동작하게 되는거죠.

(1 to: 6) copyReplaceAll: (3 to: 5) with: { 'three'. 'etc.' }        #(1 2 'three' 'etc.' 6)


String Matching. 메시지 match: 를 발송함으로써 패턴이 String 과 매치되는지의 여부를 요청하는 작업이 가능합니다. 패턴에서 *(asterisk) 기호는 임의의 길이를 의미하며, #(sharp) 기호는 임의의 1 개문자를 의미합니다. match: 는 패턴에서 문자열을 받을는 경우로 사용하며 문자열에 패턴을 보내는 상황에 사용되는건 아니라는걸 주의해 주세요.

'Linux *' match: 'Linux mag'        true
'GNU/Linux #ag' match: 'GNU/Linux tag'        true


다른 유용한 메서드로는 findString: 입니다.

'GNU/Linux mag' findString: 'Linux'                                                        5
'GNU/Linux mag' findString: 'linux' startingAt: 1 caseSensitive: false        5


Perl 수준의 좀더 진보된 패턴 매칭 도구도 사용이 가능합니다만, 표준 이미지에 포함되어 있지는 않습니다.[2]


String 에 대한 테스트.

아래의 예제들은 String 뿐만 아니라 다른 일반적인 컬렉션들에서도 정의되고있는 isEmpty, includes: 와 anySatisfy: 등의 메시지를 string 에 사용했을때의 동작을 보여줍니다.

'Hello' isEmpty        false
'Hello' includes: $a        false
'JOE' anySatisfy: [:c | c isLowercase]        false
'Joe' anySatisfy: [:c | c isLowercase]        true


String templating. String templating 을 관리하는데 유용한 format:, expandMacros 그리고 expandMacrosWith: 와 같은 3 개의 메시지들이 있습니다.

'{1} is {2}' format: {'Squeak' . 'cool'}        'Squeak is cool'


expandMacros 계열의 메시지들은 캐리지 리턴을 위해 <n> 을 사용한 변수 교체를 제공하며, 도표작성을 위해 <t> 를 반환하고 인수들을(<1p>, <2p>, 작은 따옴표로 문자열을 둘러싸서) 위해 <1s>, <2s>, <3s> 를 반환하고, 조건문을 위해 <1?value1:value2> 를 반환하는것등을 지원합니다.

'look-<t>-here' expandMacros                                        'look- -here'
'<1s> is <2s>' expandMacrosWith: 'Squeak' with: 'cool'        'Squeak is cool'
'<2s> is <1s>' expandMacrosWith: 'Squeak' with: 'cool'        'cool is Squeak'
'<1p> or <1s>' expandMacrosWith: 'Squeak' with: 'cool'        '''Squeak'' or Squeak '
'<1?Quentin:Thibaut> plays' expandMacrosWith: true        'Quentin plays'
'<1?Quentin:Thibaut> plays' expandMacrosWith: false        'Thibaut plays'


그외 유틸리티 메서드 String 클래스는 메시지 asLowercase, asUppercase 와 capitalized 를 포함한 여러 개의 다른 유틸리티를 제공합니다.

'XYZ' asLowercase        'xyz'
'xyz' asUppercase        'XYZ'
'hilaire' capitalized        'Hilaire'
'1.54' asNumber        1.54
'this sentence is without a doubt far too long' contractTo: 20        'this sent...toolong'


printString 메시지를 발송하여 객체에게 보유한 문자열 표현을 요청하는 작업과, asString 메시지를 이용해서 문자열로 변환하는 작업에는 일반적으로 차이점이 있다는 것에 주의하십시오. 여기에 그 차이에 대한 예제가 있습니다.

#ASymbol printString        '#ASymbol'
#ASymbol asString        'ASymbol'


Symbol 은 string 과 비슷하지만, global 에서 고유성 유지가 보장된다는것이 차이가 있습니다. 이러한 이유 때문에 Symbol 들은 특별히 IdentityDictionary 의 인스턴스인 경우, Dictionary 들을 위한 key 들로서 string 보다는 Symbol 을 더 선호하는 편입니다. string 과 symbol 에 관해 더 많은 내용을 원하신다면 8 장을 참고해주세요.


Notes

  1. 일본어버전의 Pharo by example 을 보면 같지 않은경우 에러가 발생한다고 되어 있습니다.
  2. 우리는 Vassili Bykov의 정규 표현식 패키지를 강력하게 추천합니다. 이 패키지는 http://www.squeaksource.com/Regex.html 에서 찾아보실 수 있습니다.