GNU Smalltalk

Origem: Wikipédia, a enciclopédia livre.
GNU Smalltalk
Versão estável 3.2.5 (11 abril 2013; 4048 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[editar | editar código-fonte]

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[editar | editar código-fonte]

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[editar | editar código-fonte]

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[editar | editar código-fonte]

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[editar | editar código-fonte]

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[editar | editar código-fonte]

Ligações externas[editar | editar código-fonte]