Instâncias
Doggie DaddyNo tutorial do ProfStef no IDE* há o seguinte (sem os comentários e a última expressão):
No tutorial do ProfStef online** a lição é diferente:
* https://amber-lang.net/learn.html
** DigiteProfStef go
e useDo it
para ter acesso ao tutorial.
Vamos usar os dois exemplos para começar a mostrar um pouco da estrutura de uma linguagem orientada a objetos, no caso específico o dialeto Pharo Smalltalk.
O Smalltalk e a quase totalidade dos ambientes que o implementam mostram que Smalltalk é uma linguagem que, dualmente, é também um ambiente de desenvolvimento.
Smalltalk deixa de fazer sentido como algo revolucionário, como considerado por alguns, se não for levado em conta o ambiente em que a linguagem, como sintaxe (que aliás não é nada extensa*), é aplicável.
* A sintaxe do Smalltalk cabe num cartão postal.
O cartão postal na imagem acima é uma reinterpretação, usando o Pharo Smalltalk, do famoso post card original do Smalltalk (Veja abaixo). Ele está ampliado com textos acizentados que descrevem os componentes do Pharo Smalltalk (que coincidem na quase totalidade com o Smalltalk ANSI).
Uma outra coisa digna de ser mencionada para mostrar a simplicidade do Smalltalk como linguagem é o fato de ela ter apenas seis palavras chaves reservadas (reserved keywords): true, false, nil, self, super e thisContext. Estas palavras chaves não podem ser usadas como nomes de variáveis e métodos.
Classes e instâncias
Vamos começar pela lição no tutorial ProfStef que está no IDE* (repetimos abaixo para sua conveniência).
* IDE:
Integrated Development System. É o ambiente integrado usado para o desenvolvimento dos programas.
No Smalltalk há uma convenção reforçada e adotada pelo ambiente na nomenclatura usada nas variáveis e objetos no uso de maiúsculas na primeira letra do identificador. Os identificadores começando com maiúsculas são identificadores* de objetos globais, que valem para todo o ambiente ou para toda uma classe. Os identificadores começando por minúsculas referem-se a objetos que são locais. Esta convenção é rigorosamente seguida pelos smalltalkers e se violada torna a leitura, que tenta obter de forma inspecional a semântica do código, mais difícil.
* Um identificador deve começar por uma letra seguida por letras ou números. O _ (sublinhado) é aceito como letra. Eles são case sensitive*, isto é, maiúsculas são diferentes de minúsculas.
A primeira linha contém vários elementos da convenção citada acima.
SimpleButtonMorph allInstances size.
SimpleButtonMorph
é global. Dentre os objetos globais e que em grande número já são preexistentes quando você carrega (abre) uma imagem estão as classes. Classes são objetos dentro da lógica de que quase tudo no Smalltalk é um objeto. SimpleButtonMorph
é uma classe.
allInstances
é local. allInstances
é o seletor de uma mensagem.
size
é local. size
é outro seletor.
SimpleButtonMorph allInstances size
é uma expressão envolvendo uma classe e duas mensagens. A narrativa para descrever a semântica da expressão é: "À classe SimpleButtonMorph
é enviada a mensagem allInstances
que retorna uma coleção de objetos *. Esta coleção de objetos recebe a mensagem size
que, por sua vez retorna outro objeto, no caso um número inteiro." Adiantamos, algo que você vai poder deduzir da documentação no futuro, que a expressão retorna a
quantidade de instâncias da classe SimpleButtonMorph
que existem no sistema no momento. Enviar a mensagem size
para a coleção faz com que você obtenha quantos objetos possui uma coleção.
* Não avalie uma expressãoAClass allInstances
usandoInspect it
pois pode incorrer num estouro de memória se houver muitos objetos na coleção. No caso acima não haverá problema pois a coleção tem poucos objetos.
Classe
Mas o que é uma instância de uma classe? Começamos a responder pela definição do que faz uma classe. Podemos dizer que a classe define como é a estrutura de um objeto que faz parte do conjunto de objetos criados a partir dessa classe. Além de definir como é a estrutura do objeto a classe também cria um objeto de sua classe.
A classe também define o comportamento das suas intâncias. Isto é, como as instâncias respondem às mensagens que recebe.
Instância
Instância é um objeto de uma classe que é criada pela classe e tem uma estrutura definida na classe. Uma instância de uma classe pode ser criada enviando a mensagem new
à classe, como em SimpleButtonMorph new
. A expressão SimpleButtonMorph new
retorna um objeto que é uma instância da classe SimpleButtonMorph
.
A segunda expressão
SimpleButtonMorph new label: 'A nice button'; openCenteredInWorld.
cria uma instância da classe SimpleButtonMorph
através da expressão SimpleButtonMorph new
. Ao objeto retornado (recém criado), são enviadas as mensagens label:
e openCenteredInWorld
. Note o ;
separando as mensagens. Conforme você aprendeu na lição Como funcionam as mensagens, nesse caso as mensagens serão enviadas ao objeto inicial e não ao objeto que é o resultado de cada mensagem.
Mas nada melhor do que a experimentação* para ver o que acontece.
* Antes de começar com a experimentação salve a imagem para poder retornar a ela caso aconteça alguma "bagunça".
Algumas das expressões abaixo podem remover algo da interface que você não saiba como repor.
Se acontecer basta fechar o ambiente sem salvar (IMPORTANTE!) e carregar de novo a imagem.
Aplique Do it
à expressão abaixo:
SimpleButtonMorph new label: 'A nice button'; openCenteredInWorld.
Deve obter algo similar ao que vê na figura abaixo:
O botão pode "desaparecer" caso você clique na janela do Playground. Quando você clica numa janela ela passa a ser exibida no topo e sobre o que estiver sendo exibido na mesma área ocupada pela janela. No caso o botão foi para "trás" da janela. Basta afastá-la da frente para que volte a ver o botão. Ou então clique no fundo da tela e use o botão direito para ver o World contents menu
. Selecione o objeto SimpleButtonMorph
para que o botão venha para "frente" de novo.
Evite avaliar a expressão que contém a mensagem new
novamente pois a cada avaliação vai criar um novo objeto.
Avalie SimpleButtonMorph allInstances size
com Print it
novamente para verificar que agora há mais uma instância de SimpleButtonMorph
.
Se houver mais de uma instância de SimpleButtonMorph você pode elminar o excedente com SimpleButtonMorph allInstances last delete.
que remove a última instância criada.
A próxima expressão
SimpleButtonMorph allInstances last label: 'ProfStef is cooooool !'; color: Color cyan.
na sua primeira linha envia a mensagem last
à coleção de instâncias de SimpleButtonMorph
que retorna o último objeto da coleção e que é o objeto que recém criamos. Então envia duas mensagens para esse objeto: label: 'ProfStef is cooooool !'
e color: Color cyan
que alteram a aparência do botão.
A próxima expressão SimpleButtonMorph allInstances last delete
remove o último objeto da coleção. O botão deve desaparecer da tela.
A expressão seguinte Smalltalk garbageCollect
aumenta a prioridade para a coleta de lixo *.
* Coletor de lixo (garbage collection) é o mecanismo do Smalltalk, que acontece "por trás dos panos" (no background), para recuperar o espaço na memória ocupado por objetos que não estão em uso.
Vamos passar a examinar a lição do ProfStef online. Abaixo repetimos a imagem que mostramos antes.
|anArray|
na primeira linha é uma declaração de variáveis. É desnessessária no Playground mas obrigatória em outros contextos.
A expressão
Array new add: 'Some text'; add: 3; yourself.
cria uma instância da classe Array
e envia três mensagens em cascata: add: 'Some text'
, add: 3;
e yourself
. Isto funciona no ProfStef online mas não no Pharo Smalltalk onde um objeto da classe Array
não responde a mensagens add:
. Para funcionar no Pharo Smalltalk precisamos trocar Array
por OrderedCollection
.
Veja como ficou abaixo.
O que vou dizer adiante pode ser facilmente constatado usando Inspect it
em qualquer parte realçada da mensagem. A mensagem add:
adiciona um objeto à coleção do tipo OrderedCollection
.
A expressão
OrderedCollection new add: 'Some text'; add: 3; yourself.
similar àquela que usava Array
, cria uma instância de OrderedCollection
e envia duas mensagens add:
e uma terceira yourself
para ela. Esta última mensagem é necessária por causa de uma sutileza em relação à implementação que responde à mensagem add:
e que é uma parte da tradição do Smalltalk que sempre retorna o objeto adicionado à coleção e não a coleção toda. A última mensagem yourself
é enviada à coleção (lembre-se que estamos usando ;
entre as mensagens o que caracteriza a cascata) e retorna o próprio objeto que foi receptor da mensagem, no caso toda a coleção.
A expressão seguinte
collection := OrderedCollection new add: 'Some text'; add: 3; yourself.
é semelhante exceto por guardar na variável collection
uma referência à coleção de objetos. Se você remover a última mensagem yourself
a variável collection
guadará somente um referência ao último objeto adicionado à coleção. A variável collection
será usada nas expressões seguintes.
Antes de executar a próxima expressão vamos abrir o Transcript
usando o World Menu
.
Posicione o Transcript
onde for mais conveniente.
Após executar o texto realçado com Do it
deve obter o que está mostrado no Transcript
.
Entenda o que ocorreu se preciso usando Inspect it
ou Print it
para avaliar trechos de expressões ou inspecionar variáveis.
Encerrando
Encerre a sessão salvando a imagem.