GNU Smalltalk
GNU Smalltalk | |
---|---|
Versão estável | 3.2.5 (11 abril 2013; 4179 dias) |
Gênero(s) | Linguagem de programação |
Licença | GPL + LGPL |
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
- Este artigo foi inicialmente traduzido, total ou parcialmente, do artigo da Wikipédia em inglês cujo título é «GNU Smalltalk», especificamente desta versão.