GNU Smalltalk
GNU Smalltalk是Smalltalk编程语言的GNU计划实现。 这个实现不同于其他Smalltalk环境,使用文本文件作为程序输入,并将其内容解释为Smalltalk代码[5]。在这种方式下,GNU Smalltalk表现得更像是一种解释器,而非传统Smalltalk方式下的一种环境[6]。GNU Smalltalk包括了对很多自由软件库的绑定,包括SQLite、libSDL、cairo、gettext和Expat等[7]。 简单例子下面的例子可工作在GNU Smalltalk 3.0和以后版本上。经典的Hello, World!例子: 'Hello, World!' displayNl
GNU Smalltalk声明了三个文件: 一些基本的Smalltalk代码: "所有东西,包括一个文字,都是一个对象,所以如下可行:"
-199 abs. "199"
'gst is cool' size. "11"
'Slick' indexOf: $c. "4"
'Nice Day Isn''t It?' asLowercase asSet asSortedCollection asString "' ''?acdeinsty'"
两个 搜集构造和使用一个数组: 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))"
构造和使用一个散列表,它是散列搜集类( 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在字符串类( 块和迭代器参数传递到是为闭包的一个块: "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"
这里用 下面的考拉兹猜想例子,展示将两个块传递给接收者,并将结果信息发送回到调用者: 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"
搜集类( (1 to: 10) collect: [ :x | x squared ] "(1 4 9 16 25 36 49 64 81 100 )"
可迭代类( 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"
可迭代类的 #(1 3 5) inject: 10 into: [ :sum :element | sum + element ] "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."
文件类( 串流类( 类GNU Smalltalk建立新类采用特有的语法形式: 超类名字 subclass: 新类名字 [
| 诸实例变量 |
pragmas
消息模式1 [ 诸语句 ]
消息模式2 [ 诸语句 ]
...
类变量1 := 表达式.
类变量2 := 表达式.
...
]
类似的,为现存的类扩展新方法采用特有的语法形式: 类表达式 extend [
...
]
在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
这里用 OrderedCollection (Mark (63) Dan (23) Cod (16) )
异常要发起能够捕获的异常,需要调用异常类( Error signal.
Error signal: 'Illegal arguments!'
异常通过块闭包( [ 做些事情
] 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"
在因异常状况而要进入调试器,可以调用对象类( self halt. "halt encountered"
self halt: 'This is a message'.
self error: 'This is a message'
参见引用
外部链接 |