GNU Smalltalk

De Wiki Software Livre na Educação

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]

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

<source lang="smalltalk"> 'Hello World!' displayNl </source>

Alguns códigos Smalltalk básicos:

<source lang="smalltalk"> "Everything, including a literal, is an object, so this works:" -199 abs "199" 'gst is cool' size "11" 'Slick' indexOf: $c "4" 'Nice Day Isnt It?' asLowercase asSet asSortedCollection asString "' '?acdeinsty'" </source>

Coleções[editar]

Construir e usar uma matriz:

<source lang="smalltalk"> 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))" </source>

Construir e usar uma tabela de dispersão:

<source lang="smalltalk"> 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'" </source>

Blocos e iteradores[editar]

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

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

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

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:

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

Iterando sobre enumerações e matrizes usando blocos:

<source lang="smalltalk"> 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" </source>

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:

<source lang="smalltalk">

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

</source>

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:

<source lang="smalltalk"> (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." </source>

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

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

Classes[editar]

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:.

<source lang="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 </source>

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

<source lang="text"> OrderedCollection (Mark (63) Dan (23) Cod (16) ) </source>

Exceções[editar]

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:

<source lang="smalltalk"> Error signal Error signal: 'Argumentos ilegais!' </source>

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

<source lang="smalltalk"> [ Algo a fazer ]

   on: Exception
   do: [ :ex | handle exception in ex ]

</source>

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

<source lang="smalltalk"> [ something to do ]

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

</source>

É 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:

<source lang="smalltalk"> [ 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"

</source>

Ver também[editar]

Portal A Wikipédia possui o portal:
  • Software livre

Ligações externas[editar]