GNU Smalltalk — это реализация языка программирования Smalltalk , разработанная проектом GNU Project .
Эта реализация, в отличие от других сред Smalltalk, использует текстовые файлы для ввода программы и интерпретирует их содержимое как код Smalltalk. Таким образом, GNU Smalltalk действует скорее как интерпретатор, а не как среда в традиционном стиле Smalltalk.
GNU Smalltalk включает привязки для многих библиотек бесплатного программного обеспечения, включая SQLite , libSDL , cairo , gettext и Expat .
Эти примеры работают только в GNU Smalltalk 3.0 и более поздних версиях. Классический пример Hello world :
'Привет, мир!' дисплейNl
Некоторый базовый код Smalltalk:
"Все, включая литерал, является объектом, поэтому это работает:" -199 abs "199" ' gst - это круто ' size "11" ' Slick ' indexOf: $c "4" ' Хороший день , не так ли ? ' asLowercase asSet asSortedCollection asString "'?acdeinsty"
Создание и использование массива :
а := #( 1 'привет' 3,14 1 2 ( 4 5 ))a at: 3 "3.14" обратный "((4 5) 2 1 3.14 'привет' 1)" a asSet "Set(1 'привет' 3.14 2 (4 5)) "
Создание и использование хеша :
хэш := Словарь из: { 'вода' -> 'мокрый' . 'огонь' -> 'горячий' } . хэш at: 'fire' "Печатает: горячий"хэш -ключиAndValuesDo: [ : k : v | ( '%1 — %2' % { k . v }) displayNl ]«Отпечатки: вода мокрая, огонь горячий»hash RemoveKey: 'water' "Удаляет "вода" -> "мокрый""
Передача параметров блока для замыкания :
«запомни блок». помните := [ : имя | ( 'Привет, %1!' % { name }) displayNl ] .«Когда придет время – объявите о закрытии!» запомнить значение: 'world' "=> 'Привет, мир!'"
Возврат замыканий из метода:
Целочисленное расширение [ asClosure [ | ценность | значение := сам . ^ { [ : х | значение := х ] . [ ценить ] } ] ] блоки := 10 asClosure . setter := сначала блокирует . getter := блокирует второй . значение получателя "=> 10" значение параметра : 21 "=> 21" значение получателя "=> 21"
Использование блока для отправки информации обратно вызывающему абоненту:
Целочисленное расширение [ ifEven: EvenBlock ifOdd: OddBlock [ ^ self Even ifTrue: [ значение EvenBlock : Self ] ifFalse: [ Значение OddBlock : Self ] ] ]
Вызовите вышеуказанный метод, передав ему блок:
10 ifEven: [ : n | n / 2 ] ifOdd: [ : n | n * 3 + 1 ] "=> 5"
Перебор перечислений и массивов с использованием блоков:
array := #( 1 'hi' 3.14 ) array do: [ : item | item displayNl ] "=> 1" "=> привет" "=> 3.14"( от 3 до: 6 ) сделайте: [ : элемент | item displayNl ] "=> 3" "=> 4" "=> 5" "=> 6"
Такой метод, как inject:into:, может принимать как параметр, так и блок. Он перебирает каждый член списка, выполняя некоторую функцию, сохраняя при этом совокупность. Это аналог функцииfoldl в функциональных языках программирования . Например:
#( 1 3 5 ) внедрить: 10 в: [ : сумма : элемент | сумма + элемент ] "=> 19"
При первом проходе блок получает 10 (аргумент для внедрения) в качестве суммы и 1 (первый элемент массива) в качестве элемента. Это возвращает 11. 11 затем становится суммой на следующем проходе, которая добавляется к 3 для получим 14. Затем к 5 прибавляется 14, и в итоге возвращается 19.
Блоки работают со многими встроенными методами:
( Имя файла : 'file.txt' ) withWriteStreamDo: [ : файл | file nextPutAll: 'Написал текст.' ; nl ] «Здесь файл автоматически закрывается»( Имя файла : 'file.txt' ) linesDo: [ : каждый | каждый дисплейNl ]"=> Написал текст."
Использование перечисления и блока для возведения в квадрат чисел от 1 до 10:
( от 1 до: 10 ) собрать: [ : x | x в квадрате ] "=> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]"
Следующий код определяет класс с именем Person. Будучи производным от величины, он автоматически определяет все методы сравнения, кроме одного ( <
). С добавлением этого asSortedCollection
можно сортировать по возрасту. Обратите внимание, что мы можем переопределить способ печати/отображения объекта (по умолчанию используется совместное представление для печати программиста и отображения пользователя), переопределив printOn:
.
Подкласс величины : Человек [ | имя возраст | Класс человека >> имя: имя возраст: возраст [ ^ само новое имя: имя ; возраст: возраст ; сам ] < aPerson [ ^ self age < aPerson age ] name [ ^ name ] name: value [ name := value ] age [ ^ age ] age: value [ age := value ] printOn: aStream [ aStream nextPutAll: ( '%1 ( %2)' % { имя.возраст } ) ]]группа := { Имя человека : 'Дэн' возраст: 23 . Имя человека : 'Марк' Возраст: 63 года . Имя человека : 'Треска' Возраст: 16 лет . }.группа asSortedCollection обратная
Приведенное выше выводит три имени в обратном порядке возраста:
OrderedCollection (Марк (63) Дэн (23) Треска (16))
Исключение вызывается вызовом halt
:
самостоятельная остановка
К исключению можно добавить необязательное сообщение; есть также error:
исключение другого типа:
самоостановка : «Это сообщение» самоошибка : «Это сообщение»
На самом деле это оболочки для фактического метода создания исключений signal
:
Сигнал ошибки Сигнал ошибки : «Недопустимые аргументы!»
Исключения обрабатываются on:do:
блоками.
[ что-то сделать ] on: Исключение do : [ : ex | обрабатывать исключение в ex ]
Конечно, вы можете перехватывать только отдельные исключения (и их подклассы):
[ что-то сделать ] on: Предупреждение сделать : [ : ex | обрабатывать исключение в ex ]
Можно использовать объект исключения, доступный для предложения обработчика, для выхода или возобновления первого блока; выход используется по умолчанию, но его также можно указать явно:
[ Сигнал ошибки : 'foo' ] on: Ошибка do: [ : ex | бывший возврат: 5 ]( Предупреждающий сигнал: 'что теперь?' ) printNl "=> nil"
[ ( Предупреждающий сигнал: 'что теперь?' ) printNl ] on: Предупреждение do: [ : ex | бывшее резюме: 5 ] "=> 5"