O GNU Smalltalk é uma implementação da linguagem de programação Smalltalk pelo Projeto GNU.

A implementação, ao contrário de outros ambientes Smalltalk, utiliza arquivos texto para entrada do programa e interpreta os conteúdos como código Smalltalk. Dessa forma, o GNU Smalltalk atua mais como um interpretador ao invés de um ambiente na forma tradicional do Smalltalk.

0 GNU Smalltalk inclui vinculação de nomes para muitas bibliotecas de software livre, incluindo SQLite, libSDL, cairo, gettext e Expat.

Exemplos

Estes exemplos funcionam apenas no GNU Smalltalk 3.0 e versões posteriores. Exemplo do clássico programa Olá Mundo:

'Hello World!' displayNl

Alguns códigos Smalltalk básicos:

"Everything, including a literal, is an object, so this works:" -199 abs "199" 'gst is cool' size "11" 'Slick' indexOf: $c "4" 'Nice Day Isn''t It?' asLowercase asSet asSortedCollection asString "' '?acdeinsty'"

Coleções

Construir e usar uma matriz:

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

Construir e usar uma tabela de dispersão:

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

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

"Prints: water is wet fire is hot"

hash removeKey: 'water' "Deletes 'water' -> 'wet'"

Blocos e iteradores

Passando um bloco como um parâmetro para que ele seja uma clausura:

"remember a block." remember := [ :name | ('Hello, %1!' % { name }) displayNl ].

"When the time is right -- call the closure!" remember value: 'world' "=> 'Hello, world!'"

Retornando as clausuras de um método:

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"

Usando blocos para enviar informações de volta ao chamador:

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

Invocar o método acima, passando-lhe um bloco:

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

Iterando sobre enumerações e matrizes usando blocos:

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"

Um método tal como inject:into: pode aceitar um parâmetro e um bloco. Ele itera sobre cada membro de uma lista, realizando alguma função enquanto retém um agregado. É análogo à função foldl em linguagens de programação funcional. Por exemplo:

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

No primeiro passo, o bloco recebe 10 (o argumento a injetar) como soma, e 1 (o primeiro elemento da matriz) como elemento. Isso retorna 11. 11, então, se torna a soma no próximo passo, no qual é adicionado 3 para obter 14. 14 é então adicionado a 5, para finalmente obter 19.

Blocos trabalham com muitos métodos embutidos:

(File name: 'file.txt') withWriteStreamDo: [ :file | file nextPutAll: 'Wrote some text.'; nl ] "File is automatically closed here"

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

"=> Wrote some text."

Utilizando uma enumeração e um bloco para elevar ao quadrado os números de 1 a 10:

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

Classes

O código a seguir define uma classe chamada Person. Por ser derivada de Magnitude, ela automaticamente define todos os métodos de comparação exceto um (<). Com a adição daquele, asSortedCollection pode ordenar por idade. Note que podemos sobrepor a forma com a qual o objeto é impresso ou exibido (o padrão é compartilhar a representação da impressão do programador e da tela do usuário) ao sobrepor printOn:.

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

O código acima imprime três nomes em ordem reversa de idade :

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

Exceções

Uma exceção é gerada com uma chamada halt:

self halt

Uma mensagem opcional pode ser adicionada à exceção; há também o error:, que gera um tipo diferente de exceção:

self halt: 'Isso é uma mensagem' self error: 'Isso é uma mensagem'

Existem atualmente invólucros para o método de geração da exceção atual, signal:

Error signal Error signal: 'Argumentos ilegais!'

As exceções são gerenciadas pelos blocos on:do:.

[ Algo a fazer ] on: Exception do: [ :ex | handle exception in ex ]

Você pode capturar apenas exceções particulares (e suas subclasses):

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

É possível usar o objeto Exceção, o qual é disponibilizado à cláusula do manipulador, para sair ou reiniciar o primeiro bloco. Sair é o padrão, mas também pode ser mencionado explicitamente:

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

Ver também

Smalltalk Projeto GNU

Ligações externas Projeto GNU Página oficial do GNU Smalltalk Pasta com o código fonte do GNU Smalltalk

Categoria:Programas de computador livres educativos Categoria:Linguagens de programação educacionais