GNU 스몰토크

**GNU 스몰토크**(GNU Smalltalk)는 GNU 프로젝트의 스몰토크 프로그래밍 언어 구현체이다.

다른 스몰토크 환경과 달리, 이 구현체는 텍스트 파일을 프로그램 입력으로 사용하고 내용을 스몰토크 코드로 해석한다. 이 방식은 GNU 스몰토크가 전통적인 스몰토크 방식의 환경이라기보다는 인터프리터처럼 작동하게 만든다.

GNU 스몰토크는 바인딩을 포함하며, SQLite, libSDL, 카이로, Gettext, Expat을 포함한 많은 자유 소프트웨어 라이브러리를 지원한다.

## 예시
이 예시들은 GNU 스몰토크 3.0 이상 버전에서만 작동한다. 고전적인 Hello world 예시:


```smalltalk
'Hello World!' displayNl
```


일부 기본적인 스몰토크 코드:


```smalltalk
"리터럴을 포함한 모든 것은 객체이므로 다음이 작동합니다:"
-199 abs                                                "199"
'gst is cool' size                                      "11"
'Slick' indexOf: $c                                      "4"
'Nice Day Isnt It?' asLowercase asSet asSortedCollection asString  "′?acdeinsty"
```


### 컬렉션
배열 구성 및 사용:


```smalltalk
a := #(1 'hi' 3.14 1 2 (4 5))

a at: 3        "3.14"
a reverse      "((4 5) 2 1 3.14 'hi' 1)"
a asSet        "Set(1 'hi' 3.14 2 (4 5))"
```


해시 구성 및 사용:


```smalltalk
hash := Dictionary from: { 'water' -> 'wet'. 'fire' -> 'hot' }.
hash at: 'fire'     "Prints:  hot"

hash keysAndValuesDo: [ :k :v |
        ('%1 is %2' % { k. v }) displayNl ]

"출력:  water is wet
          fire is hot"

hash removeKey: 'water'  "'water' -> 'wet' 삭제"
```


### 블록과 이터레이터
블록을 클로저로 매개변수 전달:


```smalltalk
"블록을 기억합니다."
remember := [ :name | ('Hello, %1!' % { name }) displayNl ].

"적절한 시기에 -- 클로저를 호출합니다!"
remember value: 'world'
"=> 'Hello, world!'"
```


메서드에서 클로저 반환:

```smalltalk
Integer extend [
     asClosure [
         | value |
         value := self.
         ^{ [ :x | value := x ]. [ value ] }
     ]
 ]

 blocks := 10 asClosure.
 setter := blocks first.
 getter := blocks second.
 getter value        "=> 10"
 setter value: 21    "=> 21"
 getter value        "=> 21"
```


블록을 사용하여 호출자에게 정보 다시 보내기:


```smalltalk
Integer extend [
     ifEven: evenBlock ifOdd: oddBlock [
         ^self even
             ifTrue: [ evenBlock value: self ]
             ifFalse: [ oddBlock value: self ]
     ]
 ]
```


위 메서드를 호출하고 블록을 전달:


```smalltalk
10 ifEven: [ :n | n / 2 ] ifOdd: [ :n | n * 3 + 1 ]    "=> 5"
```


블록을 사용하여 열거형 및 배열 반복:


```smalltalk
array := #(1 'hi' 3.14)
array do: [ :item | item displayNl ]
"=> 1"
"=> hi"
"=> 3.14"

(3 to: 6) do: [ :item | item displayNl ]
"=> 3"
"=> 4"
"=> 5"
"=> 6"
```


`inject:into:`와 같은 메서드는 매개변수와 블록을 모두 허용할 수 있다. 이 메서드는 목록의 각 멤버를 반복하며, 집계를 유지하면서 일부 함수를 수행한다. 이는 함수형 프로그래밍 언어의 foldl 함수와 유사하다. 예를 들어:


```smalltalk
#(1 3 5) inject: 10 into: [ :sum :element | sum + element ] "=> 19"
```


첫 번째 전달에서 블록은 10(inject에 대한 인수)을 sum으로, 1(배열의 첫 번째 요소)을 element로 받는다. 이는 11을 반환한다. 11은 다음 전달에서 sum이 되어 3과 더해져 14가 된다. 14는 다시 5와 더해져 최종적으로 19를 반환한다.

블록은 많은 내장 메서드와 함께 작동한다:


```smalltalk
(File name: 'file.txt') withWriteStreamDo: [ :file |
        file nextPutAll: 'Wrote some text.'; nl ]
"파일은 여기서 자동으로 닫힙니다."

(File name: 'file.txt') linesDo: [ :each |
        each displayNl ]

"=> Wrote some text."
```

열거와 블록을 사용하여 1부터 10까지의 숫자를 제곱하기:


```smalltalk
(1 to: 10) collect: [ :x | x squared ] "=> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]"
```


### 클래스

다음 코드는 Person이라는 클래스를 정의한다. Magnitude에서 상속받음으로써, 하나의 비교 메서드(`&lt;`)를 제외한 모든 비교 메서드가 자동으로 정의된다. 이 하나의 메서드를 추가하면 `asSortedCollection`이 나이순으로 정렬할 수 있다. 객체가 인쇄/표시되는 방식(기본값은 프로그래머 출력과 사용자 표시 표현을 공유함)을 `printOn:`을 오버라이드하여 재정의할 수 있음에 유의하라.


```smalltalk
Magnitude subclass: Person [
    | name age |
    Person class >> name: name age: age [
        ^self new name: name; age: age; yourself
   ]

    < aPerson [ ^self age < aPerson age ]
    name [ ^name ]
    name: value [ name := value ]
    age [ ^age ]
    age: value [ age := value ]
    printOn: aStream [ aStream nextPutAll: ('%1 (%2)' % { name. age }) ]
]

group := {
        Person name: 'Dan' age: 23.
        Person name: 'Mark' age: 63.
        Person name: 'Cod' age: 16.
}.

group asSortedCollection reverse
```


위 코드는 세 이름을 나이 역순으로 출력한다:

```output
OrderedCollection (Mark (63) Dan (23) Cod (16) )
```


### 예외
`halt` 호출로 예외가 발생한다:

```smalltalk
self halt
```

선택적으로 메시지를 예외에 추가할 수 있다; 다른 종류의 예외를 발생시키는 `error:`도 있다:

```smalltalk
self halt: 'This is a message'
self error: 'This is a message'
```

이것들은 실제 예외 발생 메서드인 `signal`의 래퍼이다:

```smalltalk
Error signal
Error signal: 'Illegal arguments!'
```


예외는 `on:do:` 블록으로 처리된다.


```smalltalk
[ something to do ]
    on: Exception
    do: [ :ex | handle exception in ex ]
```


물론 특정 예외(및 그 서브클래스)만 잡을 수 있다:


```smalltalk
[ something to do ]
    on: Warning
    do: [ :ex | handle exception in ex ]
```


핸들러 절에서 사용할 수 있는 예외 객체를 사용하여 첫 번째 블록을 종료하거나 재개할 수 있다; 종료는 기본값이지만 명시적으로 언급할 수도 있다:


```smalltalk
[ Error signal: 'foo' ]
    on: Error
    do: [ :ex | ex return: 5 ]

(Warning signal: 'now what?') printNl                       "=> nil"
[ (Warning signal: 'now what?')
        printNl ] on: Warning do: [ :ex | ex resume: 5 ]    "=> 5"
```


## 같이 보기
* 스몰토크
* GLASS (소프트웨어 묶음)

## 외부 링크
* 

분류:스크립트 언어
분류:GNU 프로젝트 소프트웨어
분류:스몰토크 프로그래밍 언어 계열
분류:자유 교육용 소프트웨어