**GNU Smalltalk**是Smalltalk编程语言的GNU计划实现。

这个实现不同于其他Smalltalk环境，使用文本文件作为程序输入，并将其内容解释为Smalltalk代码。在这种方式下，GNU Smalltalk表现得更像是一种解释器，而非传统Smalltalk方式下的一种环境。GNU Smalltalk包括了对很多自由软件库的绑定，包括SQLite、libSDL、cairo、gettext和Expat（英语：）等。

简单例子
----

下面的例子可工作在GNU Smalltalk 3.0和以后版本上。经典的Hello, World!例子：

```
'Hello, World!' displayNl

```

GNU Smalltalk声明了三个文件：`stdin`、`stdout`和`stderr`，作为文件串流类（`FileStream`）的全局实例，并绑定了适合传递给C虚拟机的值。对象类（`Object`）定义了特有于GNU Smalltalk的四个方法：`print`、`printNl`、`store`和`storeNl`。它们对接收者做一次`printOn:`或`storeOn:`至`Transcript`对象。这个对象是文本搜集器类（`TextCollector`）的唯一实例，它通常将写操作委托给`stdout`。 

一些基本的Smalltalk代码：

```
"所有东西，包括一个文字，都是一个对象，所以如下可行:"
-199 abs.                                               "199"
'gst is cool' size.                                     "11"
'Slick' indexOf: $c.                                    "4"
'Nice Day Isn''t It?' asLowercase asSet asSortedCollection asString "' ''?acdeinsty'"

```

两个`"`包围的是注释；`$c`是字符常量`c`；两个`'`包围的是字符串，字符串中的`''`是`'`的转义序列。

搜集
--

构造和使用一个数组：

```
a := #(1 'hi' 3.14e0 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))"

```

构造和使用一个散列表，它是散列搜集类（`HashedCollection`）的子类即字典类（`Dictionary`）的实例：

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

hash keysAndValuesDo:
       [ :k :v | ('%1 is %2' % { k. v }) displayNl ].
"=> fire is hot
 => water is wet"

"删除 'water' -> 'wet'"
hash removeKey: 'water'

```

GNU Smalltalk在字符串类（`String`），和作为它的超类的数组式搜集类（`ArrayedCollection`）之间，又介入了特有的字符数组类（`CharacterArray`），它的`%`方法，将其接收者中具有的特殊转义序列，替换为由参数给出的搜集中的元素，其中`%n`被替代为这个搜集的第`n`个元素（`1 <= n <= 9`或`A <= n <= Z`）。这里给它的搜集，是在`{`和`}`之间包围的，当前Smalltalk变体一般都提供的动态数组，其中的元素可以在运行时间求值。

块和迭代器
-----

参数传递到是为闭包的一个块：

```
"remember被绑定到一个块."
remember := [ :name | ('Hello, %1!' % { name }) displayNl ].

"时机成熟时 -- 调用这个闭包!"
remember value: 'world'
"=> Hello, world!"

```

从一个方法返回由两个闭包构成的一个数组：

```
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"

```

这里用`extend`为现存的类扩展新方法是GNU Smalltalk特有的语法。

下面的考拉兹猜想例子，展示将两个块传递给接收者，并将结果信息发送回到调用者：

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

10 ifEven: [ :n | n / 2 ] ifOdd: [ :n | n \* 3 + 1 ]    "5"

```

搜集类（`Collection`）的`collect:`方法，将接收者的每个元素传递给一个块来求值，返回这些结果的搜集。这类似于函数式编程语言中map函数。例如计算从`1`到`10`的平方：

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

```

可迭代类（`Iterable`）定义了由子类实现的`do:`方法，将一个块迭代于接收者的每个元素之上。这也被称为隐式迭代器。例如迭代于数组和区间之上：

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

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

```

可迭代类的`inject:into:`方法，接受一个参数和一个块二者；它迭代于接收者的每个元素之上，在其上执行某个函数并保持结果为一个聚集。这类似于函数式编程语言中foldl函数。这个方法是凭借调用`do:`方法实现的。例如：

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

```

在第一个趟时，这个块接受`10`（要注入的实际参数）作为`sum` ，和`1`（这个数组的第一个元素）作为元素，结果为`11`。`11`接着成为在下一趟时的`sum`，这时向它加上`3`得到`14`。`14`接着加上`5`，最终返回`19`。

块可以和很多内建方法一起工作，下面例子向一个文件写一行文本，然后再读取它的每一行并显示：

```
(File name: 'file.txt') withWriteStreamDo:
    [ :file | file nextPutAll: 'Wrote some text.'; nl ]

(File name: 'file.txt') readStream linesDo:
    [ :each | each displayNl ] ; close
"=> Wrote some text."

```

文件类（`File`）的特有于GNU Smalltalk的`name:`方法，返回具有绝对路径的文件名。GNU Smalltalk有特有的文件路径类（`FilePath`），它的`withWriteStreamDo:`方法，对接收者调用`writeStream`方法打开一个只写的文件串流类（`FileStream`）实例，在其上调用一个块，并在这个块的动态范围结束处保证（`ensure:`）关闭这个串流；它的`readStream`方法，在接收者上打开一个只读的文件串流类（`FileStream`）实例。

串流类（`Stream`）的特有于GNU Smalltalk的`linesDo:`方法，对它的接收者的每一行都求值它的参数块一次。 在GNU Smalltalk中，文件串流类（`FileStream`）的超类，不再是作为可定位串流类（`PositionableStream`）子类的读写串流类（`ReadWriteStream`），而是其特有的作为串流类（`Stream`）子类的文件描述符类（`FileDescriptor`），它的`close`方法关闭这个文件。

类
-

GNU Smalltalk建立新类采用特有的语法形式：

```
超类名字 subclass: 新类名字 [
    | 诸实例变量 |
    pragmas
    消息模式1 [ 诸语句 ]
    消息模式2 [ 诸语句 ]
    ...
    类变量1 := 表达式.
    类变量2 := 表达式.
    ...
]

```

类似的，为现存的类扩展新方法采用特有的语法形式：

```
类表达式 extend [
    ...
]

```

在Smalltalk有关书籍中有一个常见版式约定，将一个类中的方法引用为`类名字 >> 方法名字`，这不是Squeak/Pharo语法的一部份，GNU Smalltalk将`类名字 class >> 方法名字`作为定义类方法的语法形式。

下面的代码定义叫做`Person`的一个类，这个类有两个实例变量`name`和`age`，它们有各自的变异子与访问子。定义了有两个关键字参数的类方法，用来创建新的类实例。定义了单独用`age`来进行比较的`<`方法，通过从`Magnitude`派生，这个类自动继承了所有的其他比较方法的定义。这个类还通过覆写`printOn:`的方式，定制了这个对象的打印（`print`）/显示（`display`）方式：

```
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

```

这里用`asSortedCollection`方法对搜集进行排序，然后用`reverse`方法来做反转。最终结果是按`age`反序打印了三个人的信息：

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

```

异常
--

要发起能够捕获的异常，需要调用异常类（`Exception`）及其子类的`signal`或`signal:`方法。错误类（`Error`）表示不可恢复的致命错误，警告类（`Warning`）表示重要但可恢复的错误，停机类（`Halt`）表示通常是漏洞（bug）的可恢复错误。例如：

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

```

异常通过块闭包（`BlockClosure`）的`on:do:`方法来处理，还可以只捕获特定的异常（和它们的子类）：

```
[ 做些事情
] on: Exception do: [ :ex |
    处理ex中异常
]

[ 做些事情
] on: Warning do: [ :ex |
    处理ex中异常
]

```

处理器子句使用它能获得的异常对象，可以退出或恢复一个块；退出是缺省的，但也可以显式的指示：

```
[ 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"

```

在因异常状况而要进入调试器，可以调用对象类（`Object`）的`halt`方法，或增加了一个消息参数的`halt:`方法；这二者实际上调用了对象类的`error:`方法，它通过原始操作停止执行及或（英语：）启动调试器，并展示这个错误消息：

```
self halt. "halt encountered"
self halt: 'This is a message'.
self error: 'This is a message'

```

参见
--

* Ruby语法（英语：）
* GLASS

引用
--

1. ↑ .  [2022-02-10]. （原始内容存档于2022-03-18）.
2. ↑  .
3. ↑ .  [2022-02-09]. （原始内容存档于2022-02-18）. The GNU Smalltalk regular expression library is derived from GNU libc, with modifications made originally for Ruby to support Perl-like syntax.
4. ↑ .  [2022-02-09]. （原始内容存档于2022-02-18）.
5. ↑ .  [2022-02-09]. （原始内容存档于2022-04-06）.
6. ↑ .  [2022-02-09]. （原始内容存档于2022-02-18）.

外部链接
----

* 官方网站

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
Smalltalk编程语言 |
| --- |
|  |
| 实现（英语：） | 

|  |  |
| --- | --- |
| 主要 | 
* Amber（英语：）
* Dolphin Smalltalk（英语：）
* GemStone/S（英语：）
* GNU Smalltalk
* Pharo
* Smalltalk/X
* Squeak
* VisualAge Smalltalk（英语：）
* VisualWorks（英语：）

 |
|  |
| 方言 | 
* F-Script（英语：）
* Little Smalltalk（英语：）
* Newspeak（英语：）
* Pocket Smalltalk（英语：）
* Self
* StepTalk（英语：）
* Strongtalk（英语：）

 |

 |
|  |
| 软件 | 
* AIDA/Web（英语：）
* Croquet OS
* GemStone/S（英语：）
* Open Cobalt（英语：）
* Seaside（英语：）

 |
|  |
| 工作站 | Xerox Alto |
|  |
| 社群 | 

|  |  |
| --- | --- |
| 人 | 
* Lars Bak（英语：）
* Gilad Bracha（英语：）
* 彼得·多伊奇
* Adele Goldberg（英语：）
* 乌尔斯·霍泽尔
* Dan Ingalls（英语：）
* Ted Kaehler（英语：）
* 艾伦·凯
* Julian Lombardi（英语：）
* 馬克·麥卡希爾
* Diana Merry（英语：）
* David P. Reed（英语：）
* David A. Smith（英语：）
* 拉里·泰斯勒
* Scott Wallace

 |
|  |
| 开发商 | 
* Cincom Systems（英语：）
* Gemstone（英语：）
* IBM
* Object Arts
* Xerox PARC

 |

 |

 |

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
GTK+应用 |
| --- |
|  |
| Platform | 

|  |  |
| --- | --- |
| GTK+ | 
* GTK+
	+ GDK
	+ ATK
	+ ClutterActor
	+ GTK+ Scene Graph Kit
	+ Pango
	+ Language bindings
		- PyGTK
		- PyGObject
* GLib
	+ GObject
	+ GIO
* IBus
* Orca
* dconf
* Genie
* Vala
* Keyring
* GNOME-DB
* GVfs
* Hildon
* Librsvg
* MetaTracker
* libxslt
* libxml2

 |
|  |
| freedesktop.org(shared) | 
* AppStream
* D-Bus
* GStreamer
* NetworkManager
* Poppler
* libcanberra
* Wayland
* X.Org Server
* PulseAudio
* PackageKit
* HarfBuzz
* Cairo

 |
|  |
| Development | 

|  |  |
| --- | --- |
| GUI designer, RAD | 
* Glade Interface Designer
* GNOME Builder

 |
|  |
| IDEs | 
* Anjuta
* Builder
* Bluefish
* Meld
* Devhelp
* Nemiver
* Poedit
* Geany
* Gtranslator
* gPHPedit
* PyRoom
* SciTE
* UberWriter
* PIDA

 |

 |

 |  |
|  |
| GNOME | 
* GNOME Shell
* GNOME Games
* Core Applications
	+ Boxes
	+ Calculator
	+ Character Map
	+ Dictionary
	+ Disks
	+ Files
	+ Software
	+ Terminal
	+ Videos
	+ Web
* Other
	+ dconf editor

 |
|  |
| Cinnamon | 
* Nemo

 |
|  |
| Xfce | 
* Thunar

 |
|  |
| LXDE | 
* PCMan File Manager
* LXMusic

 |
|  |
| Graphical shells | 
* GNOME Panel
* Docky
* GNOME Do
* Avant Window Navigator

 |
|  |
| 3rd-partyapplications | 

|  |  |
| --- | --- |
| Office | 
* AbiWord
* Dia
* Gnumeric
* Evince (pdf)
* Evolution
* Dictionary
* OCRFeeder

 |
|  |
| Education | 
* Gramps
* GCompris
* DrGeo
* GeoGebra
* Ghemical
* Celestia
* Wine-Doors

 |
|  |
| Graphics | 
* GIMP
* GNU Paint
* Inkscape
* gThumb
* gPhoto
* Eye of GNOME
* Sushi
* Shotwell
* F-Spot

 |
|  |
| Internet | 
* Balsa
* Sylpheed
* Claws Mail
* Empathy
* Ekiga
* gtk-gnutella
* GpsDrive
* GNU Ring
* Vino (VNC server)
* Vinagre
* Midori
* Uzbl
* transmission-gtk

 |
|  |
| Audio | 
* Audacious
* Banshee
* Buzztrax
* Exaile
* Rhythmbox
* Sound Juicer
* SoundConverter
* Quod Libet
	+ Ex Falso
* EasyTag
* Asunder

 |
|  |
| Video | 
* Avidemux
* Cinelerra
* Kino
* LiVES
* OpenShot Video Editor
* Pitivi
* Gnome MPlayer
* Cheese

 |
|  |
| Utilities | 
* Archive Manager
* Brasero
* dconf-editor
* Diodon
* gedit
* gnote
* Screenshot
* GParted
* Guake
* Leafpad
* Tilda
* Tomboy
* Workrave

 |

 |
|  |
| 
* 分类 Category:GTK+
* 分类 Category:Software that uses GTK+
* 共享资源页面 Commons

 |

 |

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
GNU计划 |
| --- |
|  |
| 历史 | 
* GNU宣言
* 自由软件基金会
	+ 欧洲（英语：）
	+ 印度（英语：）
	+ 拉丁美洲（英语：）
* 自由开源软件历史

 | GNU's not UNIX |
|  |
|  | 
* GNU通用
* GNU
* GNU Affero通用
* GNU
* GPL

 |
|  |
| 软件 | 
* GNU
	+ 变种
* Hurd
* Linux-libre
* glibc
* Bash
* Coreutils
* findutils
* 构建系统
* GCC
* binutils
* GDB
* GRUB
* GNOME
* GNUstep
* GIMP
* Jami
* GNU Emacs
* GNU TeXmacs
* GNU Octave
* GNU R
* GSL
* GMP
* GNU Electric（英语：）
* GNU Archimedes（英语：）
* GNUnet（英语：）
* GNU Privacy Guard
* Gnuzilla
	+ IceCat
* GNU Health
* GNUmed
* GNU LilyPond
* GNU Go
* GNU Chess
* Gnash
* Guix
* Guix系統發行版（英语：）
* *更多...*

 |
|  |
| 公众发言人 | 
* Alexandre Oliva
* Benjamin Mako Hill
* Bradley M. Kuhn
* 伊本·莫格林
* Georg C. F. Greve
* Loïc Dachary
* Ricardo Galli
* 理查德·斯托曼
* Robert J. Chassell
* John Sullivan

 |
|  |
| 其它议题 | 
* GNU/Linux命名爭議
* 《操作系统革命》
* 自由软件基金会反Windows运动
* 设计式缺陷

 |

 |