Estruturas de contrôle em Smalltalk

As três estruturas básicas de contrôle, repetição simples, seleção condicional, e repetição condicional são implementadas através do uso de blocos. Embora o efeito seja semelhante ao obtido por comandos tipo if-then-else, for e while em linguagens como Pascal, a implementação utiliza princípios próprios da programação orientada para objetos. As estruturas de controle em Smalltalk não tem uma sintaxe particular, e são implementadas através de mensagens com palavras-chave apropriadas, como será visto a seguir.


Seleção condicional - ifTrue:ifFalse:

É utilizada quando desejamos selecionar qual, entre duas sequências de expressões, será executada, dependendo de uma condição ser verdadeira ou falsa. Smalltalk provê uma mensagem especial para realizar esse tipo de seleção, que tem seletor ifTrue:ifFalse: e cujos argumentos são ambos da classe Bloco. Essa mensagem faz parte do protocolo da classe Boolean, cujas duas únicas instâncias são os objetos true e false.

Seja a mensagem: ifTrue: bloco1 ifFalse: bloco2 enviada tanto para true como para false, onde as variáveis bloco1 e bloco2 são blocos.

Quando o objeto true recebe essa mensagem, ele envia para o primeiro argumento (bloco1) a mensagem value, provocando a execução de suas expressões. Quando false recebe essa mensagem, ele envia a mensagem value para o segundo argumento, provocando a execução das expressões de bloco2. Isso é possível porque, graças ao mecanismo do polimorfismo, a mesma mensagem recebida por objetos de classes diferentes, pode provocar efeitos diferentes.

Esse mecanismo ilustra mais uma vez como o paradigma de objetos e mensagens é mantido uniformemente em todo o ambiente Smalltalk, mesmo para a implantação das estruturas básicas da linguagem.

Como exemplo, seja a expressão abaixo que atribui à variável paridade o valor 'par' ou 'impar' dependendo da paridade de outra variável numero:

(numero \\ 2) = 0 ifTrue: [
paridade := 'par'
] ifFalse:[
paridade := 'impar'
]

Nota: Números reagem à mensagem \\ respondendo com o valor de si mesmos módulo argumento. Note que os parênteses acima são desnecessários, pelas regras de precedência. O mesmo efeito da expressão acima pode ser obtido com a seguinte expressão:

paridade := numero \\ 2 = 0 ifTrue: ['par'] ifFalse: ['impar']

Quando só se deseja testar a veracidade ou a falsidade de uma condição, podem ser usadas as mensagens com um único argumento, ifTrue: ou ifFalse:.

A mensagem: ifTrue: bloco é equivalente à mensagem

ifTrue: bloco ifFalse: [ ]

Da mesma forma, a mensagem: ifFalse: bloco é equivalente à mensagem

ifTrue: [ ] ifFalse: bloco


Repetição simples - timesRepeat:

Para repetir um número determinado de vezes uma sequência de expressões, o mecanismo usado em Smalltalk consiste em enviar a um Inteiro, cujo valor é o número desejado de repetições, a mensagem timesRepeat:, onde o argumento é um bloco que contém a sequência de expressões a repetir.

Ao receber a mensagem, o Inteiro responde enviando ao bloco um número de mensagens value sucessivas igual ao seu próprio valor. Por exemplo, a expressão abaixo

3 timesRepeat: [n := n * n]

faz com que o valor de n seja elevado à quarta potência.


Repetição condicional - whileTrue: e whileFalse:

Smalltalk implementa a repetição condicional de um bloco de expressões através do envio da mensagem whileTrue: (ou whileFalse:) a outro bloco, cujo valor retornado deve ser um Booleano. O argumento da mensagem é o bloco que contém a sequência de expressões a serem repetidas.

Quando um bloco recebe a mensagem whileTrue:, ele envia a si mesmo a mensagem value. Caso a resposta seja true, ele envia a seguir a mensagem value ao bloco do argumento, e torna a enviar a si mesmo a mensagem value, reiniciando o ciclo. Caso a resposta seja false, o processo termina.

Por exemplo, para zerar todos os elementos de um Array de nome lista, pode ser usada a sequência abaixo:

i := 1.
[i <= lista size] whileTrue: [
lista at: i put: 0.
i := i + 1
]

A mensagem whileFalse: produz efeito inverso, fazendo com que as expressões do bloco argumento sejam repetidas enquanto o valor do receptor for igual a false.