Escolar Documentos
Profissional Documentos
Cultura Documentos
net/publication/262882317
CITATIONS READS
0 2,153
2 authors:
Some of the authors of this publication are also working on these related projects:
All content following this page was uploaded by Aldo Von Wangenheim on 06 June 2014.
6PDOOWDON&RPSOHWR
9HUVmR
5HYLVmR$OGR
Capítulo 1 Por Quê Smalltalk ? . . . . . . . . . . . . . . . . . . . . . . . . . 15
Orientação a Objetos e Smalltalk 16
O quê é este livro ? 19
Para quem é este livro ? 19
Temas abordados no livro 20
Capítulo 2 Histórico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
As origens 23
O grupo de pesquisas da Xerox em Palo Alto 24
Bytecodes e JAVA 26
Adele Goldberg e seu livro 27
Smalltalk IBM 28
Smalltalk para Linux 29
Aplicações comerciais e projetos 29
Smalltalk Completo
Arquivos com a Documentação do Smalltalk 33 Convertendo Smalltalk para C++ 71
Manuais contidos no diretório doc 34 Help do VisualWorks 72
Instalando o VIsualWorks em sua máquina 37 Gerenciando o Arquivo de Alterações 73
Iniciando e finalizando uma seção 39 Restaurando código e instâncias após a queda do sistema 73
Os principais arquivos do sistema 43 Exercícios 75
Visual Laucher 44
Browsers 45 Capítulo 4 Conceitos Básicos da Linguagem . . . . . . . . . . . . . . 77
Procurando por uma classe ? 47
Adicionando uma nova categoria 49
Orientação a Objetos 77
Classes x instâncias 78
Adicionando um novo protocolo de métodos 50
Template para a criação de classes 50 Classes 79
Instâncias 81
Template para a criação de métodos 52
Listando os métodos 52 Mecanismo de Herança e Hierarquia de Classes 82
Expandindo a hierarquia de classes 53 Polimorfismo 83
Workspace 53 Métodos, mensagens e variáveis 84
Executando código 55 Características da Linguagem 84
Resource Finder 58 Características funcionais 85
UIPainter 59 Características léxicas 86
Canvas Tool 60 Filosofia de programação 87
Palette 61 Navegar 89
Canvas 61 Editar/Criar 89
Properties 61 Inspecionar 89
Settings & VisualWorks Settings Home 62 Objetos especiais - Literais 90
Coletando o Lixo 64 Números 91
Carregando e Salvando Código Fonte 64 SmallInteger, LargePositive-Integer e LargeNegativeInteger 91
Mecanismo de fileIn/fileOut 65 Float e Double 92
Salvando em XML ou em texto chunk 65 Fraction 93
Números em outras bases 93
Geração de Pacotes de Programa: Parcels 66
Exponen-ciação 94
Código fonte e código executável 66
Adicionando um novo parcel à sua imagem 67
Caracteres 95
Removendo um parcel 68 Strings 95
Criando seu próprio parcel 68 Booleanos 95
Alguns parcels comumente utilizados 70 O Objeto Indefinido nil 96
Código Executável 71 Símbolos 96
Criando aplicativos .exe 71 Arrays 97
gramação comercialmente aplicada realmente orientada a objetos, pois é adaptaram alguns dos conceitos existentes na orientação a objetos para
a única que de fato implementa de forma consistente todos os aspectos da expandir as suas capacidades. As duas linguagens sobreviventes dessa
teoria da orientação a objetos. Nós vamos ver adiante que esta afirmativa explosão-OO do final da década de 80, C++ (o “C”-orientado a objetos que
vai muito além de ter conseqüências meramente acadêmicas. Vale dizer se consolidou) e DELPHI (o PASCAL orientado a objetos que conquistou o
agora que este fato torna Smalltalk a linguagem de programação para mercado) são linguagens modulares que incorporaram alguns conceitos
ensino de computação por excelência e, de longe, a melhor linguagem de orientação a objetos. Elas não são linguagens de programação orienta-
para o primeiro contato do aluno com a arte de programar, pela forma intui- das a objetos. O objetivo desta apologia de Smalltalk é, por um lado, o de
tiva com que trata a modelagem do mundo real sob a forma de programas quebrar alguns preconceitos que existem acerca de Smalltalk ser uma lin-
de computador. guagem “de brinquedo”, por outro lado, de elevar as expectativas do usuá-
A segunda resposta é que todos os impedimentos que havia para rio, reduzidas pelas capacidades limitadas das implementações de
que Smalltalk se tornasse uma linguagem de programação amplamente orientação a objetos mais comuns do mercado.
utilizada na indústria e em softwares comerciais 20 anos atrás deixaram de Como foi dito anteriormente, Smalltalk é mais que a linguagem de
existir. Hoje em dia, um computador com muita memória, um processador programação orientada a objetos por excelência. A euforia orientada a
razoável e um monitor grande e com boa resolução gráfica viraram lugares objetos que citamos anteriormente, foi na realidade desencadeada pelo
comuns e não há mais impedimentos tecnológicos ao desenvolvimento de fato de, em 1980, o Centro de Pesquisas de Palo Alto, PARC, da XEROX
software aplicativo comercial em Smalltalk. Isto tem se traduzido em um ter anunciado e demonstrado uma linguagem orientada a objetos. Esta lin-
interesse crescente, principalmente por parte da indústria e de bancos, no guagem, produto de um projeto denominado Dynabook, chamava-se
desenvolvimento de software em Smalltalk. Este interesse vem crescendo Smalltalk. Smalltalk foi o produto de longas e minunciosas pesquisas e foi
em ritmo constante desde meados da década de 90, devido tanto à facili- desenvolvido juntamente com o próprio conceito de orientação a objetos:
dade e rapidez de modelagem de processos complexos oferecida por ambos evoluíram em conjunto. Detalhes dessa evolução estão descritos
Smalltalk, como pela sua facilidade de adaptação de programas a requisi- no Capítulo 2 deste livro. O que importa no momento, é que Smalltalk
tos em constante mutação. implementou todos os conceitos de OO, desde aspectos bastante comple-
xos até coisas básicas como modelar internamente tudo como objeto,
Orientação a Quando o paradigma de Orientação a Objetos começou a se inclusive coisas básicas como números inteiros, que também são objetos,
Objetos e popularizar, no final da década de 80, houve uma grande pressão por parte também são subclasses de uma classe abstrata Object e podem ter seu
Smalltalk do mercado para o surgimento de linguagens de programação que incor- comportamento alterado pelo usuário. Em C++ ou em Delphi, inteiro, byte,
porassem as facilidades de intuitividade de modelagem, polimorfismo, reu- float são tipos de dados e não objetos e não possuem comportamento,
tilizabilidade de código e suporte à prototipagem prometidas pelo novo mas sim operações e também não possuem objeto-pai. Em Smalltalk, a
paradigma. Nessa euforia orientada a objetos surgiram uma infinidade de superclasse de Integer é Magnitude, uma classe abstrata que imple-
linguagens de programação prometendo a “melhor orientação a objetos”. menta vários comportamentos de grandezas numéricas em geral. Em
Dentre estas, só para listar algumas, podemos citar: vários PASCAis orien- Smalltalk você não “chama uma função ou procedure”, mas realmente
tados a objetos, vários “C”s orientados a objetos, LISP orientado a objetos envia uma mensagem a um objeto.
(CLOS), MODULA orientado a objetos (OBERON) e muitos outros. Com Para citar outro exemplo, em Smalltalk o tão falado polimorfismo
poucas exceções de interesse meramente acadêmico (OBERON e não é um conceito bonito mas sem utilidade, mas realmente funciona e
EIFFEL), todas essas linguagens na realidade de uma forma ou de outra
permite a você você criar vários objetos diferentes, mas que possuem Este é um livro sobre a linguagem orientada a objetos Smalltalk, O quê é este
métodos com o mesmo nome. Estes objetos realmente vão se comportar técnicas de programação em Smalltalk, metodologia de modelagem orien- livro ?
de forma diferente dependendo para qual deles uma mensagem é envi- tada a objetos visando a geração de programas em Smalltalk e um guia de
ada. Tente fazer isto em C++. A não ser que você queira chamar a técnica programação para vários tipos de aplicações usando Smalltalk, desde apli-
de usar ponteiros para funções1 de polimorfismo, isto é completamente cações gráficas e de Inteligência Artificial até aplicações cliente-servidor
impossível. Em Smalltalk é parte integrante da boa técnica de programa- na Internet.
ção fazer uso do polimorfismo para dar flexibilidade e adaptabilidade a O livro é ao mesmo tempo um guia de referência da linguagem
seus programas. Para ilustrar, no final do Capítulo 2 deste livro nós vamos Smalltalk, onde o programador pode consultar aspectos específicos da lin-
abordar várias aplicações comerciais e científicas de Smalltalk na atuali- guagem, como também um guia de programação, onde o programador
dade e relatar uma experiência de sucesso de migração de um ambiente pode consultar técnicas de programação e formas de resolver seus proble-
de programação em mainframes para Smalltalk de uma grande empresa mas específicos, com processos, arquivos e interfaces gráficas.
européia.
Neste livro são abordadas todos os conceitos básicos da lingua-
Com o surgimento de JAVA esta constelação foi finalmente modifi- gem, como sintaxe, tipos de variáveis, tipos de métodos e mensagens e
cada. JAVA pode também ser considerada uma linguagem verdadeira- como criar uma classe de objetos.
mente orientada a objetos, apesar de manter alguns conceitos de C++,
como o fato de que existem tipos primitivos de dados que não são objetos Neste livro também abordamos as principais técnicas avançadas
e de não existir uma classe pai de todas as classes. JAVA realmente imple- de programação Smalltalk e descrevemos as bibliotecas de classes que
menta o polimorfismo e uma grande flexibilidade na utilização da memória, podem ser usadas em cada caso, mostrando exemplo de aplicação práti-
através do uso de coletores de lixo, da mesma forma que em Smalltalk. O cos.
conceito básico de construção de interfaces gráficas de usuário também
segue o paradigma MVC, criado por Smalltalk. Para tonar JAVA palatável Este livro foi concebido para ser tanto um livro para o ensino da Para quem é
ao grande número de desenvolvedores de C++, principalmente europeus, programação em Smalltalk como um livro de consulta e referência. Por este livro ?
a Sun decidiu criar a linguagem com base na sintaxe do C++. Esta escolha isso, este é tanto um livro para ser usado como livro texto em um curso de
é, na nossa opinião, o maior ponto negativo de JAVA em relação a Small- programação orientada a objetos, como também um livro para ser usado
talk: o código simples e intuitivo que se poderia ter definido para uma lin- por muito tempo como manual de referência de técnicas de programação
guagem orientada a objetos foi deixado de lado em favor de na definição orientada a objetos.
de sintaxe baseada em modelos da década de 60 usada por C++. Com o O livro foi concebido para poder ser utilizado como livro texto em
atual crescimento da bases de bibliotecas de classes para diversas aplica- uma disciplina de programação de primeiro ou segundo semestre. Pode
ções de JAVA, a vantagem de 20 anos de desenvolvimento de classes de também, acompanhado de um livro de modelagem orientada a objetos, ser
Smalltalk tem se reduzido e, para o desenvolvimento de aplicações comer- um livro texto de uma disciplina de Projeto Orientado a Objetos de um
ciais, JAVA é hoje uma opção à altura. Para o ensino de programação, segundo ou tercerio semestres.
porém, Smalltalk continua sendo a opção por excelência.
Para a alunos de primeira e segunda fases de um curso de Ciên-
cias da Computação ou Sistemas de Informação, este é um livro que vai
1. Técnica que na verdade já era usada por ANSI “C” antes de surgir o C++
servir de base para o aprendizado de programação e acompanhar as suas No Capítulo 9 abordamos a teoria e a prática de um aspecto espe-
atividades de programação por muitos anos. cífico das linguagens orientadas a objetos: a mecanismo de dependência.
Para o autodidata em programação orientada a objetos ou para Esta técnica permite que se crie objetos que reajam automaticamente a
aquele que está migrando de outra área, este livro não somente serve modificações sofridas por outros.
como tutorial de Smalltalk, pois está organizado em capítulos abordando Nos capítulos 10 e 11 abordamos as técnicas que você precisa
temas encadeados e possui listas de exercícios no final dos capítulos prin- para implementar a concorrência em Smalltalk: processos, semáforos e
cipais, mas também vai servir como manual de bom estilo de programa- controle de exceções. Smalltalk permite que se crie processos indepen-
ção. Em todos os capítulos abordamos o melhor estilo de se realizar a dentes, possibilitando a uma aplicação executar várias coisas ao mesmo
modelagem e a programação dos problemas relacionados àquele assunto. tempo. Nestes capítulos vamos tratar da teoria e prática desse assunto.
Isto não é apenas uma forma de trazermos a nossa experiência no desen- Para os programadores em Linux/Unix vamso explicar também como criar
volvimento de sitemas orientados a objetos, mas também a maneria de processos de sistema operacional, externos ao ambiente Smalltalk, e con-
mostrarmos como desenvolver bons programas. trolá-los de dentro da aplicação.
Nos capítulos 12 a 15 tratamos todos os aspectos do desenvolvi-
Temas O livro foi desenvolvido para servir tanto como livro texto para o mento de aplicações com intefaces gráficas, iniciando por superfícies gráfi-
abordados no aprendizado de Smalltalk e técnicas de orientação a objetos em Smalltalk cas, contexto gráfico e primitivas gráficas, passando pelos conceitos de
livro como também para servir como material de referência de programação e programação visual de interfaces em Smalltalk e desenvolviemnto de
de estilo durante o desenvolvimento de aplicações. Em função disso, nós menus e janelas de diálogo.
construímos o livro como uma série de tópicos encadeados, mas que após
o seu aprendizado podem ser consultados de forma direta e independente. No Capítulo 16 abordamos a teoria e técnicas de programação do
paradigma MVC. O paradigma model-view-controller é o mecanismo que
No Capítulo 2 é feito um breve relato da história de Smalltalk e de permite que interfaces gráficas de usuário se adaptem automaticamente
temas atuais e aplicações comerciais da linguagem. às alterações sofridas nos dados de suas aplicações.
Nos capítulos 3 a 7 abordamos os aspectos básicos do ambiente No Capítulo 17 nós vamos desenvolver passo a passo uma aplica-
e da linguagem necessários a todo aquele que deseja programar em ção que utiliza todas as técnicas vistas nos capítulos anteriores. Esta apli-
Smalltalk. No capítulo 3 descrevemos o ambiente de programação do cação é um pequeno simulador de redes neurais, uma aplicação da
VisualWorks, versão padrão de Smalltalk e conceitos básicos de Smalltalk, Inteligência Artificial, que nos permitirá aplicar e explicar através de exem-
como a execução interativa de código e a inspeção de objetos. Nos outros plos em um contexto maior todos os conceitos vistos.
capítulos explanamos conceitos básicos de orientação a objetos, de como
a linguagem os implementa e como utilizá-los no desenvovlimento de apli- No Capítulo 18 tratamos do desenvolvimento de aplicações cli-
cações. ente-servidro para WWW. VisualWorks possui uma poderosa biblioteca de
classes denominada VisualWave que permite desenvolver de forma
No Capítulo 8 abordamos manipulação de arquivos externos e tranparente e interativa aplicações para Internet. Neste capítulo vamos
estruturas de acesso seqüencial, assunto importante para aquele que vai explicar esta técnica e exemplificá-la através de uma pequena aplicação
desenvolver aplicações utilizando arquivos em disco e desenvolver formas de comércio eletrônico.
específicas de comunicação de dados via rede de computadores.
Capítulo 2 +LVWyULFR
Neste capítulo você vai ter uma visão geral do histórico da Lingua-
gem de Programação Smalltalk. A história de Smalltalk está intimamente
ligada ao próprio desenvolvimento da idéia de orientação a objetos e esta
será também abordsada neste capítulo. Ao final do capítulo vamos ver
quais são as tendências atuais em orientação a objetos e qual o desenvol-
vimento futuro de linguagem.
Creio que um bom ponto de partida para se aprender uma lingua- As origens
gem de programação não seja o tão famoso programa "Olá Mundo!!!". Par-
ticularmente prefiro aprender sobre a origem da linguagem, quais são suas
idéias principais, e a que propósito ela se destina.
Pensando nisso, fiz uma pesquisa sobre a história do Smalltalk,
sua origem, precursores, idéias que inspiraram, pessoas envolvidas, etc.
No final dos anos 60, mais precisamente entre 66 e 68, uma nova
implementação da linguagem ALGOL tomou forma. Ela se chamava
SIMULA e foi idealizada e escrita na Noruega. Ela se destinava a criação
de aplicações modeladas através de várias partes distintas ou invés do,
isso possibilitaria que várias pessoas trabalhassem concomitantemente no
mesmo projeto. É claro que era possível em linguagens como ALGOL ou específicas e se destinavam quase que completamente a aplicações
Pascal trabalharem várias pessoas juntas, cada uma escrevendo uma numéricas. Então uma nova linguagem de programação se fazia neces-
parte do programa. O problema residia no momento de se agrupar as sária. Uma linguagem que fosse de fácil programação, que possuísse
várias partes do programa. A linguagem SIMULA se destinava a tornar uma sintaxe simples. Alan entrou para o PARC e o projeto da nova lin-
simples e rápido esta tarefa de agrupar as partes em um todo consis- guagem de programação ficou entre as prioridades do projeto Dynabook.
tente. Alan Kay foi buscar as idéias de que necessitava para a criação
O que existia no SIMULA era bem parecido com alguns concei- da nova linguagem em uma linguagem educativa escrita por Seymour
tos de orientação a objetos de hoje. Se definia uma classe em uma estru- Papert. Ela se denominava LOGO, possuía interface gráfica e se desti-
tura de classes organizada em uma hierarquia. Cada classe possuía nava ao ensino de programação para crianças. A linguagem LISP,
dados e comportamentos comuns a todas as instancias da classe. desenvolvida por MacCarthy na década de 50, forneceu o poder neces-
Porém naquela época SIMULA era considerada uma extensão de sua sário para a manipulação de símbolos (coisa até então inédita para as
linguagem pai, o ALGOL. As idéias de polimorfismo e herança não linguagens que só tratavam de números). Vários conceitos vindos do
faziam parte dos conceitos da linguagem. LISP formaram as bases da estrutura da linguagem Smalltalk. Até hoje
Mais tarde o conceito de TAD’s (Tipos Abstratos de Dados) foi todo método em Smalltalk retorna um valor, da mesma forma que uma
derivado dos conceitos preliminares da linguagem SIMULA e hoje, utili- função LISP. A facilidade com que se programa recursivamente em
zados em qualquer linguagem Estruturada. Smaltalk também é uma herança de LISP. Por fim, as idéias de modulari-
dade e os primitivos conceitos de orientação a objetos da linguagem
foram inspirados na linguagem de simulação de sistemas SIMULA.
O grupo de Nesta mesma época estava em andamento um projeto revolu-
pesquisas da cionário dentro do PARC (Palo Alto Research Center), um centro de pes- O útero para a gestação do Smalltalk estava criado. A equipe de
Xerox em quisas da XEROX na Califórnia. O projeto se intitulava Dynabook, e tinha Alam Kay trabalhou intensivamente, e no final de 1972 a primeira versão
Palo Alto como objetivo prover um ambiente completo tanto para crianças como do Smalltalk estava pronta. Foi a primeira linguagem realmente orientada
adultos, consistinod num novo computador revolucionário, de onde deri- a objetos porém ainda sem o conceito de herança. Uma linguagem de
varam posteriormente as idéias de Interface Gráfica, Sistema de Janelas, fácil programação destinada ao aprendizado de programação, com uma
Mouse ou apontador gráfico, Conexão entre computadores (usando linha sintaxe reduzida e clara. O nome surgiu do propósito a que se desti-
telefônica ou conexão para LAN’s usando Ethernet), reprodução de sons nava1. A idéia era que fosse tão fácil programar em Smalltalk quanto se
conectando-se a um aparelho de som e tantos outros. ter uma conversa informal. O programa era bem rudimentar, possuía
apenas alguns milhares de linhas. Ela foi traduzida para assembly e bati-
Em paralelo, um pesquisador da Universidade de Utah chamado
zada com o nome de Smalltalk-72.
Alan Kay trabalhava em um projeto chamado Flex, que era um sistema
de programação, com um novo desing para a simulação em computado- Em 1974, Smalltalk foi expandido para suportar capacidade grá-
res. Alan tomou ciência do projeto desenvolvido na PARC e propôs fica com o mapeamento de imagem por bits (os Bitmaps), e também o
varias extensões de software para o diretor geral do projeto Dynabook, conceito de memória virtual. Estes melhoramentos levaram ao primeiro
tais como as aplicações que conhecemos hoje como editores de textos sistema de gerenciamento de janelas2. Foi então chamado de Smalltalk-
simples, programas para desenho, para a criação de objetos 3-D, etc.
Porém na época as linguagens de programação existentes eram muito 1. Small talk em inglês significa “papo furado”.
74. O conceito de herança só veio a ser implementado na versão do ano um esquema para a abertura da linguagem ao público em que continua-
de 1976. Tudo era baseado no conceito de classes, objetos, mensagens ria a publicar artigos pelo mundo, depois publicaria um livro e por fim dis-
e blocos. Na versão de 1976, também foi adicionado o conceito de byte- ponibilizaria o programa. Vários artigos foram publicados explicando os
codes e máquina virtual (VM - Virtual Machine), o que desvinculou a lin- conceitos por trás da linguagem e suas principais características. Alguns
guagem de programação do hardware específico de cada máquina e dos mais antigos e interessantes podem ser encontrados na revista Byte
também otimizou o que já existia. daquela época.
Bytecodes e Hoje o conceito de “linguagem interpretada baseada em código O livro planejado pela XEROX se multiplicou dando origem uma Adele
JAVA pré-compilado” representado pela geração de código intermediário série de três livros, com o título geral de Smalltalk - The Language and Its Goldberg e
usando byte-codes foi resgatado pela Sun Microsystems na linguagem Implementation. A organização e editoração da série ficou a cargo de seu livro
JAVA e é considerado a forma mais moderna e flexível de se produzir Adele Goldberg, uma das principais pesquisadoras do Projeto. Hoje os
programas ao mesmo tempo rápidos e independentes de máquina e de livros são conhecidos pela cor de suas capas, sendo chamados de Blue
sistema operacional. Isto permite que um programa em Smalltalk ou em Book, Orange Book e Green Book e formam a literatura mais clássica
JAVA desenvolvido em Microsoft Windows possa ser executado sem sobre Smalltalk, constituindo respectivamente: um manual de programa-
nenhuma modificação, nem mesmo recompilação, em uma Workstation ção, a referência da linguagem e a documentação da implementação da
Sun ou um Servidor IBM AIX ou em qualquer outra plataforma para a linguagem e da máquina virtual. Existia um plano em se lançar outro
qual exista uma versão da máquina virtual e vice-versa. Graças ao con- livro, porém ele nunca foi publicado. Ele se destinava a explicar uma fer-
ceito de byte-codes, a interpretação dos programas é feita de forma ramenta para aplicações interativas.
extremamente eficiente e rápida, sendo em alguns casos quase indife- A distribuição da linguagem, se deu através de fitas com uma
renciável de um programa compilado em “C”ou Delphi. versão portável da mesma. Esta versão portável consistia de um pro-
Em 1978, uma nova versão foi criada, porém apenas com o grama, a máquina virtual e um arquivo chamado imagem, onde todos os
código da anterior otimizado. Foi chamada, seguindo o padrão, Small- objetos do sistema residiam. A versão distribuída era chamada de
talk-78. Smalltalk-80 que nada mais era que uma versão mais enxuta do Small-
Neste momento, a pesquisa desenvolvida no Palo Alto Reseach talk-78. Neste ponto Smalltalk já possuía uma grande biblioteca de clas-
Center provocava curiosidade no mundo todo. Alguns artigos sobre o ses, e o mais interessante desta linguagem era que toda ela era
projeto do Dynabook e sobre sua nova e singularíssima linguagem de orientada a objetos. O compilador, a ambiente de programação e até
programação, o Smalltalk, eram publicados. O Dynabook nunca se tor- mesmo os números e caracteres eram objetos.
nou um produto comercial, em parte por seu custo altíssimo, porém o Smalltalk era então portável para qualquer plataforma que pos-
Smalltalk sobreviveu ao naufrágio do projeto. Neste ponto a XEROX suísse um sistema de bitmaps e outras poucas características e para o
acreditou estar na hora de tornar público o Smalltalk. A empresa montou qual existísse uma máquina virtual que interpretasse o byte-code gerado
pelo pré-compilador. A XEROX convidou então algumas empresas para
2. É interessante notar aqui, que o conceito de interação com o usuário de Smalltalk-74
desenvolverem as tais máquinas virtuais para suas plataformas. Dentre
de fato inspirou os sistemas de janelas atualmente em uso: MS Windows e X-Win- elas podemos citar a gigante Hewlett Packard, a emergente Apple Com-
dows. É muito citada na literatura uma visita de Bill Gates a Palo Alto, de onde voltou puter e a Digital Equipment. Depois desta primeira experiência que não
com “muitas idéias”.
podemos deixar de citar acarretaram alguns problemas, uma grande Muitas outras implementações de Smalltalk foram criadas. Com Smalltalk
variedade de implementações do Smalltalk começou a surgir. Muitos pro- o surgimento do Linux uma versão baseada no ST-80, sob o Projeto para Linux
jetos se iniciaram dentro dos Estados Unidos, Japão e Europa. A Apple GNU, foi lançada com o nome de Smalltalk/X. Esta versão é de livre dis-
apresentou um particular interesse em relação a linguagem, e vários pes- tribuição e possui máquina virtual com código fonte aberto, conforme exi-
quisadores do projeto original foram para lá com o intuito de criar uma gem os termos de uso do GNU.
nova arquitetura de computador que deu origem ao sistema operacional Outro Smalltalk de livre distribuição que surgiu em 1996 foi o
da Apple baseado em interface gráfica. Squeak. Esta implementação é bem interessante pois foi desenvolvida
por um pequeno grupo de desenvolvedores, e entre eles constava nada
Smalltalk IBM A IBM não deixou por menos. Desenvolveu várias pesquisas e menos do que o pai do Smalltalk, Alan Kay. Ela possui características
criou a sua versão do Smalltalk chamada Smalltalk V. O Smalltalk V foi o bem interessantes com uma interface bem amigável e colorida. Atual-
primeiro Smalltalk a rodar também em DOS e tornou-se extremamente mente é utilizada pela Disney.
popular no final da década de 80. Posteriormente a IBM mudou o nome
de sua implementação de Smalltalk para VisualAge for Smalltalk, versão Atualmente a CINCOM inclui uma máquina virtual para Linux em
que possui diferenças mínimas em relação ao VisualWorks. sua distribuição não-comercial gratuita de VisualWorks, o que definitiva-
mente consolidou o VisualWorks como o Smalltalk padrão.
A XEROX não teve muito sucesso com suas implementações de
Smalltalk para suas Workstations. Em 1987 a XEROX criou uma nova As áreas de aplicação de Smalltalk são extremamente extensas: Aplicações
empresa chamada PARC PLACE para cuidar especificamente de negó- quanto mais complexo o problema a ser resolvido, maiores as vatagens comerciais e
cios relativos ao Smalltalk. Eles criaram várias versões baseadas no de se utilizar Smalltalk para o desenvolvimento de uma solução. projetos
Smalltalk-80 para diversas plataformas como IBM-PCs, Workstations da
Apollo e da Sun e para os Apple Macintosh. Em 1990 uma versão cha- No Brasil, Smalltalk ainda não é muito utilizado comercialmente,
mada ObjectWorks foi lançada. Ela era bastante comercial e possuía apesar de alguns bancos já possuírem partes de seus sistemas desen-
uma biblioteca de classes bem extensa. Depois da versão 4.1 o nome do volvidos em Smalltalk. Suas maiores aplicações residem nas áreas de
produto foi mudado para VisualWorks e ganhou um ambiente para pro- pesquisa e ensino, principalmente em Universidades Federais como a
gramação visual de interfaces gráficas de usuário. A Parc Place foi com- Universidade Federal de Santa Catarina - UFSC, Universidade Federal
prada pela CINCOM no final dos anos 90, que manteve a linha de do Rio Grande do Sul - URGS e Universidade Federal de Pernambuco -
produtos VisualWorks. O VisualWorks tem duas linhas. Uma de produtos UFPE.
comerciais com uma extensa biblioteca de classes e com inúmeras pos- Na Europa Smalltalk é extensivamente utilizado comercialmente,
sibilidades que vão desde a capacidade de se criar aplicações para rodar e praticamente todas as Universidades de Computação a utilizam como
na Internet, objetos para acesso de grandes bancos de dados como ferramenta para ensino do paradigma de programação orientada a obje-
ORACLE até objetos para o suporte de programação distribuída e ferra- tos.
mentas de controle de versões de código fonte. Ela também possui uma
Dois exemplos de aplicação comercial são a DEUTSCHE BANK,
distribuição não comercial para estudantes e curiosos, porém sem algu-
que em meados da década de 90 passou todo seu sistema de gerência
mas das funcionalidades da versão comercial, principalmente no que
de mercado financeiro para Smalltalk, e uma das maiores cadeias de
tange o controle de versões, e limitada apenas para uso individual.
supermercados da Europa, que na mesma época passou por uma rees-
&RQFHLWRV%iVLFRV
truturação completa de seu setor de informática, passando todo o sis-
tema para Smalltalk. Capítulo 3
Essa Rede de Supermercados é um exemplo extremamente
interessante e ilustrativo da facilidade com que se pode aprender Small-
talk e portar um sistema desenvolvido em um paradigma completamente
GR$PELHQWH
diferente para o ambiente Smalltalk. Um dos autores deste livro trabalhou
no grupo de pesquisas da Universidade de Kaiserslautern responsável,
em 1995, por desenvolver e aplicar o programa de treinamento e recicla-
gem dos profissinais de informática desa rede de supermercados. Na
época, todo o sistema da empresa era desenvolvido em RPG, uma lin-
guagem de segunda geração, em plataforma AS 400. O perfil médio do
desenvolvedor de software empregado na empresa apresentava uma
média de idade de 40 anos e formação profissional de tecnólogo em pro-
cessamento de dados. A grande maioria não possuía quaisquer conheci-
mentos de orientação a objetos. Para o desenvolvimento do novo
sistema foram escolhidas estações Unix IBM AIX e VisualAge for Small-
Este capítulo tem por objetivo familiarizar o leitor com o ambiente
talk como ambiente de desenvolvimento. VisualAge foi escolhido em fun-
de desenvolvimento do VisualWorks. Neste capítulo passaremos ao leitor
ção de suas ferramentas de conectividade a mainframes, o que permitiu
uma vissão geral do ambiente de desenvolvimento/execução do Visu-
continuar utilizando os bancos de dados rodando em AS 400 a partir de
alWorks. Também apresentaremos os vários tipos de browsers, o works-
programas em Smalltalk. Dessa forma foi possível uma migração gradual
pace, o VisualLaucher e o UIPainter. O mecanismo de fileIn/fileOut e
dos sistemas em RPG para a nova base de software em Smalltalk. Em
parcels também terá vez neste capítulo, onde explicaremos para que serve
função do perfil dos profissionais que necessitavam ser reciclados, foi
e como funcionam todas essas partes do VisualWorks. Apresentaremos
desenvolvido um programa de treinamento especialmente voltado a pro-
por fim como podemos fazer para buscar ajuda dentro do ambiente de
gramadores experientes, mas sem nenhuma noção de orientação a obje-
desenvolvimento.
tos. Em função da antigüidade da plataforma RPG, isto foi um desafio
especial. A experiência foi um sucesso, todos puderam ser reciclados e
não foi necessário demitir funcioinários em função da mudança de tecno-
logia, o que demonstra claramente a facilidade de aprendizado do Small- 3.1 Smalltalk e VisualWorks
talk. Para programadores experimentados em outras linguagens de
Esse programa de treinamento foi adaptado e originou o Curso programação, principalmente aquelas de linha de comando, o VisualWorks
de Smalltalk regularmente ministrado como Curso de Extensão no pode parecer um tanto confuso. Para aqueles familiarizados com LISP ou
Departamento de Informática da Universidade Federal de Santa Catarina PROLOG o impacto será um pouco menor. A grande diferenciação do
e também propiciou muitas das experiências que nortearam o desenvol- Smalltalk para as outras linguagens de programação reside no fato de que
vimento deste livro. todo o ambiente de desenvolvimento está acoplado ao ambiente de execu-
ção. Podemos em suma dizer que não existe muita diferença em se edi- Dentre os pontos negativos podemos ressaltar uma menor per-
tar ou executar um programa em Smalltalk. formance de execução se comparada a linguagens como C ou Pascal, e
O VisualWorks é uma versão do Smalltalk que, como pudemos também a impossibilidade de se gerar código executável.
ver no histórico, é o sucessor principal do projeto da PARCPLACE. Nesta A seguir mostraremos ao leitor como se procede para se iniciar
seção introduziremos os principais conceitos que permeiam esta ferra- uma seção do VisualWorks e como devemos encerrá-la.
menta e a fazem única detre as linguagens de programação.
O VisualWorks é uma ferramenta de desenvolvimento interativo.
As classes são criadas e objeto podem ser intanciados e executados no 3.2 Obtendo uma cópia do VisualWorks
mesmo ambiente. O mais interessante desta interatividade proporcio-
O VisualWorks é uma ferramenta comercial de desenvolvimento
nada, como veremos mais adiante neste capítulo, é o fato de que qual-
tal como DELPHI ou Visual Basic. Como toda ferramenta comercial que
quer objeto pode ser inspecionado a qualquer momento e em qualquer
se prese, ela é paga. Mas o VisualWorks possui uma vrsão não cormer-
lugar do ambiente.
cial que pode ser utilizada por qualquer pessoa para uso pessoal ou edu-
Vale também ressaltar que o Smalltalk é uma linguagem inter- cacional. Esta versão não comercial possui algumas limitações em
pretata tal como JAVA, ou seja, código executável não é gerado, apenas relação a versão comercial, mas é perfeitamente usável .
bytecodes que são interpretados por uma máquina virtual. A grande dife-
Ela pode ser baixada diretamente do site da Cincom. O ende-
rença exsitente entre o bytecode gerado pelo VisualWorks e o gerado por
reço é o seguinte:
JAVA é que todos os objetos de todas as aplicações escritas em Small-
talk são colocadas dentro de um único arquivo que possui a extensão http://www.cincom.com
.im, a imagem. A abstração é que a imagem do VisualWorks é como um Vale dar uma olhadinha no site da fabricante. Periodicamente
“pequeno mundo“ onde tudo reside. Podemos então imaginar que se existem novas versões atualizadas para serem baixadas bem como notí-
essa filosofia aplica-se realmente a tudo, o compilador, o parcer e todos cias sobre o VisualWorks Smalltalk.
os objetos do ambiente de desenvolvimento também residem dentro da
imagem. A imagem é um arquivo relativamente grande, devido a esta
filosofia de agrupar tudo, então veremos que a imagem padrão tem seu 3.3 Arquivos com a Documentação do Smalltalk
tamanho girando em torno de 7 MB, e que após a eventual carga de
alguns parcels pode, tranquilamente, ter seu tamanho almentado para Na distribuição de instalação do VisualWorks existe um diretório
além de 10 MB. Parcels serão vistos mais a frente neste capítulo. chamado doc que contém vários arquivos pdf que compoem a docu-
mentação do VisualWroks. Neste diretório reside a documentação de
O fato do VisualWorks ser interpretado possui em si pontos bons
quase tudo o que existe no VisualWorks. O arquivo mais utilizado por
e maus. Uma de suas grandes vantágens é o fato de ser perfeitamente
programadores é sem sobra de dúvida o VisualWorks Application Deve-
portável para várias plataformas. Se o leitor der uma olhada no diretório
loper´s Guide, que contém uma descrição de boa parte do básico da lin-
bin da instalação do VisualWorks, poderá ver que lá se encontram mais
guagem. Vale ressaltar que este guia é um tanto superficial, deixando em
de 10 máquinas virtuais para diferentes plataformas. Dentre elas, Win-
aberto ou mal cobrindo alguns tópicos, tais como o uso de yourself
dows, Linux, Unix, Solaris, AIX, HP, etc. Outra grande vantágem de ser
ou thisContext que cobriremos nos próximos capítulos.
interpretado é a interatividade a qual já foi discutida acima.
Manuais A seguir, descreveremos cada um dos arquivos pdf contidos no dstcon.pdf -- VisualWorks Distributed Smalltalk Configuration
contidos no diretório doc. À medida que considerarmos necessário, vamos comentar Guide: Explica como configuar aplicações distribuídas em Smalltalk.
diretório doc seu conteúdo, sua utilidade e a ordem em que devem ser lidos. Na lista- dstpr.pdf -- VisualWorks Distributed Smalltalk Programmer´s
gem adiante vamos descrevê-los em ordemm alfabética. Reference -- Explica a idéia básica por detrás do desenvolvimento de
atug.pdf --VisualWorks Advanced Tools User´s Guide: Descreve aplicações distribuidas em Smalltalk.
algumas ferramentas do VisualWorks tais como o Parser, o Compilador, fixed_ars.pdf -- ARs Resolved in 5i.3 : lista os erros corrigidos
o gerador de relatórios, a ferramenta de benchMarks, etc..... na versão 5i.3.
bridge.pdf -- VisualWorks StORE BRIDGE: Descreve como se icslides.pdf -- VisualWorks Internet Connectivity Workshop.
migra uma aplicação usando o controle de versões do Envy para o con- Alguns slides do referido Workshop (sinseramente, eu nunca li isso!)
trole de versão usado pelo StORE. Tem muito pouca utilizade para usuá-
rios standalone, a não ser que estajam envolvidos em algum grande idlpr.pdf -- VisualWorks Distributed Smalltalk IDL Programmer´s
projeto de software. Reference: Referência da implementação de Smalltalk de IDL - Interface
Definiton Language, a linguagem padrão de intercâmbio de objetos utili-
comc_automation.pdf -- Using COM Conect Automation zada por Distributed Smalltalk e por CORBA.
Wizard: Descreve como se utiliza a ferramenta IAAutomationWizard para
publicação de automações COM. otcldg.pdf -- VisualWorks Opentalk Communication Layer
Developer´s Guide: provê informação sobre como implementar protoco-
comug.pdf -- VisualWorks COM Connect User´s Guide: Este los de comunicação e como desenvolver aplicações distribuidas utili-
guia descreve como usar o VisualWorks COM Connect para acessar ou zando Opentalk Communication Layer.
publicar objetos de dentro de Aplicações escritas em VisualWorks. Tam-
bém fornece referência para usar COMAutomation, ou seja OLE com visualworksfaq.pdf -- VisualWorks Frequently Asked Questi-
VisualWorks. ons: Como o próprio título já diz é um FAQ sobre Smalltalk. Muitas das
perguntas e respostas vêm do newssite comp.lang.smalltalk. Se
dbadg.pdf -- VisualWorks Database Connect Aplication Develo- o seu domínio de Internet, seja este um provedor comercial ou sua uni-
per´s Gride: Descreve o acesso a bancos de dados externos, ObjectLens versidade, colocar um serviço de news à sua disposição, sugerimos for-
e ODBC suporte para acessar bancos de dados relacionais dentro de temente que você assine este grupo de news, pois ele sempre tras
aplicações no VisualWorks. Descreve acesso genérico a banco de dados muitas informações e discussões úteis e atualizadas sobre Smalltalk. A
e também acesso específico para Oracle 7, Oracle 8, SYBASE CTLib e forma mais fácil de assessar um newssite é através da ferramenta Nets-
ODBC. cape Mail, onde você pode configurar acesso a vários servidores de
dllccug.pdf -- VisualWorks DLL & C Connect : Descreve o news simultaneamente.
mecanismo empregado para se utilizar bibliotecas escritas em C e DLLs vwadg.pdf -- VisualWorks Application Developer´s Guide: Prin-
em uma aplicação escrita em Smalltalk. cipal documento sobre o VisualWorks. Descreve a linguagem e o ambi-
dstadg.pdf -- VisualWorks Distributed Smalltalk Application ente.
Developer´s Guide: Apresenta o processo de desenvolvimento de aplica-
ções usando DST - objetos distribuídos em Smalltalk. Vale citar que DST
é compatível com CORBA.
vwiccb.pdf -- VIsualWorks Internet Connectivity Cookbook: Este wavescon.pdf -- VisualWave Server Configuration Guide:
arquivo é bem quente. Descreve como perfazer tarefas de internet tais Manual de configuração das classes servidoras HTTP que podem ser
como ftp, http, etc. usadas com aplicativos Smalltalk exportados para Internet.
vwintlg.pdf -- VisualWorks Internationalization Guide: O guia Existem ainda muito poucos livros que tratam de Smalltalk. A
de internacionalização indica técnicas e ferramentas em Smalltalk para maioria deles se reporta a versôes antigas e durante a elaboração deste
criar interfaces de usuário multiligües. Se você está desenvolvendo um livro realizamos uma pesquisa e não encontramos nenhum escrito em
software comercial para o Mercosul ou um software científico e deseja portugês ou traduzido. Ao consultar a bibliografia, o leitor verá que cita-
colocá-lo à disposição para ser baixado pela internet depois, é interes- mos alguns livos em inglês, mas a massa de documentos consultados
sante que ele seja multilíngüe. pelos autores deste livros foi artigos e páginas da web.
vwpluginadg.pdf -- VisualWorks PlugIn Application Developer´s Outro aviso importante ao leitor se refere às páginas que tratam
Guide: Da mesma forma que JAVA, Smalltalk também suporta a geração, do assunto na web. Existem muito boas referências porém a grande mai-
disponibilização e utilização de Applets na Internet. Para executar esses oria das páginas consultadas pelos autores demstrou conter um con-
applets a partir de um cliente remoto, é necessário que o browser possua teúdo superficial e até mesmo errôneo em alguns casos. Não queremos
um plugin especial (disponível somente para o Netscape) que é uma desta forma desencorajar o leitor a procurar mais informações pela Inter-
máquina virtual extremamente enxuta e especial para excução remota, net de maneira alguma, apenas alertamos para que tenha critério ao utili-
da mesma forma que você necessita do JDK para execução de código zar algum material publicado na mesma.
JAVA. Este manual ensina a desenvolver aplicações que usam esta
máquina virtual-plugin.
vwrn.pdf -- VisualWorks Release Notes: Descrição de caracte- 3.4 Instalando o VIsualWorks em sua máquina
rísticas novas da versão atual, que você acabou de baixar.
A partir da versão 5i.2 o VisualWorks vem com um estalador. Ele
walkthrough.pdf -- VisualWorks Walk Through: Um dos melho- ajuda tremendamente a intalar o software. Em versões anteriores o dire-
res tutoriais de Smalltalk. Comece por aqui. tório contendo todas as pastas referentes a instalação do VisualWorks
waveadg.pdf -- VisualWave Application Developer´s Guide: tinham que ser copiadas manualmente para o disco rígido.
VisualWave é a infraestrutura de VisualWorks para desenvolvimento de Não existe nenhuma grande diferença em instalar o VisualWorks
aplicações para Internet. Contém um conjunto de classes para transfor- em relação a qualquer outro software. Um ponto porém é interessante. O
mar suas interfaces de usuário em páginas HTML de forma transparente programa de instalação foi escrito em Smalltalk, e como toda a aplicação
e dois tipos de servidores HTTP que podem ser conectados com a sua em Smalltalk está contida dentro de uma imagem, uma imagem é execu-
aplicação Smalltalk. É de longe a forma mais fácil de desenvolver um tada para carregar o programa de instalação.
aplicativo para Internet: você desenvolve como se fosse um programa
O programa de instalação é executado diretamente quando o
normal, com janelas e interfaces gráficas e Wave exporta em tempo real
CD-ROM é inserido. Caso o sua máquina ou plataforma não suporte este
para um browser.
recurso, execute a imagem chamada install.im.
wavegs.pdf -- VisualWave Developer’s Getting Started with
Além de permitir a instalação, este programa também permite
VisualWave: Comece aprendendo a usar Wave por aqui.
que o VisualWorks seja removido de sua máquina.
3.8 Browsers
Os browsers são as ferramentas básicas para edição de progra-
mas. E através deles que criamos novas classes e é por onde podemos
analisar o código da biblioteca de classes. Existem três tipos de brow-
sers. Eles podem ser acessados a partir do Laucher, nos 3 botões mos-
trados na figura 3.7 .
Figura 3.6 Laucher do VisualWorks Figura 3.7 Botões para abertura dos browsers
Como descrito na seção anterior, se o laucher for eventualmente Da esquerda para a direita temos o browser organizado por
fechado, para que a imagem possa ser salva ou para que se feche a NameSpaces (NameSpaces serão vistos em detalhes mais a frente no
seção será necessário que o laucher seja novamente aberto. Isso pode livro), o Browser organizado por Categorias e o browser organizado por
ser feito de duas maneiras. Fechando todas as demais janelas fazendo parcels. Como podemos ver, cada um destes browsers se destina a uma
assim com que o laucher seja reaberto ou executando o seguinte aplicação específica dentro do ambiente de desenvolvimento. Para a cri-
comando mostrado no exemplo 3.1 . Para saber como executar este ação de classes e métodos o mais indicado é o organizado por catego-
comando, veja mais adiante neste capítulo a seção “Executando rias (botão do meio). Os outros browsers serão abordados em maiores
Código”. detalhes no decorrer do livro. Tomemos o browser acionado pelo botão
do meio como objeto de estudo então.
VisualLauncher open. Ele permite que o programador inspecione todas as classes e
Exemplo 3.1 Reabertura do visual laucher seu respectivo código fonte que estão contidos dentro da imagem. Como
podemos ver na fig. , o system browser é dividido em 5 quadros e um
será automaticamente criado. esta é realmente uma das grandes vantá- Geralmente é muito útil ter-se uma noção da topologia da árvore Expandindo a
gens de Smalltalk. não necessitarmos explicitamente compilar o código. de hierarquia de uma determinada classe. Isso nos facilita concluir onde hierarquia de
O processo de compilação anda em paralelo com o de criação de clas- um método que foi enviado a instancia de uma classe foi realmente classes
ses e métodos. implementado, além de mostrar claramente a estrutura que compõe uma
Feito isso, a sua nova classe será então adicionada à lista de classe.
classes daquela categoria finalizando assim o processo para a criação Isso pode não parecer muito útil a primeira vista, mas durante o
de uma nova classe. tempo em que o leitor for se familiarizando com o Ambiente, inerente-
mente, a necessidade de uma ferramenta como essas lhe saltará aos
Template Similarmente ao template para a criação de classes, o template olhos.
para a para a ciração de métodos define em geral onde se deve colocar o nome Quando uma classe é selecionada para que tenha a sua hierar-
criação de do método, o comentário, a lista de variáveis temporárias e o código pró- quia expandida, o que acontece de fato é a abertura de um novo brow-
métodos priamente dito. Em geral, quando o template de métodos é aberto, sim- ser, um tipo especial chamado hierarquical Browser. Sua principal
plesmente delete o texto e entre com a descrição do método. característica é apresentar a hierarquia de classes de uma dada classe.
Para se criar um novo método, basta que se selecione um dos Note que este browser só tem 3 listas, que são: classes (organizandas
protocolos de métodos de uma classe. O template será mostrado imedia- hierarquicamente), protocolos e métodos. O nível de categorias é abstra-
tamente no campo inferior do browser. Delete-o, digite seu método e ído neste caso.
então clique com o botão direito do mouse sobre o método. Selecione a Para abrir um Hierarquical browser clique sobre uma classe na
opção <accept>. Isso fará com que o VisualWorks chame o compilador lista de classes no System Browser e selecione a opção <Spawn Hierar-
que verificará a corretude de seu código e então, caso esteja tudo certo, chy>.
compila gerando o bytecode correspondente e o adiciona a imagem.
outro editor de textos, usando o mouse ou através das teclas de desloca- janela de inspeção contendo o estado interno do ultimo objeto retornado
mento e do shift. pela parcela de código (este processo será explicado em detalhes mais a
frente no livro). Por último, a quarta opção permite que debuguemos a
parcela de código através da ferramenta de debug do Smalltalk.
Figura 3.16 Código selecionado no workspace Figura 3.17 Popup menu aberto a partir do botão direito do mouse
Uma vez que a parcela de código alvo esteja selecionada, deve- Na figura 3.18 na página 58 podemos ver o resultado de esco-
mos clicar com o botão direito do mouse sobre o cõdigo. Isso fara com lhermos a segunda opção (print it). O conteúdo da coleção criada é então
que um menu popup seja aberto. A partir deste menu, temos quatro impresso no workspace. Note que o texto é simplesmente escrito no
opções que nos permitem executar o código. Estas quatro opções são workspace e não faz parte do código. por isso ele já é impresso selecio-
encotradas na quarta seção de cima para baixo na figura 3.18 . Todas as nado pois deve ser deletado, a menos que você queira comentá-lo.
quatro opções, do it, print it, inspect it e debug it executam a parcela de
Caso o código lhe pareça difícil de entender, não se preocupe, à
código selecionado. A diferença é que a primeira opção simplesmente
medida que avançar pelos capítulos, você vai compreender todos os
executa o mesmo, a segunda executa e chama o método2 e redireciona
aspectos da sintaxe do Smalltalk. Por enquanto concentre-se neste
a saida para onde o código se encontra. A terceira opção abre uma
aspecto importante e novo, que é a capacidade de, em Smalltalk, você
selecionar qualquer trecho de código, em qualquer lugar, e simplesmente
2. O método printOn: é definido na classe Object e é responsável pela forma com que mandar executá-lo.
um objeto será impresso. Ele é usado em diverças partes do Ambiente de desenvolvi-
mento e será melhor esplicado no capítulo 9.
Figura 3.18 Resultado do execução da opção print it Figura 3.19 Janela do Resource Finder
3. Recursos editáveis são: imagens, menus, interfaces gráficas, etc. 5. Termo comumente utilizado em Informática para denomenar editores que permitem
4. windowSpec é o nome padrão dado a especificação de uma janela. Este tópico será definirmos interfaces e documentos da mesma maneira em que os vemos (O que você
visto em detalhes mais adiante. vê é o que você obtém)
acaba de ser feita seja salva como um recurso em uma classe especifi-
cada.
O UIPainter também possui a operação define que só é abilitada
uma vez que a interface já está instalada. Ela permite que operações
básicas dos componentes que geralmente deveriam ser explicitamente
definidas pelo programador sejam criadas de forma automatizada.
Esta janela contém todos os componentes que uma janela pode Palette
conter. Seu funcionamento é bem parecido com o encontrado no VB e
DELPHI, escolhe-se o componente a ser inserido na janela e arasta-o
Interface do aplicativo Paleta até a posição desejada. Na parte inferior da janela é apresentado o nome
Paleta que você está desen- para do componente selecionado.
para volvendo. Inicialmente formatação
adição Uma boa característica encontrada na palette são os dois botões
ela se chama sempre de
de Unlabeled Canvas interfaces encotrados no canto superior direito e esquerdo, eles permitem que sele-
componentes e menus cionemos um objeto para adição simples ou multipla ao canvas.
Ele é dividido em 3 janelas principais que permitem a edição da Seu funcionamento é bem simples, ele é a superfície gráfica
interface, seleção de componentes e operações básicas sobre o projeto onde podemos desenhar interfaces e possui propriedades como qual-
da interface. A seguir descreveremos cada uma delas e apresentaremos quer janela em outras linguagens de programação.
ainda outras duas ferramentas, o menu editor e o image editor.
Se o leitor já possui alguma esperiência em desenvolvimento de Properties
interfaces em Delphi ou VB deve estar se perguntando: Mas e as proprie-
Canvas Tool Esta janela permite operações básicas sobre a edição da inter-
face tais como alinhamento e redimencionamento de componentes. Tam- dades dos componentes ?
bém possui botões e entradas de menu para perfazer duas operações É importante observar que a maioria das ações em smalltalk são
muito importantes durante o desenvolvimento de interfaces gráficas no suportadas em menus. Eles são utilizados exaustivamente em todo o
VisualWorks, “DEFINE“ e “INSTALL“. ambiente de desenvolvimento e a medida que o leitor for se acostu-
Uma vez que a interface está completamente desenhada e mando com o smalltalk verá que é extremamente prático tem todos os
todas as propriedades dos objetos estão definidas a operação de install comando “ao alcance do botão direito do mouse”.
deve ser executada. Ela faz com que a especificação de interface que
Então é de se esperar que as propriedades possam ser acessa- A grande maioria destas variáveis de ambiente podem ter seus
das através de um menu acionado pelo botão direito do mouse. A figura valores alterados através da janela Settings. Esta janela pode ser aberta
3.21 na página 62 mostra a janela de propriedades de um botão através do menu <File> opção <Settings>, conforme mostrado na figura
3.22 na página 63.
lado. Muitas outras variáveis de ambiente fazer referência a esta variável linguagens de programação, demorar-nos-emos a explicar em que con-
e se está esntiver apontado para o caminho errado muitos problemas sistem.
ocorrerão com a sua imagem. De fato este é o problema mais comum
que um iniciante em Smalltalk irá encontrar. Problemas como código Como o leitor já sabe, todo o código produzido fica inserido den- Mecanismo
decompilado, e parcels que não podem ser encontrados são em geral tro do arquivo imagem. Desta forma não existe aquele conceito tão de fileIn/
causados pela incorreção do caminho desta variável de ambiente. comum em outras linguagens de programação de se salvar o seu arquivo fileOut
Ela pode ser alterada através de uma janela especial unica- de código fonte separado do executável. No Smalltalk eles são uma
mente com esta finalidade que pode ser aberta através do itém de menu coisa só.
<File> opção <Set VisualWors Home>. Porém, não são raros os casos onde se deseja possuir uma
cópia textual do programa editado, e também situações onde desejamos
fazer backups apenas de certas alterações ou situações onde desejamos
3.13 Coletando o Lixo compartilhar um pedaço de código com um colega por motivos vários.
Desta forma, o mecanismo de FileOut permite que se salve uma Catego-
Uma das grandes facilidades do Smalltalk reside no fato de que ria, Classe Propocolo ou somente um método em um arquivo separado.
na maioria dos casos o programador não precisa se preocupar com a Também é permitida a seleção de métodos esparços por várias classes e
liberação de memória, está tarefa enfadonha é feita automaticamente por qualquer outra combinação que o leitor imaginar ou sentir necessidade.
uma parte do ambiente conhecida como Garbage Collector (ou coletor
de lixo). O processo de FileIn, como já era de se esperar, é exatamente o
oposto. Tendo como base arquivo previamente gerado pelo Smalltalk,
O fato é que as vezes o coletor de lixo pode demorar um pouco permite que o código nele contido seja incorporado a imagem.
para perceber que certos objetos já podem ser liberados. Desta forma
existe um ítem no menu <File> opeção <Collect all Garbage> que per- Duplicatas de qualquer tipo serão sobrepostas com os dados
mite acionar o coletor de lixo explicitamente. Em geral porém não existe contidos no arquivo.
muita necessidade de se preocupar com isso.
Atualmente o Smalltalk permite que que estes arquivos sejam Salvando em
Existem outras situações como veremos mais a frente em que o XML ou em
escritos em duas linguagens, Smalltalk Chunk Source Code, que nada
programador deve se preocupar com a liberação de memória, devido a texto chunk
mais é do que texto Smalltalk passível de ser interpretado pelo compila-
fenomenos conhecidos como referência circular e outros, mais isso será
dor Smalltalk e também editado em qualquer editor de programas, e XML
abordado mais a frente no livro.
Source Code. Se uma determinada parcela de código for salva utilizando
XML e tentar ser carregada prevendo Smalltalk chunk ou vice-versa um
erro será gerado.
3.14 Carregando e Salvando Código Fonte
A linguagem utilizando para abertura e escrita de arquivos
O processo de FileIn e FileOut já foi citado lagumas vezes (FileIn e FileOut) pode ser definida através de uma variável de ambiente
até aqui no livro, e por ser até certo ponto uma operação pouco usual encontrada na janela Settings.
senão quase desconhecida para programadores que conheçam outras
Código fonte Arquivos contendo o código executável são salvos com a exten-
e código ção .pcl, e arquivos contendo o código fonte são salvos com a extenção
executável .pst. O VisualWorks fornece um tipo de browser especial para que geren-
ciemos nossos parcels. Na figura 3.23 temos os 3 botões para aciona-
mento dos browsers fornecidos pelo VisualWorks. O browser de parcels
pode ser acionado pelo botão da direita.
Figura 3.25 Janela para remoção de parcels necessárias foram adicionadas ao parcel, faz-se necessário salvá-lo.
Isso pode ser feito através do item de menu <Parcel> >> <Save>.
Criando seu Criar um parcel é um passo essencial para o desenvolvimento e O Parcel Browser adota algumas convenções que indicam o
próprio intercâmbio de suas aplicações e, ao contrário do que possa parecer, é estado do código fonte em relação a um parcel. A tabela 3.1 na página
parcel bem simples. Abra um parcel Browser (como mostrado anteriormente 70 detalha algumas delas.
neste capítulo) e selecione a partir do menu principal do browser o item
<Parcel> >> <New>. Uma janela será aberta pedindo que você indique o
nome do parcel a ser criado. A seguir navegue pelas classes protocolos
e métodos adicionando os que pertencem a aplicação que queremos sal-
var no parcel que acabamos de criar. Note que se adicionarmos uma
classe a um parcel todos os seus protocolos e métodos serão automati-
camente adicionados ao parcel, e se adiocionarmos um protocolo a um
parcel todos os métodos por ele agrupados serão adicionados ao par-
cel.Uma vez que o todas as classes, métodos, protocolos e variáveis
convenção significado
3.16 Código Executável
Negrito Indica que existe algum subitem adicionado ao parcel.
Sublinhado Indica que todo o item foi adicionado ao parcel. Ao contrário de alguns ambientes de desenvolvimento de JAVA,
que permitem que você gere código nativo executável para a máquina
indica itens definidos em mais de um parcel. Representa
Vermelho específica onde você desenvolveu a sua aplicação, nenhuma implemen-
possivel conflito.
tação de Smalltalk permite que código executável seja gerado. Este
* Indica que o parcel foi modificado e ainda nao foi salvo código JAVA “nativo” evidentemente perdeu as características de inde-
< Indica que o parcel nao foi criado mas sim carregado pendência de sistema operacional e de máquina que são características
o parcel possui parte de seu código que não está pre- essenciais da linguagem JAVA. Smalltalk utiliza outra filosofia para con-
!
sente na imagem. tornar o problema de aplicações “prontas” para o usuário usar, sem a
o parcel possui métodos que foram sobrescritos durante necessidade de instalar máquina virtual e outras coisas. Veremos isto
+ neste capítulo.
seu processo de carregamento.
Tabela 3.1 Convenções adotadas pelo parcel browser Desta forma, o que foi durante muito tempo muito comum de se
ver em relação a Smalltalk, é que ele era muito utilizado como ferramenta
Alguns Workspace Organizer -- Este é um parcel muito útil pois funci- de prototipação devido às óbivias vantagens oferecidas pelo mesmo
parcels ona como um ficheiro de workspaces, onde vários itens e subitens são nesta tarefa, mas dificilmente era utilizado como ferramenta para criação
comumente podem ser criados a maneira de um menu permitindo organizar o seu de produtos. Diante deste quadro, vários esforços tem sindos dispendi-
utilizados código de teste. dos no sentido de se criar aplicações executáveis a partir de uma aplica-
ColorEditing -- Permite que se defina cores para variáveis, ção escrita em Smalltalk.
métodos, classes, etc. Muito útil durante o desenvolvimento. Este tipo de
caracteristica adicionada por este parcel está presente na maioria dos Em Microsoft Windows, VisualWorks fornece uma ferramenta Criando
ambientes de desenvolvimento modernos. chamada ImageMaker para minimizar este problema. O que ela faz na aplicativos
realidade é “limpar“ a imagem de todos os objetos que sejam irrelevantes .exe
VisualWave -- Permite que aplicações sejam publicadas na
a sua aplicação deixando a mesma compacta. Em seguida ele junta a
Internet. Na realidade faz uma tradução da aplicação para HTML.
imagem com uma versão igualmente enxuta da máquina virtual e salva o
ODBC -- Permite acesso a bancos de dados utilizando o meca- resultado final com uma extensão .exe. O arquivo final geralemente tem
nismo de ODBC. seu tamanho girando em torno de 5 MB e não possui a mesma perfor-
DLL & C Connect -- Permite que código objeto salvo sob a mance que um programa compilado, pois em verdade será interpretado.
forma de bibliotecas executáveis em DLLs (Windows) e em arquivos .SO
(Unix e Linux) sejam acessados dentro do Smalltalk. Esta ferramenta Existe uma segunda abordagem. Trata-se de traduzir o código Convertendo
quando bem utilizada pode permitir um aumento de perfornance nas apli- escrito em Smalltalk para C++, permitirndo desta forma que o código seja Smalltalk
cações que utilizem muito processamento. compilado de forma bem eficiente. Este enfoque é útil dentro de uma filo- para C++
sofia de se utilizar as facilidades de prototipagem de Smalltalk para o
desenvolvimento de uma aplicação, que, depois de pronta, é cross-com-
pilada para uma linguagem mais rápida. Uma ferramenta para isto já
existia nas versões 2.5 a 4.0 do ObjektWorks Smalltalk, que podia ser 3.18 Gerenciando o Arquivo de Alterações
adquirido juntamente com um pacote (somente disponível para ambien- O arquivo .cha apresentado anteriormente funciona como um log
tes Apollo Domain e Unix) denominado ObjektKit C++. O ObjektKit dispo- de todas as atividades do programador durante o processo de programa-
nibilizava versões C++ de todas as classes básicas do Smalltalk (com ção do VisualWorks. Tudo, desde a criação de uma classe até a posição
limitações) e vinha com um conjunto de classes cross-compiler para você do browser na tela é registrado e arquivado neste arquivo.
transformar o código Smalltalk que você desenvolveu em código C++,
que podia então ser compilado em um ambiente de desenvolvimento Desta forma, ele se torna uma ótima referência para restauração
C++ similar ao SystemBrowser. A dificuldade de uso deste ambiente e as da imagem no caso de algum problema como o computador travar, a luz
limitações das classes C++ que “imitavam” as classes Smalltalk fizeram acabar ou o programador perfazer algo inimaginável.
a ParcPlace descontinuar o produto em 1992. A partir do VisualLaucher existe um ítem no menu chamado
Hoje em dia existe SPICE, que é um ambiente experimental para <Changes>. Seus subitens nos permitem manipular arquivos .cha e mui-
a conversão de código Smalltalk para C++. SPICE é um projeto de pes- tos outros tais como .pcl .st etc. Se nada ocorrer de anormal, não existe a
quisa e sua utilização é exclusivamente acadêmica. necessidade de se utilizar as ferramentas de manipulação de alterações,
mas caso o leitor sinta necessidade de saber como elas funcionam, con-
sulte a referência bibliográfica ao final deste capítulo.
3.17 Help do VisualWorks
VisualWorks é extremamente estável, mesmo a versão para Restaurando
Informações sobre Smalltalk e VisualWorks não são muito fáceis Microsoft Windows, e você dificilmente vai se encontrar em uma situação código e
de encontrar. não existe nenhum livro em portugues (além deste) e os onde há um error de acesso à memória ou outro que faça a máquina vir- instâncias
poucos que existem em ingles só cobrem até a versão 3 do VisualWorks. tual cair. Mas isso não é completamente impossível e sempre há as situ- após a queda
Na internet existem alguns sites bons (que listaremos ao final do livro), ações onde houve falta de energia durante uma sessão de edição ou do sistema
mas se o leitor se aventurar pelo altavista procurando a ermo, o que você saiu sem salvar o arquivo imagem. É possível restaurar o estado do
encontrará serão muitos sites superficiais e contendo crasos erros con- imagem, ou os método que foram editados foram perdidos ?
ceituais. Smalltalk, como foi dito, realiza um log de tudo o que você faz e
O help do VisualWorks é uma cópia resumida dos manuais mas o código de todos os metodos que você alterou através de <<accept>>
para uma consulta rápida ele se mostra bem eficiente. No caso do leitor fica registrado no arquivo de alterações .cha, mesmo que você não tenha
desejar uma explicação mais detalhada de alguma classe, existe uma salvo o imagem. Se você quiser restaurar o estado de seu imagem,
opção no system browser que mostra o comentário da classe. Todas as mesmo instâncias que foram criadas, tudo o que você precisa fazer é
classes da biblioteca de classes contém uma descrição. Elas podem ser reexecutar os comandos ou as alterações de código-fonte protocoladas
acessadas através do ítem de menu <View> >> <Comment>. Também no arquivo .cha. Suponha que você tenha iniciado uma sessão de desen-
podemos verificar os comentários das classes através de <Help> >> volvimento e tenha criado uma categoria “Teste”, onde você acabou de
<Object reference>. criar uma classe Teste como subclasse de ApplicationModel, conforme
mostrado na figura 3.27 .
&RQFHLWRV%iVLFRV
2. Abra a imagem visualnc.im e salve-a com outro nome.
3. Tente abrir outro VisualLaucher programacionalmente a partir do Capítulo 4
workspace.
4. Procure referências sobre o Transcript o help e tente enviar algumas
mensagens ao Transcript a partir do workspace. GD/LQJXDJHP
5. Utilize o mecanismo de busca de classes para encontrar as seguintes
classes:
OrderedCollection
Object
Point
ArraySet
(obs: Tente utilizar * e ? durante as pesquisas)
6. Crie uma categoria como apresentado anteriormente neste capítulo.
Crie em seguida uma classe chamada Fatorial, então crie o pro-
tocolo “aritimetica“ e adicione o método ‘fat: num’.
(obs: por enquanto apenas crie, no capítulo seguinte escreveremos o Este capítulo tem por objetivo apresentar ao leitor o básico da lin-
método, mas caso o leitor sentir vontade de tentar...). guagem Smalltalk. Inicialmente abordaremos o conceito de classes e obje-
7. Digite as seguintes parcelas de código no Workspace e inspecione-as tos visto pela ótica do Smalltalk. Em seguida discutiremos todos os
(use a opção inspect it). Verifique o que aparece no lado direito da mecanismos de orientação a objetos disponíveis, falaremos um pouco
janela de inspeção. Essa saída é criada pelo método printOn:. sobre a biblioteca de classes e sobre a filosofia de programação, apresen-
1) 10 taremos a sintaxe e características específicas da linguagem, discutiremos
2) 10.12 o conceito de namespaces e, por último, apresentaremos alguns objetos
3) Rectangle origin: 10@10 corner: 100@100 básicos e que são extensivamente utilizados durante o processo de pro-
4) |c| gramação.
c := OrderedCollection new.
c add: 10;
add: 20;
add: ‘st-80’. 4.1 Orientação a Objetos
c. Smalltalk é uma linguagem OO dita pura. Como apresentado no
8. Acompanhando a distribuição do Smalltalk vem uma série de parcels histórico da linguagem, podemos concluir que se trata da linguagem-mãe
e arquivos st de exemplos que podem ser facilmente carregados em do paradigma orientado a objetos e que influenciou todas as demais lin-
sua imagem. Consulte o help online (acessível através do Visual- guagens OO.
Laucher) e carregue alguns destes parcels. Isso lhe ajudara a se
familiarizar com a maneira como código em Smalltalk é escrito. O importante para o leitor (principalmente se o leitor já está famili-
arizado com alguma outra linguagem de programação OO), é notar e
registrar as diferenças entre os conceitos de orientação existentes em mente identificar uma dada instâncias como pertencente a uma certa
Smalltalk e outras linguagens tais como C++ e Object Pascal. Podemos classe mas sim permitir algumas otimizações em termos de espaço e
afirmar que os conceitos de OO em Smalltalk são simples. Perto dos performance que serão explicadas logo a diante.
detalhes existentes em C++ referentes a OO, Smalltalk pode parecer a Classes e Instâncias são conceitos tão primários em Smalltalk
primeira vista um tanto quanto simplória. Porém isso não é verdade. A que nos reportarmos a eles ainda divenças vezes durante o resto do
riqueza de expressividade em Smalltalk resize na seu alto grau de orto- livro, desta forma a não compreensão do conceito em sua plenitude
gonalidade1 e principalmente no fato de que absolutamente tudo em neste momento não deve preocupar o leitor.
Smalltalk são objetos.
Uma classe em Smalltalk além de ser um molde para a criação Classes
Classes x Para o leitor que ainda não está familiarizado com os conceitos de instâncias também é por si só um objeto. Isso pode parecer um tanto
instâncias de orientação a objetos, faz-se necessário uma clara definição e distin- quanto confuso a primeira vista, mas o que temos que tem sempre em
ção dos conceitos e nomenclatura que permeiam este paradigma de pro- mente quanto tratamos de Smalltalk é que tudo dentro de sua imagem
gramação. Caso o leitor já esteja familiarizado com tais conceitos, deve são objetos.
sentir-se à vontade para pular os próximos tópicos, no entanto, sugeri-
mos que sejam revistos, devido às nuâncias e pequenas diferenças aqui Uma pergunta pode estar perscrutando o leitor: Mas se até
apresentadas. mesmo uma classe em Smalltalk é um objeto, quem é a forma para cria-
ção de classes? A resposta, seguindo a regra básica de que tudo em
A seguir introduziremos brevemente o conceito de classes e ins- Smalltalk são objetos já deve ser imaginada. Obviamente um objeto.
tâncias, apresentaremos sua correlação e nas próximas seções deste Este objeto chama-se metaclassse e cria um mecanismo reflexivo que
capítulo descreveremos em maiores detalhes cada uma delas. permite ao Smalltalk adotar esta forma de mecanismo2.
Uma classe pode ser vista como um molde para a criação de Deixando um pouco de lado esta discussão sobre metaclasses
objetos/instâncias. Embora uma classe em Smalltalk não seja propria- visto o sua ínfima influencia para ações práticas de desenvolvimento
mente apenas um molde de criação, é importante que este conceito fique vamos entender como uma classe está organizada. Ela possui, exata-
registrado, e uma maior explanação do mesmo poderá ser encontrada mente como os objetos atributos, e métodos. Também está sobre a regra
mais a frente. do encapsulamento que dita que todos os seus atributos não podem ser
Uma instância/objeto é um conjunto de atributos (características acessados de fora da classe e todos os seus métodos são visíveis a
do objeto) e mensagens (que permite ao objeto perfazer ações úteis) qualquer um. Em geral, quando nos referimos a métodos e atributos de
agrupados todos sob uma “casca“ que os isola do resto do mundo. A uma classe falamos em variáveis de classe e métodos de classe.
este isolamento, dá-se o nome de encapsulamento. Uma classe não precisa e nem existe maneira de ser instanci-
Instâncias são criadas a partir de classes, e mantém uma refe- ada, ela é simplesmente criada. Seus atributos uma vez alterados per-
rência a sua classe criadora. O motivo desta referência não é unica- manecem com o novo valor até que eles sejam alterados novamente e
mesmo que a imagem seja fechada eles continuarão a armazenar o valor vel suportado que será discutida em detalhes no capítulo relativo à variá-
setado, desde claro que a imagem tenha sido salva previamente. veis.
Programar em Smalltalk consiste fundamentalmente em se criar
e refinar classes. As ferramentas utilizadas para a criação e edição de Instâncias de uma classe ou objetos que em verdade tratam do Instâncias
classes são os browsers. Daí a grande necessidade de se familiarizar mesmo conceito, são criados através do envio de uma mensagem de cri-
rapidamente com o seu funcionamento. Caso o leitor ainda não se sinta a ação a sua classe molde. Esta mensagem geralmente é new. Existe
vontade com o browser, reporte-se quantas vezes for necessário ao capí- alguns casos de objetos especiais também conhecidos como objetos lite-
tulo anterior. rais em que a instanciação se dá diretamente. Objetos literais serão
abordados em detalhes neste capítulo. Possuem mensagens e atributos
e são geralmente descritos como métodos me instâncias e variáveis de
instância. Estão como já dissemos sob a regra do encapsulamento e
podem ser criados a qualquer momento.
Como sabemos, instâncias de uma determinada classe pos-
suem atributos e respondem a mensagens através da execução de
métodos. Estes métodos por sua vez são parcelas de código que são
executados. Desta forma poderíamos imaginar que toda vez que uma
instância fosse criada, todo o código relativo aos seus métodos fosses
copiados também para o espaço de memória a ela destinado. Mas como
as instâncias são idênticas umas as outras em sua estrutura diferindo
apenas no valor de seus atributos, podemos ver que essa abordagem da
cópia de código a cada instância criada seria um grande desperdício de
espaço. Em verdade a Smalltalk não replica código a cada instância cri-
ada. Como já havíamos citado, quando uma instância é criada ela tam-
bém cria uma referência à sua classe fonte, desta forma e guarda como
um atributo especial, uma relação de todas as mensagens que ela
Figura 4.1 System Browser e opções classe, instância e variáveis compartilhadas conhece diretamente, ou seja que foram implementados na sua classe
criadora. Quando ela recebe uma mensagem, uma pesquisa é execu-
Na figura 4.1 vemos o System Browser, descrito no capítulo tada nesta lista de mensagens conhecidas, caso a mensagem recebida
anterior. Na terceira janela da esquerda para a direita vemos três botões conste na lista, uma requisição é enviada a classe fonte e o método cor-
de seleção. Dependendo de qual estiver selecionado, as informações respondente a mensagem recebida é executado. No caso da mensagem
apresentadas pelas janelas de protocolos e métodos do system browser, não constar na lista de mensagens implementadas na classe fonte, ela
mudam. Caso o botão instance esteja selecionado todos os protocolos e não é refutada diretamente, porém este segundo caso será apresentado
métodos relativos a instâncias serão apresentados, e em caso da sele- no momento em que explicarmos o mecanismo de herança e a hierar-
ção ser class os protocolos e métodos de classe serão apresentados. A quia de classes.
terceira opção, shared variables, diz respeito a um tipo especial de variá-
car várias técnicas como por exemplo padrões e facilita o entendimento No capítulo anterior citamos que a linguagem não gera um pro- Caracterís-
da estrutura de uma classe. grama executável. Em verdade isso acontece devido ao fato da lingua- ticas funcio-
gem ser interpretada. Uma linguagem ser interpretada significa que ao nais
compilarmos um programa (no caso do Smalltalk isso acontece toda vez
4.4 Métodos, mensagens e variáveis que selecionamos a opção accept) o compilador não gera instruções de
máquina, mas sim um código intermediário, código esse que chamamos
Método, mensagem e variável são três conceitos centrais em de ByteCode. Existem outras linguagens que também interpretam código
Smalltalk e bastante complexos e que necessitam de grande detalha- intermediário pré-compilado e organizado em bytecodes. Podemos citar
mento. Para apresentar ao leitor todas as nuâncias e detalhes pertinen- JAVA como a mais famosa de todas.
tes a estes conceitos, capítulos específicos foram escritos.
Quando compilamos um programa, instruções de máquina são
No Capítulo 5 deste livro tratamos de mensagens e métodos, geradas e estamos tornando o programa dependente da máquina que o
dois temas em Smalltalk tão intimamente ligados, que se confundem. executará, pois as instruções assembly que processadores da Intel reco-
No Capítulo 6 deste livro trataremos de variáveis em Smalltalk. nhecem são diferentes das instruções reconhecidas pelos processado-
Em Smalltalk toda variável é uma referência a um objeto, independente- res SPARC. Desta forma, gerando um código intermediário (ByteCode)
mente da complexidade deste, podendo ser apenas um Byte ou um tornamos nossos programas independentes da plataforma que os execu-
objeto extremamente complexo, representando todo o mecanismo de fin- tará, bastando para alcançar esta independência escrevermos interpreta-
cionamento de uma central hidrelétrica. Esta característica de Smalltalk dores específicos para cada máquina. Estes interpretadores são
‘we muito diferente das outras linguagens e porisso abordaremso variá- chamados de máquinas virtuais.
veis em um capítulo à parte. Outra característica interessante de Smalltalk é que a linguagem
não é tipada. Isso significa dizer que ao definirmos uma variável não pre-
cisamos dizer qual tipo de dado aquela variável poderá armazenar. Isso
4.5 Características da Linguagem provoca uma maior flexibilidade ao programas visto que as variáveis
poderão armazenar qualquer valor (no caso objetos) em momentos dis-
Como toda linguagem de programação, Smalltalk possui várias
tintos.
características relativas ao funcionamento da linguagem bem como à
forma como devemos escrever nossos programas. Como já dissemos, escrever programas em Smalltalk consiste
fundamentalmente em criar e editar classes. Criamos classes através de
De uma maneira geral podemos dividir tais características nos
um template como mostrado no capítulo anterior e de maneira análoga
seguintes sub-grupos:
criamos os métodos. Para tornar qualquer criação ou alteração válida
• características funcionais - relativas a como a linguagem precisamos aceitar nossas alterações. Isso é feito através de um popup
funciona. menu selecionado a partir do botão direito do mouse. O item de menu
• características léxicas - definem como os identificadores, ou responsável por este processo é accpet. Ele compila o código a ser
seja, métodos, variáveis, classes, etc, devem ser escritos. Sua
aceito e posteriormente o salva. desta forma, não existe em Smalltalk um
forma léxica.
operação específica para compilar código fonte como na maioria das
outras linguagens. Citamos esta característica da linguagem aqui por ser
bem diferente e também porque identificamos o processo de compilação Na tabela 4.2 apresentaremos algumas das convenções utiliza-
como uma das principais dúvidas existentes entre os programadores que das. Aqui as apresentaremos de maneira simplificada, cobrindo-as em
começam a aprender esta linguagem. maiores detalhes nos capítulos seguintes.
Caracterís- Com relação as características léxicas, ou seja, como os progra- identificador convenção exemplo
ticas léxicas mas em Smalltalk podem ser escritos, quais nomes de variáveis, méto- classes primeira letra em Maiúscula e a Carro
dos, classes, etc, são válidos, Smalltalk se mostra extremamente flexível. cada nova palavra também. Não se
Nas próximas linhas apresentaremos as poucas regras existen- usa _.
tes com relação a como é permitido escrever identificadores e quais as métodos primeira letra em Minúsucla e a trocaPneu
convenções adotadas pela biblioteca de classes. cada nova palavra uma maiúsula
iniciando. Não se usa _.
Com relação a que caracteres podemos utilizar para a criação
de nossos identificadores, sejam eles nomes de classes, métodos e vari- variáveis de instan- primeira letra em Minúsucla e a pneuReserva
cia cada nova palavra uma maiúsula
áveis, podemos utilizar os seguintes caracteres:
iniciando. .
a b c d e f g h i j k l m n o p q r s t u v variáveis de classe primeira letra em Maiúscula e a TipoPneu
x y z A B C D E F G H I J K L M N O P Q R S T U V cada nova palavra também.
X Y Z 1 2 3 4 5 6 7 8 9 0 _
NameSpaces sem restrições.
Também podemos utilizar qualquer símbolo de acentuação. A Categorias cada palavra inicia-se com maiús- Veículos-4Rodas
seguir apresentaremos alguns identificadores aceitos: cula. Pode-se usar - e _
estáRodando Protocolos tudo minúsculo. Pode-se usar - e _ initialize-release
_comendo Tabela 4.2 Convenções de nomeação em Smalltalk
Diferentemente de outras linguagens de programação onde mos que estes são os passos comuns que nós os autores utilizamos
escrevemos programas em forma textual e em seguida o submetemos à quando estamos programando e também tem surtido bom efeito no
um compilador para que erros sejam depurados e, ao fim de todo o pro- aprendizado da linguagem em cursos por nós ministrados.
cesso de depuração, um programa objeto seja gerado, em Smalltalk Os três passos por nós sugeridos são:
vemos uma maior interatividade, onde os programas são escritos, depu-
• Navegar
rados e executados de maneira concomitante.
• Editar/Criar
Diante desta abordagem de programação, bem como as facilida- • Inspecionar
des fornecidas pela não tipagem e também devido a ela ser interpretada,
podemos imaginar que Smalltalk seja uma linguagem muito boa para Como a biblioteca de classes e bem grande (algumas milhares Navegar
prototipação. Isso é verdade. A experiência mostra que o tempo de pro- de classes e algumas dezenas de milhares de métodos), se torna prati-
topitação em Smalltalk é extremamente menor se comparado ao tempo camente impossível sabermos exatamente que classe contém tal funcio-
gasto em outras linguagens de programação. nalidade e qual específicamente é o método desejado. Desta forma
Mas não é só neste aspécto que Smalltalk se mostra singular em devemos contantemente nos reportar à biblioteca de classes a procura
termos da maneira de se programar. Como sabemos, a linguagem é dita da funcionalidade desejada. O system browser possui a forma apresen-
orientada à objetos pura. Isso significa que como tudo nela são objetos, tada no capítulo anterior exatamente por causa desta necessidade de
características como reutilização de código e objetos sejam plenamente pesquisa constante. Desta forma se queremos saber se existe alguma
utilizadas. Programar em Smalltalk pode então ser visto mais ou menos função de exponenciação para números em ponto flutuante devemos
como bricar com um jogo de LEGO. Isso para aqueles que vêem a pro- executar uma pesquisa. Esta perquisa é facilitada então pela forma como
gramação como algo divertido e prazeroso. o system browser está organizado. Como sabemos que um pontos flutu-
antes são números temos uma indicação de que devemos procurar na
Além disso, a biblioteca de classes é extremamente madura,
parte referente a números da hierarquia de classes. Esta está sobre a
tendo cerca de 30 anos, podemos imaginar que ela seja extremamente
categoria Magnitude-Number. Assim fica fácil passearmos pelas classes
completa e útil, desta forma boa sempre que precisamos de alguma fun-
e métodos desta parte da hierarquia de classes e encontrarmos o
cionalidade em nossos programas devemos primeiro verificar a biblioteca
método ‘**’ .
de classes para ver se ela já não existe.
É muito comum os iniciantes no aprendizado de Smalltalk dize- Uma vez que não pairarem mais questões tais como se existe tal Editar/Criar
rem que a linguagem é complicada e que eles não conseguem criar pro- funcinalidade e de como podemos utiliza-las passamos para o passo em
gramas nela. De fato, as primeiras investidas de programação são um que devemos criar nossas classes e métodos.
tanto complicadas, pois para produzir programas em Smalltalk se faz
necesário conhecimento de que classes existentem na biblioteca de clas- Note que durante todo o processo de edição/criação podemos
ses e de como podemos utiliza-las. voltar a navegar pelas classes a procura de um funcionalidade ao para
sanar qualquer dúvida.
Diante deste quadro fornecemos uma filosofia de programação
dividida em 3 passos que devem ser seguidos para facilitar o programa-
A medida que vamos criando nossas classes e métodos pode- Inspecionar
dor novado em Smalltalk a produzir programas. Em verdade, observa-
mos verificar se elas estão correspondendo ao que desejamos. Desta
1298754609685407983876487236443489470958694567368 É interessante notar que podemos utilizar tanto “d“ como “D“
74564385468573235284385623856293485 para indicar que tal número é do tipo doublee também não é necessário
Como podemos ver no útimo exemplo citado, Smalltalk suporta utilizar escrever a parte fracionária do número caso ela seja zero.
números de tamanhos extremamente grandes. Na verdade não existe
um limite prático para qual o tamanho máximo um número inteiro pode Números fracionários podem ser criados digitando-se numera- Fraction
ter, o que acontece é que para números entre -536870912 e 536870911 dos/denominador. Note que se o resultado da divisão entre as partes
serão instancias da classe SmallInteger e para os demais inteiros tere- envolvidas for inteiro a um inteiro será gerado.
mos instanicas de LargePositiveInteger e LargeNegativeInteger. Por exemplo, se digitarmos 10/2 o SmallInteger 5 será gerado,
porém se digitarmos 10/3 uma instancias de Fraction é que será criada.
Float e Números em ponto flutuante, também conhecidos como con-
Double junto dos números reais na matemática, são representados em Smalltalk Podemos representar qualquer número também com relação a Números em
utilizando um ponto “.“ para separar a parte inteira da parte fracionária. A sua base. Base de um número indica qual o sistema numérico utilizado. outras bases
seguir apresentamos alguns exemplos: Dentre os mais utilizados temos o decimal que também é o padrão, o
120.0 binário e o hexadecimal. Porém Smalltalk nos permite utilizar qualquer
base numa faixa que vai de 2 ate 36. A forma de representação de núme-
-12121212.0123 ros em outras bases que não sejam a decimal é a seguinte:
Note que não é permitido escrever números em ponto flutuante <base> r <número>
omitindo-se nem a parte inteira nem a fracionária. Desta forma, 100.
implicará em se criar apenas um inteiro e seu programa ainda estará Quando tratamos de bases que possuam mais que dez dígitos,
sucetível a erros, pois o caracter “.“ também é utilizado como delimitador apenas os algarismos arábicos não são suficientes para representar
de comandos. todos os dígitos suportados pela base. Por exemplo se utilizarmos uma
base de dezesseis dígitos como no caso dos números hexadecimais, uti-
Existe um limite para números do tipo float.Eles devem estar lizamos os seguintes caracteres para representar cada um dos possíveis
dentro da faixa que vai de -1038 a 1038 . Caso necessitemos de uma pre- dígitos:
cisão maior podemos utilizar números do tipo double. Eles podem variar
em uma faixa que vai de -10307 a 10307 e são declarados exatamente
como os números em ponto flutuante porem sendo finalizados por uma
letra “d“. A seguir apresentamos alguns exemplos de números tipo dou-
ble:
10d
10.2d
1239831398.123213D
<número>e<potencia>
A seguir apresentamos alguns exemplos de números em forma Como podemos notar no último exemplo a aspa é representada
de potência, que também são conhecidos como números em notação duplicanda.
científica:
10e2
4.11 Booleanos
1232312.3232e132312
Existe, como já era de se imaginar apenas dois objetos boolea-
No caso de números do tipo double não podemos utilizar a letra
nos. um que representa o valor verdadeiro que no caso é true e o que
“e“ para inidicar que o número está elevado a um expoente. Em vez
representa o valor falso, denominado false. Eles são Instancias das clas-
disso, digitamos o expoente logo após a letra “d“. A seguir apresentamos
ses True e False respectivamente. Um erro muito comum quando esta-
alguns exemplos:
mos programando é digitar True ao invés de true. Isso significa que a Símbolo Comentário
classe está sendo referenciada ao invés do objeto.
#abcde começa com letra, então só aceita mais
Objetos booleanos são muito importantes e extensivamente utili- letras ou dígitos e _
zados em expressões lógicas e também são neles que alguns laços de #== começa com símbolo então só aceita mais
repetição e seleções condicionais são implementados. símbolos.
#’simbolo’ as áspas são desconsideradas em opera-
#’pneu radial’ ções com símbolos, porém se queremos
4.12 O Objeto Indefinido nil definir um símbolo com espaços, devemos
usá-las ao definí-lo.
O objeto nil é instancia única da classe UndefinedObject.
Tabela 4.4 Exemplos de simbolos válidos
nil é um conceito que Smalltalk herdou de LISP e vem do termo latim
nihil que significa “nada”. Quando criamos uma nova variável, ela por
Símbolo Comentário
definição armazena o valor nil, que significa que não referencia
nenhum objeto. Uma comparação possível, mas que não captura todo o #123adsas não pode começar com digitos
espectro do significado de nil é dizermos que nil corresponde ao #==10d não pode começar com caracter especial e ser
ponteiro nulo null em C++. seguido por digitos ou letras
Podemos explicitamente atribuir o valor nil a uma variável ##=== não se pode passar de dois caracteres especiais
caso desejemos que o objeto referenciado por aquela variável seja cole- Tabela 4.5 Exemplos de simbolos inválidos
tado pelo coletor de lixo. Note que isso só ocorrerá se nenhuma outra
variável referenciar também o objeto em questão.
4.14 Arrays
Arrays são literais que representam um coleção de objetos que
4.13 Símbolos podem ser acessados de maneira indexada. Qualquer outro objeto literal
Instâncias da classe Symbol são como strings porém possuem pode fazer parte de um array até mesmo outros arrays. A forma geral é
algumas propriedades adicionais. Eles não precisam estar delimitados apresentada a seguir:
por aspas como no caso de strings normais. Caso as aspas existam, elas #(<objetos literais separados por espaço>)
serão iguinoradas. O que caracteriza um símbolo é que ele sempre é
A seguir apresentamos alguns exemplos de arrays:
precedido por um símbolo #.
#($a $b $c $d $e $f)
Eles podem começar com letras ou caracteres especiais mas
nunca com números. Caso o símbolo começe com caracteres especiais #(1 2 3 4 5 6 7 8 9 0)
nenhuma letra ou dígito serão válidos, e caso ele comece com letras, #(1 2 3 $a ‘texto’ 12d2 1.1)
caracteres especiais não serão válidos. Abaixo apresentamos alguns
Existe um outro tipo de array suportado sob a forma de literal.
exemplos de símbolos válidos e outros inválidos:
Estamos falando de instancias da classe ByteArray. Objetos instancia-
dos a partir desta classe devem possuir apenas números inteiros vari- Esta é uma classe chave do Smalltalk e deve ser exaustiva-
ando de 0 a 255 como elementos e devem seguir a seguinte forma mente análizada durante o processo de aprendizado da linguagem. Mui-
padrão: tas das características desta tão importante classe serão abordadas no
#[<inteiros de 0 a 255 separados por espaço>] restante do livro.
A seguir apresentamos alguns exemplos de criação:
Pontos são utilizados exaustivamente pelo Smalltalk principal- Pontos
#[1 2 2] mente no que se refere a parte gráfica seja na criação de objetos gráficos
#[ 0 0 0 0 0 0 0 ou nos mais diversos pontos da linguagem. Podemos criar pontos de
0 0 1 1 0 0 0 diverças formas, mas a mais comum é enviando a mensagem binária
‘@<numero>’ à outro número.
0 0 1 1 0 0 0
0 1 1 1 1 0 0 ]
Instancias desta classes são muito úteis por exemplo para
manipulacão de imagens em tons de cinza utilizadas em informática
médica.
Object A classe Object é superclasse de todos os objetos em Smalltalk. Na figura 4.5 vemos a implementação da mensagem ‘@’ na
Ela define o comportamento básico e também muitos dos mecanismos classe número. Ela cria uma instancia da classe Point a sendo o valor do
importantes da linguagem. Nela encontramos a implementação do meca- número que recebe a mensagem correspondente a coordenada x do
nismo de dependência que será visto em detalhes mais a frente no livro, ponto e o argumento da mensagem ‘@’ a coordenada y.
também encontramos os métodos responsáveis pela cópia de objetos e
o mecanismo de impressão.
0HQVDJHQVH
Um ponto pode ser criado a partir de qualquer número perten-
cente a hierarquia da classe Number. Desta forma, todos os pontos Capítulo 5
apresentados abaixo são válidos:
10@13
12.2@1.1
0pWRGRV
12.5@2
(10/3)@2
Podemos notar nos exemplos acima que um ponto não precisa
necessáriamente ter suas duas coordenadas como números do mesmo
tipo, embora coordenadas de diferentes tipos de números sejam rara-
mente utilizadas.
4.16 Exercícios
Neste capítulo você vai aprender como funciona a estrutura
1. Procure onde é implementada a mensagem ‘flush’ na classe Ran- básica que determina o funcionamento de um objeto em Smalltalk: o
dom. método. Além disso, neste capítulo será visto como métodos são invoca-
2. Expanda a hierarquia de classes de AritimeticValue e procure todas dos através do envio de mensagens a objetos, sendo descrito o meca-
as implementações da mensagem ‘+’. nismo básico de comunicação entre objetos, o envio e rebebimento de
3. Procure a implementação das classes que representam os objetos lit- mensagens. Várias peculiaridades desta importante parte do Smalltalk
erais e navegue pelos seus métodos. serão aqui abordadas. As três formas básicas que um método/menságem
4. Identifique qual o tipo dos seguintes objetos: pode assumir (unária, binária ou por palavra chave) serão discutidas em
a) 12 g) -1246733221 detalhes bem como o mecanismo de encadeamento de mensagens e de
precedência entre as mesmas. Por fim vamos discutir bom estilo de pro-
b) -12 h) $a
gramação de métodos.
c) #abc i) $$
d) #= j) $ Primeiramente apresentaremos uma definição sólida do que vem Estrutura do
a ser uma mensagem e um método. O mecanismo de execução de uma capítulo
e) ‘Smalltalk’ k) ‘a’
mensagem é aqui explicado em detalhes visando uma maior compreenção
f) 1246733221 l) ‘=’ global do smalltalk pelo leitor. Em seguida apresentaremos uma série de
5. Discutimos muito sobre arrays neste capítulo, mas nada falamos convenções muito úteis para definir o tamanho ótimo que um método deve
sobre matrizes. Sugira uma forma de como poderíamos implementar assumir, como definir bons nomes para métodos e argumentos e também
matrizes apenas utilizando arrays. como organizar seus métodos em protocolos utiizando para isso exemplos
de soluções adotadas na própria hierarquia de classes do VisualWorks, e No restante deste livro utilizaremos os termos mensagem e
visando uma maior reutiização do código criado, aumento de método como sinônimos, mas o leitor deve ter em mente a diferença
manutenibilidade e legibilidade. A descrição do comportamento básico existente entre ambos.
que um método deve assumir será abordada a seguir, bem como os valo-
res de retorno que eles devem assumir.
Por fim diferenciaremos os método entre métodos de classe e 5.2 Mensagens Unárias
métodos de instância apresentando a teoria por traz de cada um deles,
Mensagens unárias são o tipo mais simples de mensagens.
as maneiras de manipula-los, vantágens e desvantágens e sutuações
Caracterizam-se por não possuírem nenhum argumento. Em geral dão
em que cada um se aplica.
idéia de uma ordem à um objeto.
Sintaxe:
5.1 Métodos X Mensagens <umObjeto> <umaMensagem>
Métodos e mensagens, em conjunto com os atributos, são par- onde <umObjeto> pode ser qualquer objeto instanciado e
tes fundamentais da orientação a objetos e tornam possível a estrutura também é conhecido como receiver e <umaMensagem> é qualquer
interna de um objeto. Porém uma pergunta pode estar incomodando o identificador válido de acordo com as regras vistas no capítulo 4. O
leitor. Qual a diferença entre um método e uma mensagem? exemplo 5.3 na página 103 apresenta algumas mensagens unárias.
A resposta é que objetos se comunicam através do invio e rece-
10 negated
bimento de mensagem e ações são executadas através de métodos.
256 fatorial
Para fazermo-nos mais claros, as menságens são o protocolo estabele- ScheduledWindow new
cido pelo qual os objetos se comunicam e os métodos são a implementa- OrderedCollection allInstances
ção destas mensagens. Desta forma quando executamos o exemplo 5.2,
Exemplo 5.3 Exemplo de mensagens unárias
o que ocorre é que a menságem rounded é enviada ao objeto tipo
Float 123.4 e em resposta ao recebimento desta menságem o método
‘rounded’ é executado. Como o leitor pode ver mensagens e métodos
tem sua grafia exatamente igual e para os programadores durante o pro-
5.3 Mensagens Binárias
cesso de criação de classes, a única preocupação está em definir os Mensagens binárias recebem este nome pois existem exata-
métodos, as existência das menságens são uma consequência direta da mente dois objetos envolvidos. Elas encontram um uso extensivo nas
criação de métodos. expressões aritméticas, aliás a maioria dos exemplos envolvendo este
tipo de mensagem são encontrados dentro das expressões aritméticas.
123.4 rounded Mas elas não são apenas usadas dentro deste contexto, são por exem-
Exemplo 5.2 Envio da mensagem “rounded” ao número ponto flutuante 123,4 plo usadas para a concatenação de strings e para a criação de relaciona-
mentos.
O Smalltalk é muito flexível com relação aos seus tipos de cons- + uma mensagem para executar a soma de dois objetos
trução. Desta forma é permidito a criação de menságens binárias da - esta para executar a subtração
maneira que o leitor bem quizer. -> usado em relacionamentos
Uma mensagem binária tem como forma básica: , usada para concatenação de strings
@ cria uma instancia da classe Point
<umObjeto> <umaMensagem> <outroObjeto> Exemplo 5.4 Símbolos comumente utilizados para compor mensagens binárias
<umObjeto> pode ser qualquer objeto instanciado e também
é conhecido como receiver, <umaMensagem> deve ser um símbolo
especial ou combinação deles respeitando as regras apresentadas na
tabela 5.1 na página 104.
Um dado interessante é que internamente o Smalltalk utiliza
símbolos para representar os nomes de métodos. Como menságens
binárias devem necessáriamente utilizar os simbolos especiais (caracte-
res de comparação e pontuação) a parte das regras para criação de sím-
bolos referente a utilização de caracteres especiais deve ser respeitada.
regra descrição
iniciar com caracter espe- qualquer mensagem binária deve iniciar com um dos
cial seguintes caracteres (! @ # $ < > = + - / * \ & ~ ,)
possuir apenas dois carac- uma mensagem binária deve ter no máximo dois caracte-
teres especiais res especiais
não possuir outros tipos de apenas são permitidos caracteres especiais na criação de
caracteres menságens binárias
Tabela 5.1 Regras para formação de mensagens
Por fim <outroObjeto> é o argumento passado ao receiver Figura 5.1 Implementação da mensagem binária +
pela mensagem. Ele, pode a priori ser qualquer objeto.
Dentre as classes da biblioteca de classes, encontramos várias
Em muitas linguagens estes símbolos são operadores aritméti-
mensagens binárias básicas que tem o seu uso consagrado. A tabela 5.2
cos com precedência de execução e função bem definida. No Smalltalk
na página 106 traz um resumo explicando os principais. O exemplo 5.5
não existe esta idéia de operadores aritméticos, tudo no mundo Smalltalk
na página 106 mostra como podemos utilizar mensagens binárias.
são objetos que se comunicam através de mensagens. Logo um número
também é um objeto que para se somar com outro numero deve mandar Para entender como as mensagens binárias funcionam, nada
uma mensagem para ele. A figura 5.1 mostra a implementação da opera- melhor que um exemplo. Como as expressões aritméticas são o exemplo
ção soma como um método associado a uma mensagem binária. mais comum de mensagens binárias, e serão extensivamente utilizadas
+ Mensagem para perfazer a soma entre de objetos ção infixada. Tomemos a expressão 10 + 2. O que temos aqui são dois
objetos, instâncias da classe Integer (10 e 2), e uma mensagem entre
- Mensagem para perfazer a subtração entre de objetos eles. Como devemos interpretar esta expressão ? O que ocorre na reali-
* Mensagem para perfazer a multiplicação entre dois objetos dade é que o objeto mais a esquerda (no caso o 10) recebe uma mensa-
/ Perfaz a divisão, e cria uma instância da classe Fraction, quando aplicado a gem ‘+’ para somar o seu valor com o valor do objeto que está sendo
dois inteiros passado por argumento (no caso o 2).
Uma Na primeira seqüência de operações do exemplo 5.5, a primeira a próxima mensagem da linha de comando será enviada a este objeto
mensagem é parte avaliada seria 10 + 2 e depois se avaliaria 12 * 4 resultando em 48, resultante.
enviada ao já no segundo exemplo primeiro se avaliaria 2 * 4 e depois se avaliaria 8 Se você já tem experiência de programação mas nunca progra-
resultado da + 10 resultando em 18. Logo descobrimos uma das primeiras regras do mou em Smalltalk nem em LISP antes, isto é bem diferente do que você
mensagem mecanismo de mensagem. Todas as mensagens são avaliadas da estava acostumado e necessita de um tempo para se acostumar. Mas
anterior esquerda para a direita. A frente veremos as outras regras. Esta regra é você vai ver que é muita mais intuitivo do que a forma tradicional à qual
muita fácil de se compreender se mantivermos em mente que o que você estava acostumado e que assim você programa de forma muito
acontece neste exemplo não é uma seqüência de operações em uma mais natural, muito mais próxima de sua forma de pensar. Mais sobre
linha de comando, mas sim uma seqüência de mensagens, cada qual esse tema você vai ver na seção sobre encadeamento de mensagens,
enviada ao objeto resultante da operação anterior. Lembre-se que fala- mais adiante neste capítulo.
mos que Smalltalk herdou de LISP a característica de que todo método
retorna um valor. Isto significa que o envio de uma mensagem a um
objeto, que acarreta a execução do método com aquele nome, devolverá
sempre o que foi definido pelo programador como sendo o valor de
5.5 Mensagens por Palavra Chave
retorno do método. Isto significa que, ao enviarmos uma mensagem a (keyword messages)
um objeto, teremos sempre um objeto como resposta. No caso aritmé- Até agora vimos mensagens sem argumentos (mensagens uná-
tico, quando definimos um método que implementa uma operação arit- rias) e mensagens com exatamente um argumento (mensagens biná-
mética, implementamo-lo de tal forma que devolve o resultado dessa rias). Então é de se esperar que mensagens por palavra chave sejam
operação. mensagens com possivelmente, mais de um argumento ? Sim. Mensa-
Observando essa filosofia, podemos ler o código do primeiro gens por palavra chave são mensagens que relacionam um identificador
exemplo 5.6 da seguinte forma: a cada argumento que se deseja passar para um objeto.
• enviar a mensagem + com 2 como argumento ao objeto inteiro Este tipo de mensagem é diferente das funções que encontra-
10 devolve como resultado o objeto 12; mos em C por exemplo. Em C, o método possui um nome e para cada
• é este objeto 12 que recebe a próxima mensagem, * , que é argumento existe um tipo e caso desejemos um nome para este argu-
enviada com 4 como argumento; mento. Em Smalltalk o nome do método é suprimido e as menságens por
• enviar * com 4 como argumento ao inteiro 12 resulta no objeto palavra chave são costruidas como segue.
48, que é o resultado final desta “linha de comando”.
A sintaxe básica de uma mensagem por palavra chave é a
A outra linha do exemplo 5.6 e todos os encadeamentos de seguinte:
mensagens binárias em Smalltalk funcionam da mesma forma. Na ver- <objeto> <ident1>: <arg1> <ident2>: <arg2> .....
dade, você pode usar isto como uma filosofia geral ao programar: o <identn>: <argn>
resultado do envio de qualquer emnsagem a um objeto é outro objeto2 e
Como podemos observar não existe um nome para a mensá-
gem, ela é diferenciada das outras pelo conjunto de palavras chave que
as compoe.
2. Ou o mesmo objeto, se o método em questão termina com ^self. Veremos isto adiante.
O limite de palavras chave que uma mensagem pode ter é 255, truídas. O exemplo 5.8 abaixo será usado para o entendimento do
porém não é aconselhável que se escreva métodos com tantos argumen- funcionamento do encadeamento de mensagens.
tos. Se um método desta magnitude é necessário, certamente ele pode
ser decomposto em outros tantos métodos. Esta é a prática corrente em 10 ** 2 + 1
programação orientada a objetos. No exemplo 5.7 podemos ver algumas Exemplo 5.8 Duas mensagens encadeadas
mensagens por palavra chave.
Vamos entender como a expressão acima é executada pelo
"aqui vemos que a mensagem só tem um argumento 10 mas a mensagem se Smalltalk:
caracteriza como keyword message pela existência do símbolo : a Quando o número 10 (instância da classe SmallInteger) recebe
frente da mensagem." a mensagem binária ‘**’ e o argumento 2, ele retorna o número 100,
(também uma instância da classe SmallInteger). O número 100 rebebe
index max: 10
a mensagem ‘+’ e o argumento 1, retornando finalmente o número 101.
"exemplo com dois argumentos" Fazemos questão de usar exemplos numéricos aqui para, por um lado
#(1 2 3 4 ’abc’ ’def’) copyFrom: 1 to: 3 conscientizar o leitor de que não existem tipos primitivos ou coisas simi-
lares em Smalltalk, mas sim que tudo é objeto, e mesmo números intei-
"exemplo de inclusão de um item em um dicionário" ros vão se comportar como objetos com métodos e respostas a
aDict at: ’abc’ put: 3 mensagens. Por outro lado queremos deixar claro que conceitos de lin-
Exemplo 5.7 Mensagens por palavra chave guagens estruturadas como precedência de operadores em Smalltalk
perdem o sentido, já que em Smalltalk todas as operações são mensa-
gens, não havendo operadores de nenhum tipo.
5.6 Encadeamento de Mensagens Agora veremos como uma mesma expressão pode fazer uso do
encadeamento de mensagens para torná-la mais simples. Temos uma
Já vimos que qualquer mensagem enviada para um objeto acar-
String ‘ST80’ composta por caracteres alfanuméricos e queremos extrair
retará no retorno de outro objeto. Isso permite o encadeamento de várias
a sub-string ‘80’ e transformá-la em um número negado. Tal intento pode-
mensagens em uma única expressão. Essa é uma das características
ria ser obtido como apresentado no exemplo 5.9 na página 111.
mais importantes do Smalltalk, faz-se necessário que o leitor tenha-a
sempre em mente. Ela foi herdada do LISP e fornece ao Smalltalk ótimas
|subString num|
características para sua aplicação em IA e processamento simbólico.
As expressões aritméticas fazem um uso extensivo do meca- subString := ’ST80’ copyFrom: 3 to: 4.
nismo de encadeamento de mensagens. Uma operação entre números num := subString asNumber.
sempre retornará um número, mesmo que ele mude de tipo, como por num := num negated.
exemplo uma divisão de dois inteiros poderá acarretar no retorno de um Exemplo 5.9 Exemplo sem a utilização do encadeamento de mensagens
número real, ma ele não deixará de ser número. Baseando-se nesta pro-
priedade dos números é que as expressões aritméticas podem ser cons-
A mesma tarefa, poderia fazer uso do mecanismo de encadea- ser que você não perceba de imediato, mas na segunda versão do
mento de mensagens e simplificar de maneira significativa o processo. código, tanto add: 1 como add: 2 são enviadas à mesma citação de
Esta nova versão pode ser observada no exemplo 5.10. ord no código. Na primeira versão do código, nós citamos ord duas
vezes, uma para receber a mensagem add: 1 e outra para receber a
|num| mensgaem add: 2.
Agora o que ocorreria se ao invés de criarmos a coleção antes
num := (’ST80’ copyFrom: 3 to: 4) asNumber negated.
de enviarmos a sequência de mensagens encadeada com a utilização de
Exemplo 5.10 Exemplo utiilzando o encadeamento de mensagens “ ; “ o que ocorreria ? O exemplo 5.12 ilustra esta situação:
"exemplo de cascateamento de mensagens usando yourself" 1. Como os parênteses alteram a ordem de execução a mensagem
|ord| ‘copyFrom:3 to: 4’ enviada para a string ‘ST80’ será executada
primeiro. Retornando a substring ‘80’.
ord := OrderedCollection new add: 1; add: 2; yourself. 2. A próxima mensagem a ser executada é a mensagem ‘asNumber’
Exemplo 5.13 Utilização da menságem ‘yourself’ (isso porque ‘asNumber’ e ‘negated’ são ambas menságem unárias)
obedecendo a regra 1 que dita que a execução é efetuada da
esquerda para a direita.
3. Finalmente a mensagem ‘negated’ é executada retornando um
5.7 Precedência de Mensagens SmallInteger valendo –80.
Como vimos até agora, no Smalltalk não existe o conceito de
precedência de operadores haja visto que nem existem operadores. Ao
invés de precedência de operadores encontramos um mecanismo de 5.8 Como a mensagem é executada?
precedência de mensagens. O mecanismo se baseia em 5 regras bem
Quando um objeto recebe uma mensagem, o Smalltalk verifica
simples que devem estar bem aprendidas entre seus conhecimentos
no dicionário de métodos da classe que define o objeto. Se um método
básicos de Smalltalk, afim de evitar maiores complicações posteriores.
com o mesmo nome da mensagem é encontrado no dicionário, o método
Elas podem ser vistas na tabela 5.3.
correspondente a mensagem é executado. Caso o um método de
mesmo nome não seja encontrado, o Smalltalk procura nas superclasses
regra descrição
da classe original, começando na classe logo acima e indo até encontrar
número 1 A avaliação de uma expressão é feita da esquerda para um método de mesmo nome que a mensagem. Se tal método não for
a direita encontrado, uma janela de exceção é aberta com a mensagem de que
número 2 As mensagens unárias tem a maior precedência aquele objeto não entende a mensagem enviada.
número 3 As mensagens binárias vem logo após as unárias em No exemplo 5.14 tentamos enviar para um objeto String uma
precedência mensagem que este objeto não "entende". O fato de o envio desta men-
número 4 Por último temos as mensagem por palavra-chave sagem resultar num erro, significa que nem este objeto nem um de seus
número 5 O uso de parênteses muda a precedência das mensa- pais na hierarquia de classe até Object implementa um método com o
gens e sempre será a precedência mais alta de todas, nome rounded.
sendo executado primeiramente os parênteses mais
internos. ‘Smalltalk’ rounded
Tabela 5.3 Regras de precedência de menságens Exemplo 5.14 Mensagem enviada para um objeto que não a implementa
Agora que já conhecemos as regras de precedência, reportemo-
nos novamente ao exemplo 5.9 na página 111. Os parênteses contidos A mensagem de erro gerada é mostrada na figura 5.2 na página
na expressão poderiam causar dúvidas até então. Analisando a expres- 116.
são seguindo as regras de precedência o entendimento as mesmas se
fará mais claro.
Para métodos tipo keyword messages, onde cada argumento devem ter o mesmo nome que o atributo a que eles destinam viabilizar o
tem o sua respectiva palavra chave valem as mesmas regras. Muitas acesso externo.
vezes nos deparamos com métodos que tem um nome bem elucidativo Como em alguns casos existe a necessidade de se retornar o
porém as palavras chave são paupérrimas semanticamente, e vice- valor de um argumento e também de se alterar seu valor dois métodos
versa. serão necessários. Desta forma, métodos de acesso são, em geral, cria-
Os métodos que retornam booleanos devem ter a aparência de dos aos pares. O exemplo 4.17 apresenta a implementação dos métodos
uma pergunta, e os métodos de converção de objetos devem ser prece- de acesso para o atributo idade de uma classe ipotética.
didos de palavras que mostrem que eles farão uma converção. Os
demais métodos deverão estar todos no modo imperativo. "método para acesso do atributo idade"
idade
"métodos que retornam booleanos" ^idade
isNil
hasData "////////////////////////////////////////"
ehInteiro
estaVazio "método de acesso para alteração do atributo idade"
idade: umaIdade
"métodos de conversão" idade := umaIdade.
asFloat Exemplo 5.18 Métodos de acesso a atributos
asOrderedCollection
comoInteiro No primeiro método vemos que a primeira ocorrência da palavra
Exemplo 5.17 Exemplos de métodos para conversão e que retornam booleanos idade é o nome do método unário e a segunda precedidada do caracter
de retorno “^“ faz referência a variável de instancia.
No segundo exemplo a primeira ocorrencia da palavra idade faz
5.11 Métodos para Acesso a Atributos parte do nome do método por palavra chave ‘idade:’ e a segunda ocor-
rência à variável de instanicia. A primeira vista pode parecer um pouco
Como vimos no capítulo anterior, um objeto é composto por atri-
confuso, mas a medida que o leitor for se acostumando com a biblioteca
butos e mensagens. Em Smalltalk todos os atributos são invariavelmente
de classes e com o Smalltalk verá que esta forma de construção de
privados, ou seja, não podem ser acessados fora do objeto, e todos os
métodos de acesso é muito prática e extensivamente utilizada.
métodos são públicos, ou seja, completamente visíveis de fora do objeto.
Desta forma, para se acessar atributos fora do escopo de um Basicamente, dividimos um método em identificador/palavras Qual o
objeto uma prática muito comumente adotada é se criar métodos de chave e código. A convenção adotada na biblioteca de classes é de que tamanho de
acesso a atributos. o tamanho do código deve girar em torno de sete linhas. Criando méto- um método?
Um dado interessante é que embora o Smalltalk não permite que dos com número reduzido de linhas o programador facilita a legibilidade
um objeto implemente dois métodos que tenham o mesmo nome, um e entendimento do código, além de tornar seu código mais reutilizável.
método e um atributo podem ter. Desta forma, métodos de acesso
Para o identificador a convenção foi descrita no tópico anterior. Neste exemplo o “estado” do objeto ordCol é alterado pois passa
Quanto ao número de argumentos, é costume que eles não devem ocu- do estado vazio para o estado contendo um objeto do tipo SmallInteger.
par mais que uma linha de código, ou seja, todos os argumentos do Métodos que devem ser evitados a qualquer custo, são aqueles
método devem caber na mesma linha do identificador. Embora o Small- que desempenham as duas funções, ou seja, que retornam algum objeto
talk aceite métodos com até 255 argumentos, a criação de métodos com significativo (entenda-se um objeto diferente de self) e que alteram o
muitos argumento cai novamente na pergunta? Será que este método estado do objeto que recebe a mensagem. Pode ser que em alguns
não poderia ser subdividido? As vantagens deste procedimento já estão casos isso seja extremamente necessário, mas tenha em mente que
mais que fomentadas neste ponto do livro. essa é uma prática pouco recomendada.
Na biblioteca de classes alguns protocolos são comumente utili- como as comumente encontradas em funções de uma linguagem estru-
zados. Na tabela 5.4 listaremos alguns deles mas saiba, pode-se criar turada, logo, comentários dentro do código se farão raramente necessá-
qualquer protocolo de método que lhe pareça conveniente. rios.
protocolo descrição
initialize- métodos de inicialização e finalização de objetos. Utilizados para 5.18 Métodos de Classe e Métodos de Instância
release configurações iniciais e finais e definição de valores padrão.
Ainda podemos subdividir os métodos em outros dois grupos.
accessing métodos para acesso a atributos. • Métodos de Instância
private métodos que não se deseja que sejam utilizados fora do escopo da • Métodos de Classe
classe, embora o protocolo não exerça nenhum efeito proibitivo ao Todo o conteúdo discutido anteriormente se aplica tanto a méto-
acesso, apenas sugere que não sejam usados.
dos de instancia quanto a métodos de classe. A diferença reside no fato
adding métodos de coleções para adição de novos ítens de mensagens de instancia só poderem ser enviados para instancias de
deleting métodos de coleções para remoção de ítens uma determinada classe, e mensagens de classe só poderem ser envia-
dos para a classe que as implementa.
printing métodos para impressão de objetos e de seus conteúdos
Quando uma classe recebe uma mensagem ela procurará a
arithmetic métodos para perfazer operações aritiméticas
implementação da mensagens diretamente entre os métodos de classe.
enumerating métodos para iterações numéricas Já quando uma instancia da classe receber uma mensagem ela procu-
comparing métodos para comparação de valores e comparações entre objetos. rará o método correspondente a mensagem dentre os métodos de ins-
Tabela 5.4 Protocolos comumente utilizados pela biblioteca de classes tancia.
No system browser do VisualWorks, a implementação dos méto-
dos de classe e métodos de instancia fica armazenada em locais distin-
5.17 Comentários tos, bastando selecionar entre as opções instance e class para ver e
edita-los.
Os Comentários proporcionam maior legibilidade para o seu
código. Por definição na biblioteca de classes, os comentários sempre Mas o leitor pode estar se perguntando por que existem métodos
vem logo abaixo do nome do método. Não se deve economizar no tama- de classe? A resposta é simples. Eles são utilizados para retorno de
nho de comentários. Se a complexidade da mensagem for grande constantes, para perfazer operações que não compensariam a criação
comentários minuciosos devem ser providos. de todo um novo objeto, e também para as operações de instanciação de
objetos do tipo da classe que os implementa e ainda de outras classes.
Porém não devemos comentar tudo que aparece pela frente.
Existem métodos tão simples, como os métodos de acesso a atributos,
ou métodos que se responsabilizam por tarefas tão simples que o próprio
nome já pode ser considerado um comentário. Prime por métodos curtos.
5.19 Exercícios
Como eles não terão muitas linhas, não terão operações intermediárias 1. Diferencie menságem de método.
Capítulo 6 9DULiYHLV
Smalltalk defineClass: #NameOfClass fico da instancia, podendo duas instancias da mesma classe tem número
superclass: #{NameOfSuperclass} de variáveis de instancia indexada distintos. Este tipo de variável é como
indexedType: #none um array, que relaciona um índice ao objeto que armazena.
private: false Vale resaltar que todas as variáveis de instancia indexadas de
instanceVariableNames: 'instVarName1 instVarName2' um objeto tem o mesmo tipo de valor, que é definido na criação da
classInstanceVariableNames: ''
classe. No campo indexedTipe especifique o tipo. Os mais comumente
imports: ''
utilizados são:
category: 'Collections-Sequenceable'
Exemplo 6.2 Definição de variáveis nomeadas
#object Para objetos genéricos
instancia de um objeto, faz-se necessário criar um método específico #byte Para bytes
para se encarregar desta tarefa. Por definição, na biblioteca de classes, Exemplo 6.4 Tipos das variáveis indexadas
estes métodos ficam agrupados no protocolo accessing e são como
Para acessar uma variável de instancia indexada, utilize a men-
segue.
sagem at: e para alterar ou incluir uma nova entrada utilize a mensagem
Imagine que na definição de uma classe que você está criando, at: put:
fez-se necessário criar uma variável de instancia chamada nomeDoCli-
Embora existam dois tipos distintos de variáveis de instancia,
ente. Os métodos de acesso para a variável seriam os seguintes:
faz-se necessário ressaltar que ambas podem conviver juntas, ou seja,
você pode Ter uma classe que tenha tanto variáveis de instancia nomea-
NomeDoCliente: umNome das como indexadas. Na figura 6.2 na página 138 vemos a definição da
“atualiza o nome do cliente”
classe OrderedCollection. Podemos ver que existem tanto variáveis de
nomeDoCliente := umNome
instancia nomeadas como indexadas.
nomeDoCliente
“retorna o nome do cliente”
^nomeDoCliente 6.5 Variáveis Temporárias a Métodos e
Exemplo 6.3 Criação dos métodos de acesso Argumentos em Métodos
Não existe problemas em se ter métodos e variáveis com o Variáveis temporárias são aquelas variáveis que tem um tempo
mesmo nome, e esta prática torna transparente a variável para quem for de vida curto. Para ser mais claro, são variáveis que só se fazem neces-
acessá-la. sárias durante um curto período de tempo seja dentro de um método
para operações intermediárias ou dentro de um bloco
É claro que as vezes você não deseja que sua variável de ins-
tancia seja acessada diretamente, neste caso, simplesmente não crie os A idéia de uma variável que seja criada, utilizada e depois des-
métodos de acesso para ela. truída serve para não sobrecarregar a memória do computador.
Já as variáveis indexadas não são nomeadas, e são acessadas Em métodos se declara variáveis temporárias, dentro de duas
através de um índice inteiro. O número de variáveis indexadas é especí- barras verticais, se existe mais que uma variável a ser declarada, seus
|bloco| mento para outro método, a única maneira de entrar dados dentro dos
bloco := [:arg1 | arg1 ** 2]. blocos é através de argumentos, visto que em outro método ele estará
bloco value: 10. fora do escopo em que foi criado.
|bloco resp|
bloco := [:arg1 :arg2 | arg1 + arg2]. 6.7 Variáveis de Instância de Classe
resp := bloco value: 10 value: 2.
(Class Instance Variables)
Exemplo 6.6 Variáveis temporárias em blocos
Uma variável tipo class instance armazena dados que variam
|bloco| com cada subclasse em uma hierarquia. A variável tipo class instance é
definida em uma classe e todas as suas subclasses a herdam, mas o
bloco :=[|resp respIntermed| valor é diferente e específico para cada sublcasse.
respIntermed := 256 / 17.
Não é muito comum a utilização de variáveis do tipo class ins-
resp := respIntermed asFloat.
]. tance, porém em alguns casos esta característica pode se mostrar bas-
bloco value. tante útil. Ela é declarada na definição da classe e só pode ser acessada
Exemplo 6.7 Outro exemplo de variáveis em blocos
por um método de classe. A seguir vemos um exemplo de como variáveis
tipo class instance podem ser utilizadas.
Outro dado interessante relacionando blocos e variáveis é o fato
de que dentro de um bloco as expressões internas “enxergam“ as variá-
veis externas dentro do método em que o bloco foi definido. Para ficar
mais claro, vamos lançar mão de um exemplo.
FALTA
"acessando variáveis em mesmo escopo dentro dos blocos"
"o resultado será o inteiro 110"
|index bloco|
index := 100.
[index + 10] value.
Exemplo 6.8 Mais um exemplo de variáveis em blocos
Exemplo 6.9 Utilização de variáveis tipo class instance
Você agora pode estar se perguntando porque então existe a
possibilidade de se passar argumentos para dentro de blocos? Os blocos
só conseguem ver variáveis que foram declaradas no mesmo escopo
que eles, isso quer dizer, que foram declaradas dentro do mesmo
método. Se existir a necessidade de se passar um bloco como argu-
Capítulo 7 %ORFRVHVWUXWXUDV
GHFRQWUROHH
VHOHomR
7.1 Blocos
Blocos foram pela primeira vez abordados no capítulo anterior no
momento em que falamos como funcionava seu mecanismo de variáveis.
Mas o conceito de blocos é muito mais amplo. Eles são usados extensiva-
mente nas estruturas condicionais e de repetição, em operações sobre
coleções controle de exceções, na criação e controle de processos e tam-
bém no mecanismo de tratamento de erros.
Basicamente, são parcelas de código Smalltalk, que podem ser
passadas como parâmetros para métodos e avaliadas a qualquer
momento. Dentro de um bloco qualquer tipo de expressão é aceita, inclu-
sive outros blocos. Eles também são extensivamente utilizados para se |bloco|
trabalhar com processos. "o resultado deste exemplo sera o valor da ultima expressão: 22"
Blocos são instancias da classe BlockClosure, e, como tudo no bloco := [
Smalltalk, subclasse de Object. Eles podem ser construídos diretamente 10 + 10.
apenas agrupando expressões entre os símbolos “[ ]” 20 + 2.
].
bloco value.
Funciona- Os blocos armazemam parcelas de código a serem executadas.
Exemplo 7.1 Retorna o resultado da operação matemática.
mento dos Mas para executar o conteúdo de um bloco precisamos explicitamente
blocos enviar uma mensagem ao bloco informando-o para que se execute. Blo-
|bloco|
cos aceitam uma grande diversidade de mensagens para executar sua
"o resultado deste exemplo será o valor da última expressão, no
validação, como podemos ver na lista de métodos abaixo:
caso, true"
•value bloco := [
•value: 10 + 10.
•value: value: 10 = 10.
•value: value: value: ].
•valueWithArguments bloco value.
•valueWithExit Exemplo 7.2 Retorna o resultado da comparação.
Caso um bloco seja encontrado durante a avaliação de um
que a mensagem de avaliação para blocos com mais de três argumentos
método e ele não receber uma das mensagens acima, ele simplesmente
(valueWithArguments:) receber como parâmetro um array de no máximo
será ignorado.
255 posições.
Partindo-se do princípio de que para avaliar um bloco precisa-
mos enviar uma mensagem para ele e de que todo método vai retornar
um objeto, é de se esperar algum retorno da avaliação do bloco. Mas o
7.2 Estruturas de controle e seleção
que exatamente ?
Por definição, os blocos sempre retornam a valor da última Estruturas de controle e seleção são geralmente implementadas
expressão avaliada. Abaixo dois exemplos de blocos. O retorno forne- utilizando envio de mensagens a instâncias das classes Number, Inte-
cido pela avaliação de cada bloco está em forma de comentário. ger, True, False, BlockClosure, e a praticamente todas as classes que
representam coleções.
Argumentos O esquema de argumentos e variáveis em um bloco já foram Existem as estruturas de seleção que são implementadas nas
e variáveis discutidos nos capítulos anteriores. Creio que o único dado relevante que classes True e False. Laços de repetição condicionais implementados a
foi deixado de lado anteriormente a esse respeito é o fato de que um partir também das classes True e False, laços de interação numérica
bloco aceita no máximo 255 argumentos. Este limite se dá pelo fato de implementados a partir das classes que representam os números e por
fim estruturas de interação sobre coleções, implementadas sobre pratica-
mente todas as classes que representam coleções.
Laços de Esse tipo de laço de repetição corresponde aos laços tipo for "mostra o valor da contagem no Transcript"
iteração presentes em outras linguagem de programação. Em Smalltalk, eles são 1 to: 100 by: 5 do: [: cont |
numérica implementados nas classes da hierarquia de números e possuem basi- Transcript show: (cont printString)
camente 3 formas: ]
• timesRepeat: Exemplo 7.4 Iteração com passo definido pelo programador
• to:by:do:
• to:do: "mostra o valor da contagem no Transcript"
A mensagem timesRepeat deve ser enviada a um inteiro e
100 to: 200 do: [: cont |Transcript show: (cont printString)]
recebe como argumento um bloco. Os comandos contidos dentro do
Exemplo 7.5 Laço com limites definidos pelo programador
bloco serão então executados tantas vezes quanto for o valor do inteiro.
Desta forma se enviarmos a mensagem timesRepeat: ao inteiro 3, o
Repetições condicionais são laços que são executados Laços de
bloco passado como argumento será executado 3 vezes. No exemplo 7.3
enquanto uma condição é satisfeita. No Smalltalk, estes laços são imple- repetição
na página 150 a seguir apresentamos um exemplo de laço utilizando
mentados por mensagens enviadas a instâncias da classe BlockClo- condicionais
esta mensagem.
sure. Existem 5 tipos de laços, representados na tabela 7.1.
"Escreve 10 vezes Smalltalk no Transcript"
método descrição
10 timesRepeat: [Transcript show: ’Smalltalk’] repeat Repete continuamente até que o bloco force a saída
Exemplo 7.3 Forma mais simples de uma estrutura de repetição usando mensagens whileTrue Repete enquanto o bloco retornar verdadeiro. Teste no final da itera-
ção
A mensagem to:by:do: também é uma variante do laço for
whileFlase Repete enquanto o bloco retornar falso. Teste no final da iteração
onde podemos indicar qual o passo a ser adotado durante as iterações
do laço. Ela deve ser enviada a um inteiro recebendo como argumentos whileTrue: Repete enquanto o bloco retornar verdadeiro. Teste no início da itera-
ção
outro inteiro indicando qual o ponto de parada, outro inteiro indicando o
passo a ser adotado e um bloco contendo os comandos a serem repeti- whileFalse: Repete enquanto o bloco retornar verdadeiro. Teste no início da itera-
dos pelo laço. O bloco a ser passado deve esperar um argumento (como ção
vimos no capítulo referente a variáveis). Este argumento conterá o valor Tabela 7.1 Tipos de laços condicionais
atual da contagem, e mesmo que não seja usado deve ser declarado. No Os métodos repeat, whileFalse e whileTrue são mensa-
exemplo 7.4 a seguir apresentamos um laço de repetição utilizando a gens enviadas a um bloco e não possuem argumentos.
mensagem to:by:do:.
Os métodos whileTrue: e whileFalse: são também méto-
Por último veremos o laço implementado pela mensagem dos enviados a um bloco mas tem como argumento outro bloco, sendo
to:do:. Este é uma versão simplificada do laço implementado pela que o bloco que recebe a mensagem é testado a cada nova iteração e é
mensagem to:by:do:. A diferença está no fato de que o passo é sem- a condição de parada.
pre constante e de tamanho 1.
O funcionamento de ambos os 5 laços de repetição condicionais Outro dado interessante, é que as seleções condicionais são,
é bem simples, sendo inclusive ‘whileTrue’ e ‘whileFalse’ definidos em como tudo termos de estrutura de controle da linguagem em Smalltalk,
relação aos métodos whileTrue: e whileFalse:, respectivamente. mensagens e são definidas na classe Boolean. Boolean é uma classe
Eles usam os conceitos de avaliação de blocos exaustivamente. Para dar abstrata e superclasse de outras duas, a classe True e classe False,
uma olhada na implementação, selecione a classe BlockClosure e pro- onde são implementados os métodos de seleção condicional descritos
tocolo controlling. Vale a pena dar uma olhadinha. abaixo:
No exemplo 7.6 vemos um trecho de código para cada tipo de • ifTrue:
laço condicional. • ifFalse:
• ifTrue: ifFalse:
"exemplo de utilização do método whileTrue" • ifFalse: ifTrue:
|c| Como o funcionamento destes métodos é intuitivo, apresenta-
c := 0. mos no exemplo 7.7 diretamente alguns trechos de código para o leitor
[Transcript show: ('numero' , c printString ).
se familiarizar.
Transcript cr.
c := c + 1.
c < 10] whileTrue. "exemplo de utilização da mensagem ifFalse:"
extremamente flexíveis e facilita muito a criação de código, simples, intui- "exemplo de detect: "
tivo e compacto. #[1 2 3 4 5 6 76 8 9 ] detect: [: each| each == 2]
Exemplo 7.9 Código para encontrar um elemento igual a 2 numa lista
7.3 Iterações sobre Coleções O método select: permite filtrarmos os itens de uma coleção select:
criando uma nova coleção. Por exemplo podemos utilizar este método
A parte da hierarquia de classes que define a grande variedade
para sabermos quantos espaços possui uma string. este exemplo é mos-
de coleções é sem sombra de dúvida um dos pontos fortes do Smalltalk.
trado a seguir:
Uma das características que fazem-na tão boa é a facilidade de manipu-
lação de dados conferida por alguns métodos implementados nestas
"exemplo de select:"
classes. A seguir apresentaremos algumas destas características e em
('Smalltalk é uma ótima linguagem OO' select: [:char|
seguida alguns exemplos.
char == (Character space) ]
Existem vários métodos para realizar a iteração sobre os objetos ) size.
contidos nas coleções. Abaixo apresentamos uma lista deles: Exemplo 7.10 Código que retorna o número de caracteres-espaço em uma string
•do:
•detect: O método reject: é exatamente o oposto ao select:. Veja- reject:
•select: mos o mesmo exemplo anterior apenas alterando a mensagem e tere-
•reject: mos a contagem de todos os caracteres na string que não são espaços.
•collect:
"exemplo de reject:"
do: O método do: avalia o bloco passado como argumento ao ('Smalltalk é uma ótima linguagem OO' reject: [:char|
método para cada elemento do conjunto. O bloco deve possuir um argu- char == (Character space) ]
mento também, que referenciará o item da coleção selecionado a cada ) size.
iteração. Exemplo 7.11 Código que retorna o número de caracteres não brancos em uma string
"exemplo de utilização do método do:" O método ‘collect:’ permite-nos criar uma nova coleção a partir collect:
#[1 2 2 3 4 5] do: [: each| da coleção original ajustada a uma regra de validação passada dentro do
Transcript show: (each printString)] bloco que é esperado como argumento. O seguinte exemplo mostra
Exemplo 7.8 Código para impressão de todos os elementos de uma lista como podemos passar toda uma string para maiúsculas.
detect: O método detect: avalia uma expressão contida no bloco pas- "exemplo de collect:"
sado como argumento ao método para cada elemento da coleção até 'Smalltalk é simples' collect: [:char | char asUppercase]
encontrar um elemento que satisfaça o bloco. Neste caso o elemento Exemplo 7.12 Código que retorna uma nova string contendo a string receptora em maiúsculas
que satisfez a expressão contida no bloco é retornado, caso nenhum ele-
mento da coleção satisfassa a expressão, um erro é gerado.
7.4 Exercícios
1. Faça um programa no workspace que calcula o fatorial de um
Capítulo 8 0DQLSXODomRGHDUTXLYRV
número. Teste-o para números grandes como por exemplo 100.
2. Crie um método que calcule o fatorial de maneira recurciva. Lembre-
HHVWUXWXUDVGHDFHVVR
VHTHQFLDO
se da classe criada anteriormente.
3. Qual é o número máximo de argumentos que podem ser passados
para um argumento ? De que forma eles são passados ?
4. Nos exercícios do capítulo 4 propomos uma questão onde gostaria-
mos de saber como criar matrizes apenas utilizando arrays. Agora
crie uma classe que implemente esta matriz e crie alguns métodos
úteis tais como calcular a matriz inverça, métodos para operações
como multiplicação e soma de matrizes, etc.
5. Navegue pela hierarquia de classes de coleções e inspecione seus
métodos a procura de outros métodos para iteração de coleções.
8.1 Introdução
Como o sistema de arquivos é muito particular à cada sistema
operacional, o Smalltalk implementa classes especializadas a partir da
classe Filename para cada sistema operacional. Abordaremos as referen-
tes aos sistemas Windows e Unix/Linux.
Também veremos a utilização de instâncias de Stream para a ExternalReadWriteStream, é responsável pela criação de streams para
manipulação seqüencial de coleções, sejam elas, instâncias de Ordered- a manipulação de arquivos.
Collection, Array, ByteArray, String ou do conteúdo de arquivos em Nesta primeira parte do capítulo daremos ênfase ao primeiro dos
disco lidos para a memória. ramos, deixando o segundo para a seção que trata especificamente de
arquivos.
A outra forma de se criar stream consistem no envio de uma Ao abrirmos a stream para leitura vemos que a posição inicial é
mensagem para a coleção. Existem quatro mensagens definidas na zero, sendo que ao enviarmos a mensagem next, o dado na posição 1
classe SequenceableCollection (que também é superclasse de String é retornado.
além de ser de Array e OrderedCollection) que nos permitem cirar stre-
ams. São elas: |stream arr|
readStream - cria uma stream a partir da coleção especifi-
arr := #(1 2 3 4 5).
cada, apenas para leitura
stream := arr readWriteStream.
writeStream - cria uma stream a partir da coleção especifi- stream next. "---> 1"
cada, apenas para escrita e exclui os dados pré-existentes na coleção. stream nextPut: 6.
stream contents. "---> #(1 6 3 4 5)"
readWriteStream - cria uma stream a parir da coleção
especificada para leitura e escrita e mantém os dados originais da cole- Exemplo 8.4 Criação de uma stream para leitura e escrita e inclusão de um novo elemento
ção posicionando a stream para escrita no seu final.
Note que neste exemplo o elemento na posição 2 foi sobrescrito,
newReadWriteStream- cria uma stream a parir da coleção pois mandamos que o SmallInteger fosse adicionado na próxima posicao
especificada para leitura e escrita e exclui os dados originais da coleção. da stream que no caso era a 2, já que havíamos posicionado a stream na
primeira posição com a mensagem next.
|stream arr|
|stream arr|
arr := #(1 2 3 4 5).
stream := arr writeStream. arr := #(1 2 3 4 5).
stream contents. "---> #()" stream := arr newReadWriteStream.
Exemplo 8.2 Criação de uma stream habilitada para escrita stream next. "---> nil"
stream nextPut:10.
Neste exemplo podemos ver que o conteúdo da coleção é exclu- stream nextPut:11.
ído quando criamos a stream para escrita. stream reset.
stream next. "---> 10"
|stream arr| Exemplo 8.5 Usando um array como novo stream de leitura-escrita apagamos seu conteúdo
arr := #(1 2 3 4 5). No exemplo 8.5 podemos ver que a mensagem newRea-
stream := arr readStream. dWriteStream exclui o conteúdo anterior da coleção. Nos exemplos
stream next. "---> 1 " anteriores apareceram várias mensagens que ainda não foram devida-
stream next. "---> 2" mente especificadas. Não se preocupe, elas serão cobertas ao longo do
Exemplo 8.3 Criação de uma stream somente para leitura capítulo.
Streams As facilidades de se utilizar streams para a manipulação de cole- Quando estamos trabalhando com strings é que vemos como as Streams
sobre ções são muitas. Quando você teve um primeiro contato com coleções streams podem ser úteis. Por exemplo, nos casos onde desejamos fazer sobre strings
coleções em Smalltalk, garantidamente uma das primeiras estruturas de dados pesquisas sobre strings para encontrar um determinado caractere. Pode
que você utilizou foi o Array. Ele tem uma limitação muito séria, seu parecer besteira, mas essa é uma das aplicações que mais ocorrem em
tamanho é fixo. Ao utilizarmos uma stream para manipular os dados de programação. Utilizando os métodos tradicionais implementados na
um array adicionamos a capacidade ao array de almentar o seu tamanho classe string você terá um bocado de trabalho, já lançando mão da solu-
diretamente. A alternativa sem a utilização de streams é cirar um novo ção de streams, boa parte do trabalho estará otilizado. O programador
array contendo todos os dados antigos e o novo dado. Outra grande faci- que alguma vez escreveu um scanner em uma linguagem de programa-
lidade é você não ter de se preocupar com os índices criando os fatidicos ção sabe do que estou falando. É realmente um saco escrever código
laços de repetição com a famosa variável “i” para incrementar o índice. para manter um pesquisa um pouco mais complexa em uma string.
As streams em geral, tem a facilidade de sempre adicionar os novos Outra grande vantagem da manipulação de strings através de
dados ao seu final, porém caso seja necessária uma alteração de algum streams está centrada na performance. Quando concatenamos duas
dado do meio da stream, também é possível perfze-lo. strings usando a mensagem binária "," , em geral o que acontece é que
O seguinte código mostra como podemos adicionar novos dados uma nova string é criada contendo os dados das duas strings pré-exis-
a uma coleção pré-existente. tentes. A solução da classe Stream para isso é em geral mais rápida,
mas pense bem, a vantagem está no fato de stream nao criar um novo
|stream arr| objeto, mas sim apenas aumentá-lo. Para poucas concatenações de
strings o método "," é bem recomendável, mas quando o número de con-
arr := Array new:1. catenações cresce e se deseja performance o uso de uma stream é
arr at:1 put: 1. indispensável. Vale resaltar que quando formos utilizar streams para
stream := arr readWriteStream. fazer concatenações de strings devemos ter uma string de um tamanho
stream setToEnd. bom como string inicial a partir da qual criamos a stream. Se criarmos
stream nextPut:6. uma stream a partir de uma string vazia, ela deverá crescer várias vezes
Exemplo 8.6 Incluindo dados em um stream préexistente para perfazer as concatenações. Neste caso, o processo será muito cus-
toso. Uma boa aplicação de concatenação de strings via stream é
Além disso, vale saber que quando criamos uma stream a partir
quando estamos compondo querys em SQL. O número de concatena-
de uma coleção, ela guarda qual é o tipo de coleção sob a qual foi criada,
ções é muito grande em geral. No exemplo 8.7 na página 164 apresenta-
desta forma podemos utilizar a mensagem contents que nos retornará
mos um exemplo para a criação de uma query.
uma nova coleção do mesmo tipo que a original e com as alterações fei-
tas pela stream. As mensagens para aproveitar estas características são:
stream contents.
Nesta seção as coisas se tornarão mais claras. Nos exemplos Lendo,
stream contentsSpecies. anteriores vimos como criar streams e também as peculiaridades ineren- escrevendo e
tes a streams sobre coleções e strings. Como o funcionamento de leitura, posicio-
A mensagem contentsSpecies retorna a classe da cole- escrita e reposicionamento em stream é de certa forma trivial, limitar-nos- nando uma
ção sobre a qual a stream foi criada. hemos a apresentar os principais métodos relativos a tais operações e stream
uma breve descrição sobre cada um deles. Para fomentar o seu aprendi-
|filename nomeDoDir dirCaminhoStr| código deste exemplo num workspace e executá-lo passo a passo, ins-
pecionando os resultados para ver o que acontece.
dirCaminhoStr := 'C:\vw5i.3nc\image'.
nomeDoDir := dirCaminhoStr asFilename. |nomeArq caminhoArq|
local correto. De qualquer forma, serve como um exemplo para entender Como podemos ver e já foi citado, instâncias de Filename nada
o mecanismo de criação de refeências de arquivos. mais são que uma referência a um arquivo existente ou que será criado,
os manipuladores ou handles de arquivo. No final das contas você pode
|stream arrayDirNames| estar pensando por que criamos uma instância de um objeto apenas
para referênciar um arquivo que pode nem existir ainda. Por que não
arrayDirNames := #('c:' 'vwnc5i.3' 'image' 'arq.txt'). usamos uma string logo de uma vez já que os tais Filenames parecem
stream := (String new: 30) writeStream. tanto com elas ? A resposta é que os Filenames nos fornecem várias
arrayDirNames do:[:cada| capacidades para verificar dados do sistema de arquivos do sistema
streamnextPutAll: cada; operacional tal como se ele é case sensitive ou qual o sistema de arqui-
nextPut: Filename separator. vos tais como os famigerados FAT, FAT32, ou NTFS. Além disso, tam-
].
bém implementa as mensagens para a abertura do arquivo por ela
Filename named: stream contents.
referenciado, coisa que soaria mutio anti-OO de ser implementada na
Exemplo 8.10 Construindo o nome e caminho de arquivo a partir de seus elementos
classe String. Dessa forma, a classe Filename cria uma coisa extrema-
Uma instância de Filename parecem em muito com uma lista em mente importante: transparência a sistema operacional nas suas aplica-
LISP. Elas são compostas por um head (cabeça) e um tail (cauda). Onde ções. Mais a frente veremos estes métodos que justificam a existência
a cabeça é o caminho em que o arquivo se encontra e a cauda é o nome da classe Filename.
do arquivo. A classe Filename também implementa diversos métodos
para verificarmos as partes que compoem o caminho do arquivo. O
exemplo 8.11 mostra alguns destes métodos. Experimente digitar o
|aStream dimX dimY magicNumber max imagem valor posi cores| 2. Procure a implementação da classe SortedCollection e analize a
implementação da mesma. Em seguida crie uma parcela de código
aStream := (ExternalReadStream on: (FileConnection que gere 10 números aleatoriamente no intrervalo de 1 a 10 e adici-
openFileNamed: 'imagem.pgm' mode: #readOnly one estes números a uma sorted colection. Por fim imprima seu resul-
creationRule: #noCreate)). tado no Transcript.
"Lê o magic number e testa se o arquivo é do formato certo"
magicNumber := aStream upTo: (Character cr).
(magicNumber = 'P5') ifFalse: [ aStream close.
self error: 'Formato errado'. ^nil.].
aStream skipSeparators.
"Vamos ler a linha de comentário e jogar fora"
aStream upTo: (Character cr). aStream skipSeparators.
"Vamos ler as dimensões X e Y da imagem"
dimX := Integer readFrom: aStream.
aStream skipSeparators.
dimY := Integer readFrom: aStream.
aStream skipSeparators.
"Vamos ler quantas tonalidades de cinza tem a imagem"
max := Integer readFrom: aStream. aStream next.
"Criamos a tabela de cores da imagem com base em max"
posi := 1. valor := 0. corres := Array new: (max + 1).
[valor < max]
whileTrue: [cores at: posicao put:
(ColorValue brightness:(valor/max)).
valor := valor + 1. posi := posi + 1].
"Passamos a ler o arquivo de forma binária"
aStream binary.
"Criamos a imagem como instância de imagem de 8 bits"
imagem := Depth8Image
extent: dimX@dimY
depth: 8
palette: (MappedPalette withColors: cores)
"Lemos o resto do arquivo como pixels"
bits: aStream upToEnd.
aStream close.
imagem inspect.
Exemplo 8.14 Código para ler um bitmap de tonalidades de cinza em formato PGM
Capítulo 9 0HFDQLVPRGH
'HSHQGrQLFD
Quando um objeto pai sofre uma alteração, ele envia uma men-
sagem para self (ou seja, ele mesmo) notificando a ocorrência de alguma
alteração em seu estado. Automaticamente, os objetos dependentes são Pai A Pai A Pai B
notificados sobre a alteração no objeto pai e podem tomar as devidas
providências. Não existe a necessidade do objeto pai sabem quais são (dependência) (dependência) (dependência) (dependência)
seus dependentes. Apenas os objetos com interesse especifico em
algum objeto pai, devem se registrar como seus dependentes.
Filho A Filho B Filho A
classe Object também seja invocado. Isso garante que todas as depen- protocolo descrição
dências serão corretamente excluídas.
contém mensagens como changed e broad-
Ainda existem outras mensagens que nos fornecem informações changing cast:. Em suma contém as mensagens de
úteis sobre o estado das dependências. Para sabermos quais são notificação
dependentes de um determinado objeto podemos utilizar a mensagem métodos de acesso aos dependentes. Contém
dependents. dependents access mensagens como addDependent: , remove-
ObjetoA dependents. Dependent: e expresInterest:
Essa mensagem retornará um array contendo todos os objetos outros métodos mais avançados referentes ao
dependents collec-
dependentes do objetoA. mecaniso de dependência. São bem pouco
tion
usados
Tabela 9.1 Protocolos dos métodos referentes ao mecanismo de
dependência
9.3 Onde são Definidos os Métodos do Mecanismo
de Dependência? • Métodos do grupo changed.
• Métodos do grupo updated.
O mecanismo de dependência é implementado na classe
Object. Porém ainda existem outras classes que especializam o meca- Cada um dos métodos contigos nos grupos citados acima for-
nismo de dependência. Um exemplo é a classe Model, vista mais adi- nece uma maneira diferente de por para funcionar o mecanismo de
ante. dependência. Variando no grau de informação sobre a alteração. Eles
funcionam em pares.
A base dos métodos está na classe Object. Fica claro que como
todos os objetos, na hierarquia de classe são filhos de Object, qualquer A mensagem changed: recebe como parametro um símbolo.
objeto pode implementar o mecanismo de dependência. Quando ela é invocada, sendo enviada para o próprio objeto pai (self
changed: anAspect), todas os objetos dependentes são notificados
Caso o leitor sentir necessidade de inspecionar os métodos que recebendo a mensagem update: , que recebe como argumento a mesma
implementam o mecanismo de dependência, deve reportar-se a classe variável (anAspect) enviada para a mensagem changed:. No método
Object. tabela 9.1 indica o que cada protocolo desta classe abriga em se update: (objeto dependente), deve ser colocado o código referente a
tratando de métodos relacionados ao mecanismo de dependência. ação esperada perante uma alteração no objeto pai. O aspecto (anAs-
pect) serve como uma informação sobre o motivo da alteração e é defi-
nido pelo objeto pai, podendo ser qualquer símbolo. Caso você não veja
9.4 Mensagens updated e Mensagens changed necessidade de informar para os objetos dependentes o motivo pelo qual
a alteração ocorreu, mande simplesmente a mensagem changed. Ela
Existem dois grupos básicos de mensagens que implementam o
agirá como se você estivesse mandando a mensagem changed: com nil
mecanismo de dependência. São as mensagens que informam a ocor-
como argumento. Em verdade, se o leitor for curioso poderá procurar a
rência de uma alteração no estado da classe pai, métodos changed, e o
implementação da mensagem changed na classe Object, lá veremos
grupo das mensagens acionadas nos objetos dependentes, em decor-
que o que changed faz é chamar o método changed : nil.
rência da alteração do objeto pai, os metodos updated.
As outras mensagens de changed e updated tem a mesma fun- algumaMensagem é enviada para todos os seus dependentes.
ção apenas tendo um argumento a mais, e no caso da mensagem upda- Também pode ser utilizada a forma:
ted: with: from: o último argumento é o objeto que recebeu a broadcast: #algumaMensagem with: aParameter
mensagem, no caso, a classe pai.
Um problema deste mecanismo é que todas as mensagens de expressInter-
atualização (changed) são enviadas para todos os dependentes. Então estIn: for:
os dependentes precisam implementar uma das mensagens da família sendBack:
de atualização (update) e checar por um símbolo particular que foi envi-
ado.
Isto pode ser eliminado utilizando-se a mensagem expressIn-
terestIn: for: sendBack: ao invés de addDependent: para o
objeto pai. Neste método, é solicitado ao objeto pai para expressar um
interesse em uma mudança particular e enviar uma mensagem especí-
fica quando ele vê o símbolo associado com a mudança. Isto é confuso
porque se poderia esperar que o dependente é quem deveria expressar
interesse pelo objeto pai. Entretanto, a sintaxe é tal que os dependentes
informam ao objeto pai para expressar um interesse pelo dependente.
Para remover o interesse deve ser enviada a mensagem:
pai retractInterestIn: #number for: self
Um ValueModel é um wrapper em torno de um valor, ele arma- A classe Model será exaustivamente vista no capítulo que trata
zena o valor. O valor não pode ser diretamente atualizado, isso somente no modelo MVC.
pode ser feito através do ValueModel. Pelo fato do ValueModel ter
esse controle da mudança ele pode notificar os dependentes da altera-
ção. Para alterar o valor deve ser utilizada a mensagem value: com o 9.7 O mecanismo de dependência e o modelo MVC
novo valor como parâmetro.
Certamente o uso mais comum do mecanismo de dependência
ValueModel>>value: newValue
no VisualWorks é observado no modelo MVC (Model-View-Controller,
self setValue: newValue.
visto mais adiante). É sobre o modelo MVC que as aplicações gráficas
self changed: #value são construídas no VisualWorks, e o mecanismo de dependência é utili-
ValueHolder é a subclasse mais simples de ValueModel. zado para manter a comunicação entre as três partes do modelo.
3URFHVVRVH
mensagem odd. Por fim, utilize o mecanismo de dependência para
resolver este exercício. Capítulo 10
5. A classe Model implementa o mecanismo de dependência de outra
maneira. Qual a vantágem de se implementar o mecanismo de
dependência como a classe Model o faz? 6HPiIRURV
10.1 Processos
Processos são uma maneira de executar e controlar múltiplos pro-
gramas independentes rodando ao mesmo tempo. Seja entendido por pro-
cesso uma aplicação inteira ou apenas parte de um programa.
Tome uma aplicação de tratamento de imagens gráficas como
exemplo de aplicação do conceito de processos. Algoritmos de manipula-
ção de imagens, geralmente demoram segundos ou até mesmo minutos.
Ao aplicar um destes algoritmos a uma imagem, um método será invo- versões e na família NT é que esta característica começou a funcionar a
cado para executar a operação. Da maneira tradicional, sem a utilização contento. Os algorítimos por traz do mecanismo de escalonamento de
de processos, seu programa iria ficar executando o algoritmo e outras processos são complexos sendo assunto de cadeiras como sistemas
funcionalidades da sua aplicação ficariam travadas. Se criarmos um pro- operacionais e programação paralela não sendo abordados neste livro.
cesso para executar o algoritmo de tratamento da imagem, ele será exe- Não devemos então confundir processos do Smalltalk, com pro-
cutado em segundo plano deixando sua aplicação livre para perfazer cessos de um sistema operacional.
outras tarefas. Quando o processo terminar, o resultado poderá então ser
apresentado. Sobre sistemas operacionais “preemptivos reais”, como Unix/
Linux , o Smalltalk tem a possibilidade de criar processos do sistema
Funciona- O mecanismo de processos no Smalltalk é o que chamamos de operacional, mas para tal não fazemos uso dos conceitos de processos
mento dos “parcialmente preemptivo”. Isso significa dizer que dois processos não internos ao Smalltalk (utilizando a classe Process), mas sim usamos
processos são executados em paralelo, e sim que eles obedecem certas regras de uma classe específica para funcionar com processos externos sobre tais
prioridade para cadenciar sua execução. sistemas (UnixProcess).
|proc|
proc resume.
Exemplo 10.2 exemplo de criação de processos através do envio da mensagem newProcces
exemplo 10.5 mostra como um processo pode ser retirado da fila de exe- será suspenso momentaneamente e o bloco passado como argumento
cução. será executado. Ao termino da execução do bloco o processo será nova-
mente retomado.
|p|
|p|
p := Process forBlock: [1 to: 200 do: [:cont| Transcript show:
(cont printString , ' '). (Delay forMilliseconds: 1) wait]] p := Process forBlock: [1 to: 200 do: [:cont| Transcript show:
priority: 50. (cont printString , ' '). (Delay forMilliseconds: 1) wait]]
p resume. priority: 50.
(Delay forMilliseconds: 100) wait. p resume.
p suspend. (Delay forMilliseconds: 100) wait.
[100 timesRepeat: [Transcript show: 'processo 2']] fork. p interruptWith: [100 timesRepeat: [Transcript show: '*']].
p resume. Exemplo 10.7 utilização da mensagem interruptWith:
o funcionamento básico do mecanismo apenas observando estas duas mativo ele é colocado na fila compartilhada sq. Como o esquema de pro-
classes. cessos em smalltalk não é preenptivo real devemos utilizar a mensagem
yield para dar chance que outros processos também possam ser exe-
cutados. A partir do momento que a mensagem yield é executada o
10.7 Filas Compartilhadas processo 2 se torna ativo ele pede a fila compartinhada pelo seu primeiro
dado, ela retorna o mesmo e ele é impresso. Ao final dacontagem o pro-
Quando desejamos que processos se comuniquem, o primeiro cesso 1 se encarrega de finalizar o processo 2.
passo a ser tomado é a abertura de um canal de comunicação entre eles.
Este canal é aberto instanciando um objeto da classe SharedQueue e |sq p1 p2|
informando os processos a se comunicarem sobre a existência do canal
de comunicação. A classe SharedQueue utiliza semáforos para sincroni- sq := SharedQueue new.
zar a comunicação entre os processos. p1 :=[ 1 to: 100 do:[:cont| (cont odd) ifTrue: [sq nextPut: cont].
O canal de comunicação é normalmente unidirecional, sendo Processor yield ]. p2 terminate] fork.
p2 := [ [true] whileTrue: [Transcript show: (sq next printString),
que um dos processos envia as informações e o outro as recebe.
' ']] fork.
Exemplificando, imagine dois processos Processo1 e Exemplo 10.8 comunicação entre processos atraves de filas compartilhadas
Processo2. Queremos enviar informações do Processo1 para o
Processo2. O primeiro passo é criar uma instancia da classe Shared- Filas compartilhadas também podem ser utilizadas para comuni-
Queue para perfazer a comunicação entre os processos. Em seguida, cação de dados entre vários processos, porém ela não define de maneira
criamos o primeiro processo e utilizamos a mensagem next para espe- alguma prioridades entre os processos para acesso a fila. Simplesmente
rar que o outro processo envie um objeto. Criamos então o segundo pro- qualquer processo pode colocar e retirar dados de uma fila comparti-
cesso que utiliza a mensagem nextPut: que envia o objeto passado nhada.
como parâmetro na mensagem para o primeiro objeto. Note que quando Além dos métodos next e nextPut: existem ainda outros
uma instancia da classe SharedQueue recebe a mensagem next, o métodos muito úteis na classe SharedQueue. Existe por exemplo o
processo corrente fica em estado de espera até que a mensagem nex- método peek que permite que um processo verifique o dado do começo
tPut: seja enviada a partir de outro processo. da fila sem no entanto o retirá-lo de lá. Outro método de extrema impor-
Note que SharedQueue se comporta como uma fila FIFO, sem tância é o size que fornece o número de objetos na fila.
descartando qualquer informação relativa a prioridade dos processos
envolvidos. O primeiro processo a ser agendado como em estado de
espera na instancia de SharedQueue será o primeiro processo que 10.8 Semáforos
receberá um objeto passado para a SharedQueue
A classe Semaphore permite um sinalização sincronizada entre
No exemplo 10.8 vemos a utilização de filas compartilhadas para
processos. Entenda por sincronizada, uma comunicação que não é feita
comunicação entre dois processos. O processo 1 possui um contador
em tempo real, mas sim através de sinais que indicam quando as coisas
que vai de 1 a 100. Durante o processo de contagem, perfaz-se um teste
devem ocorrer.
para verificar se o numero corrente da contagem é impar, em caso afir-
Podemos ver o funcionamento de instâncias da classe Sema- semáforo eles vão entrando no final da fila. O primeiro sinal recebido
phore como uma analogia do funcionamento dos semáforos de transito. libera o primeiro processo em estado de espera. Este processo de fila
Eles sinalizam como o transido deve fluir, e em que sentido, dependendo também é conhecido como FIFO(first in first out), ou seja , o primeiro a
de alguns sinais, tais como sinal verde e sinal vermelho. entrar é o primeiro a sair.
No Smalltalk, semáforos são usados por um processo para sina- É interessante ressaltar que a Classe semáforo não se preocupa
lizar quando outro processo deve continuar. Também são empregados como a prioridade dos processos e sim apenas com a ordem em que
quando um determinado processo deve ficar em estado de espera até eles entraram na fina. Abaixo, um exemplo mostrando a ordem de execu-
que algum recurso seja liberado ou algum evento esperado aconteça. ção dos processos controlados por um semáforo.
Como exemplo imagine uma classe que tivesse como atributo
um nome. Toda vez que este nome fosse alterado, o novo nome deveria
ser mostrado no Transcript. Mas como informar quando o nome foi alte-
rado? É claro que poderíamos, neste caso inserir a linha de atualização F A L T A
do nome no Transcript diretamente no método que altera o nome, mas
digamos que isto não seja possível. Então só nos resta usarmos um
semáforo. Criamos um processo para mostrar o conteúdo do atributo Exemplo 10.10 Ordem de execução
nome e toda vez que ele for alterado, uma mensagem é enviada para o
semáforo avisando que o valor de nome foi alterado e deve ser mostrado O funcionamento básico de semáforos se baseia em 3 mensa-
no Transcript. gens, uma para criar um semáforo, outra para incluir um processo na fila
de espera e finalmente um mensagem para liberaro primeiro processo da
fila.
F A L T A New
Cria um novo semáforo.
Capítulo 11 &DSWXUDH
7UDWDPHQWRGH
([FHo}HV
ração ilegal. As linguagens de programação de última geração se de acesso a recursos do sistema computacional que podem estar em uti-
preocupam particularmente com este requisito, fornecendo desta forma, lização por outro processo e que requerem acesso exclusivo.
muitas ferramentas para um bom gerenciamento de erros. Como não
poderia deixar de ser, Smalltalk implementa um ótimo mecanismo de Existem outros casos onde uma determinada parcela do pro- Espera à
erros que permite ao programador abstrair muito do código relativo ao grama assume que outra já foi executada. Por exemplo a inicialização de ocorrência de
tratamento de erros e se ocupar quase que exclusivamente com o pro- uma variável de classe. Caso este evento não tenha ocorrido, um erro eventos
blema a ser resolvido programacionalmente. pode vir a ocorrer.
Com a crescente popularização e cotação de importância a
engenharia de software após a crise do software, muita pesquisa foi Erros lógicos por sua vez, são aqueles gerados por uma opera- Erros lógicos
desenvolvida para tornar o software escrito reutilizável, facilitar a manu- ção matemática ilegal como por exemplo uma divisão por zero, ou o no código
tenção, gerenciamento de alterações e uma atenção toda especial foi envio de uma mensagem desconhecida a um objeto.
dedicada para o esquema de deteção e tratamento de erros. Podemos O mecanismo do Smalltalk utiliza a idéia de signals e handles,
ver no decorrer deste livro, que Smalltalk se enquadra muito bem nos onde um sinal é um objeto especializado capaz de tratar um determinado
requisitos mais cotados pela engenharia de software, pois devido a OO tipo de erros.
pura adotada pelo smalltalk, temos a reutilização de código maximizada,
No Smalltalk o mecanismo de exceção é baseado em duas clas-
devido a sua sintaxe simples, as possíveis manutenções em um pro-
ses base: Exception e Signal. A idéia básica por traz do mecanismo é
grama também ficam facilitadas, o gerenciamento de alterações (ou con-
que tando a sinalização de um exceção como a posterior captura do
trole de versões) possui uma ferramenta poderosa no Smalltalk. O ENVY,
mesmo e feita por uma classe do ramo de Signal. A tarefa das classes
facilita em muito este trabalho.
do ramo de Exception é responsável por gerenciar a exceção, ou seja,
Neste capítulo então veremos que o tratamento de erros não foi que ações tomar quando ele ocorrer.
neguigenciado pelo Smalltalk, estando compatível com o utilizado pelas
Este mecanismo embora ainda suportado pelo Smalltalk já se
mais modernas linguagens de programação.
encontra obsoleto sendo mantido unica e exclusivamente por motivos de
compatibilidade, descreveremos o mesmo pois existe a possibilizade do
leitor ter de fazer manutenção em códigos existentes que utilizem o
11.2 Tipos de Erros mecanismo antigo, mas tenha em mente que quando antes o esquema
Podemos dizer que existem basicamente três situações onde de Exceções deve ser mudado para o novo modelo, pois o Cincom não
erros podem acontecer. garante que o suporte a sinais será mantido por muito tempo.
• Recursos indisponíveis No esquema novo tanto a sinalização, a capitura e a informação
• Espera à ocorrência de eventos relativa à exceção ocorrida são responsabilidade de uma classe da hie-
• Erros lógicos no código rarqua de Exception.
Erros são um tipo especial de exceção que pode ocorrer em
Recursos Chamamos de recursos indisponíveis tentativas de abertura de uma aplicação. Uma exceção nada mais é que um fato que desejamos
indisponíveis um arquivo para escrita que já se encontra aberto, ou qualquer outro tipo
GenericException
Error Na figura 11.2 vemos que o método 1 possui uma rotina de trata-
mento de erros. O código deste método executa o método 2 que por sua
Figura 11.1 Hierarquia de classes reduzida das exceções
vez executa o método 3 que por sua vez executa o método 4. Durante a
execução do método 4 um erro ocorre. Como não existe nenhuma rotina
de tratamento de erros no método 4 o erro sinalizado neste método per-
corre a pilha de execução do método 4 para o método 1 onde encontra
11.3 Mecanismo de Tratamento de Erros um sinal capaz de trata-lo. Teoricamente, este mecanismo pode parecem
O interessante do mecanismo de tratamento de erros adotado um tanto quanto abstrato. Caso o leitor não esteja certo de ter entendido,
pelo Smalltalk é que se assume de antemão que tudo que o programador reportece ao exemplo 11.1.
programou vai funcionar. Mas como nada é perfeito, dificilmente esta Este é um exemplo completo onde criamos uma classe que
situação ideal irá ocorrer. Ai entra o mecanismo de tratamento de erros, representa o clock de um computador. Ela tem hertz como variável de
ele fica a escuta de sinalizações de erros. Quando algum é encontrado instancia que é a abstração da velocidade do clock. No método initialize
ele o trata. incluímos a rotina de tratamento de erros. Ela consiste na criação de um
Desta forma não precisamos incluir código de tratamento de sinal que no caso utilizamos um sinal genérico definido na classe Object
erros para cada método, basta que algum método na pilha de execução (mais sobre este sinal a frente). De posse da instância do sinal utilizamos
seja capaz de trata-lo. A figura 11.2 mostra como funciona a busca recur- a mensagem handle: do: que espera como argumentos dois blocos.
siva pela pilha de execução. No primeiro vai a rotina que deve ser executada caso algum erro ocorra.
Já na segunda vai o código do método propriamente dito. Este esquema "TEMPLATE PARA CRIAÇÃO DA CLASSE"
se refere ao mecanismo antigo onde utilizavamos sinais para tratar os Smalltalk defineClass: #NameOfClass
erros ocorridos. No novo modelo devemos criar uma instancia de uma superclass: #{NameOfSuperclass}
das classes da hierarquia de Exception e enviarmos a mensagem on: indexedType: #none
do: para ela. private: false
instanceVariableNames: 'instVarName1 instVarName2'
Para testarmos nosso exemplo podemos avaliar a seguinte
classInstanceVariableNames: ''
expressão no workspace:
imports: ''
Clock new: 10. category: 'Exemplos'
O que acontecerá? Como inicializamos a variável hertz com 0 "MÉTODOS DE CLASSE"
quando tentarmos dividir 1 por ela, um erro será sinalizado pois tentamos new: hertz
|inst|
dividir um número por zero. Como no método período não existe
inst := super new initialize.
nenhuma rotina de tratamento de erros, o sinal percorrerá o caminho
inst hertz: hertz.
oposto a pilha de execução passando então para o método initialize ^inst.
que foi o método que invocou período. Veremos mais exemplos a "MÉTODOS DE INSTANCIA"
frente neste capítulo, então caso o leitor não entenda o exemplo em sua initialize
plenitudo, não se desespere. (Object errorSignal)
Como este método possui uma rotina de tratamento de erros o handle:[:ex|
erro sinalizado no método periodo será tratado sendo então executado Dialog warn: (ex errorString).
]
o bloco passado como parametro para a palavra-chave handle.
do: [
hertz := 0.
Transcript show: (self periodo printString).
11.4 Sinais ].
hertz
Como dissemos anteriormente sinais são um recurso obsoleto e ^hertz
que apenas é mantido na biblioteca de classes por um motivo de compa- hertz: novaFrequencia
tibilidade. Um sinal trabalha em cooperação com uma exceção para pro- hertz := novaFrequencia
ver uma resposta particular para um tipo específico de erro. Por exemplo, periodo
um sinal deve ser desenvolvido para perceber um erro de uma divisão
por zero. ^1 / hertz.
Na verdade, a classe ArithmeticValue é definida como um sinal. Exemplo 11.1 Tratamento do erro divisão por zero
Cada sinal é normalmente criado por uma classe que se preo- classe DivisionByZero é acessível pelo método divisionByZero.
cupa com um tipo específico de erro. Claro que estamos falando de clas- Este esquema possibilita que aplicações acessem qualquer sinal que
ses especializadas da hierarquia de classes dos sinais. Por exemplo, a
estes são sinais padrão que devemos utilizar como base para criar nos- |a b|
sos próprios sinais como veremos nas próximas seções. a := 10.
b := 0.
classe evento [a / b]
ArithmeticError erro ao avaliar uma expressão matemática on: GenericException
do: [:ex| Dialog warn: 'ocorreu um erro'].
Error Qualquer erro em um programa
Exemplo 11.2 Outra forma de capiturar exceções
MessageNotUnderstood Uma mensagem é enviada a umobjeto que não imple-
menta um método correspondente Ao executar o código do exemplo 11.2 veremos a janela apre-
Notification Um evento inusual mas que não impede a execução do sentada na figura 11.4 . Como podemos ver nenhuma janela de Exceção
programa padrão foi aberta e esta, é sem dúvida uma maneira muito mais profissio-
Warning Um evento incomum que o usuário deve ser informado nal de apresentação de exceções em um aplicativo final.
sobre.
ZeroDivide Quando se tenta dividir um numero por zero
Tabela 11.1 mais comuns subclasse de Exception
divisão por zero, mensagem desconhecida earquivos inacessíveis, são Uma outra abordagem é criar uma heirarquia de classes, uma
todas préviamente suportadas. subclasse da outra e por sua vez a de mais alto nível subclasse de uma
Caso não escrevamos uma rotina para tratar esters possíveis das classes da hierarqua de Signal. Como sabemos que uma classe pai
erros, em última instância a classe Object as capturará e tratará utili- possui a capacida de capiturar as exceções que suas classes filhas
zando o tratador padrão citado anteriormente neste capítulo. Como esta gerenciam, usamos a classe de mais alto nível para executar esta tarefa.
solução não é nem um pouco profissional, devemos criar nossos próprios
sinais para gerenciar de maneira adequada nossas exceções.
11.10 Exercícios
A maneira mais simples de se criar um sinal é enviando a men-
sagem errorSignal para a classe Object. Ela por sua vez, retronará 1. Procure a classe Exception no System Browser e selecione a obção
uma instância da classe Error, que como pdemos ver na hierarqua de Spawn hierarchy. De posse do browser de classes expandidas, dese-
classes simplificada mostrada na figura 11.1 , é subclasse deGenericer- nhe a árvore de classes das exceções.
ror. 2. Citamos neste capítulo que existem diverças maneiras de se obter
uma instancia da classe Error. Procure a implementação das manei-
Como sabemos, Smalltalk é uma linguagem extremamente ver-
ras apresentadas e verifique que em suma todas são realmente
sátil, desta forma existem várias maneiras de fazer a mesma coisa. O
equevalentes.Justifique.
exemplo 11.7 mostra maneiras equivalentes para perfazer a mesma
3. Na classe clock apresentada neste capítulo, crie um sinal para sinali-
tarefa cumprida pelo comando Object errorSignal.
zar quando a freqüência exceder o valor de 100MHz. Abra uma
janela de aviso para indicar ao usuário a exceção ocorrida.
Object errorSignal newSignal 4. O seguinte fragmento de código se utiliza o esquema antigo de trata-
Signal new mento de erros. Como possivelmente ocorrerá durante processos
Exemplo 11.7 maneiras alternativas de se cirar uma instancia padrão de Error onde haja a necessidade de fazer manutenção em códigos pré-exis-
tentes, traduza-o para o novo esquema de tratamento de erros.
Podemos organizar nosso mecanismo de tratamento de diver-
|cont|
ças formas. A mais simples é utilizar apenas um sinal para tratar todos os
erros ocorridos em uma aplicação. A segunda abordagem é utilizar (Object errorSignal)
vários sinais, um específico para cada tipo de exceção ocorridae por fim handle:[:ex| Dialog warn: 'Erro!!!!']
utilizar uma coleção de sinais. do:[cont := 0.
Como dissemos anteriormente, podemos utilizar apenas um Transcript show: cont ].
isnal para tratar todos os erros de uma aplicação. Podemos então utilizar Identifique também qual a causa do erro e corrija-o se possível.
um sinal genérico para todas as exceções. Esta abordagem funciona
muito bem para pequenas aplicações porém fornece muito pouco con-
trole sobre os diverços tipos de exceções que possivelmente poderão
ocorrer.
Capítulo 12 6XSHUItFLHVJUiILFDV
FRQWH[WRJUiILFRH
SULPLWLYDVJUiILFDV
Este capítulo tem por objetivo apresentar ao leitor o mecanismo série de primitivas para a converção da informação gráfica em diretivas
de funcionamento deste rico framework. Abordademos inicialmente o do sistema gerenciador de janelas utilizado pela plataforma.
conceito de superfícies gráficas explicando sua função. Em seguida Em geral instâncias da classe DisplaySurface raramente serão
apresentaremos alguns dos objetos gráficos suportados pelo framework, úteis, mas vale a pena dar uma olhada na implementação desta classe, o
construindo alguns exemplos para elucidar os conceitos. Dentre os obje- conhecimento de sua funcionalidade pode facilitar em muito tarefas mais
tos apresentados estão textos, figuras, linhas, polígonos, icones e curso- avançadas em manipulação de informação gráfica.
res. Esta parte da biblioteca de classes, é onde as diversas
implementações de Smalltalk diferem. Como nós escolhemos Visu- Seja qual for a superfície gráfica em questão, elas sempre
alWorks como implementação Smalltalk de referência para este livro, necessitarão de uma instância da classe GraphicsContext como inter-
muitos dos exemplos que nós vamos prover neste capítulo não vão funci- mediária para a apresentação de qualquer objeto gráfico. A classe Gra-
onar totalmente sem problemas em Visual-Age ou Squeak. phicsContext gerencia alguns parâmetros gráficos tais como espessura
de linhas e será vista em detalhes mais a frente neste capítulo. Mesmo
Executando Os exemplos providos neste capítulo dependem para fun-cionar para impressão, você necessita de um contexto gráfico: Smalltalk imple-
os exemplos de você ter carrregado o parcel ExamplesBrowser que vem com a dis- menta uma classe chamada PostScriptGraphicsContext1 para a gera-
deste capí- tribuição padrão de VisualWorks. Usamos o método prepareS- ção de arquivos em formato .ps, que podem ser enviados a impressoras
tulo cratchWindow da classe ExamplesBrowser para abrir uma janela laser para impressão ou usados para gerar documentos PDF. Na pró-
simples onde vamos desenhar. Incluir código para abrir uma janela no xima seção vamos examinar o contexto gráfico padrão em detalhes.
exemplos os tornaria demasiado longos e desviaria a atenção do que
queremos mostrar. O código deste método é bastante simples e você Instâncias da classe GraphicsContext e suas subclasses ser- Contexto
pode dar uma olhada nele e entender facilmente o que ele faz. vem como um intermediárias entre a superfície gráfica e os objetos gráfi- gráfico
cos por ela mostrados. Esta classe se responsabiliza por vários outros
parâmetros gráficos como por exemplo a espessura das linhas, a fonte
padrão a ser utilizada pelos textos gráficos ou a cor padrão.
12.2 Superfícies Gráficas
Nenhum objeto gráfico é diretamente apresentado em uma
Para que qualquer informação gráfica seja apresentada na tela superfície gráfica. Tudo o que se quiser apresentar deve ser repassado
ela deve ser direcionada para uma “superfície de apresentação”. Existem para o contexto gráfico. Existem vários métodos para apresentação de
três tipos de superfícies de apresentação no VisualWorks. Elas estão lis- objetos específicos ou para a apresentação genérica de um objeto supor-
tadas a seguir: tados por uma instância de GraphicsContext. O contexto gráfico tam-
• Janelas bém suporta mensagens para a alteração de parâmetros gráficos.
• Pixmaps ou matrizes de pixels
Como a apresentação de vários objetos gráficos pode alterar
• Máscaras repetitivamente os parâmetros do contexto gráfico, cada operação é res-
Elas são representadas pelas classes Window, Pixmap e ponsável por ajustar seus parâmetros.
Masks respectivamente. Todas elas são subclasses de DisplaySurface.
Esta classe interage diretamente com a máquina virtual, e suporta uma
1. Em um parcel denominado PostScriptPrinting
A classe GraphicsContext é uma superclasse abstrata de A classe Pixmap é uma superfície gráfica que tem como princi- Pixmaps
outras duas classes de nosso interesse. Dizemos que existem dois tipos pal característica não ser mostrada na tela diretamente, mas sim ter suas
de contextos gráficos. Os contextos gráficos que apresentam objetos na operações gráficas feitas em segundo plano, tendo que ser mostrada em
tela e os contextos gráficos que geram código PostScript para que seja outra superfície gráfica, ou seja uma janela. A vantagem de perfazer ope-
impresso As classes que implementam estes dois tipos de contextos rações gráficas em segundo plano reside no fato de certas operações
gráficos são ScreenGraphicsContext e PostScriptGraphicsContext são muito complicadas ou a imagem a ser mostrada ser muito grande.
respectivamente. A classe GraphicsContext também possui funcionalida- Este tipo de operação pode demorar muito tempo, então a utilização de
des para redimencionar os objetos por ela mostrados, definir janelas de uma instância de Pixmap para executar a operação e depois apenas
visibilidade (clipping e viewport). transferir o resultado para uma janela se torna uma tarefa bem rápida. O
Instanicas de GraphicsContext não podem ser criadas a ermo, resultado das operações executadas em uma instância de Pixmap
elas em geral são capturadas de uma janela (pois a janela, como vere- podem ser apresentados utilizando a mensagem displayOn:at:
mos a frente é a única saída gráfica existente) e então, possuindo uma Uma instância de Pixmap pode ser criada por exemplo contendo o con-
referência para esse tipo de objeto podemos apresentar nossas informa- teúdo da área de transferência utilizando para isso a mensagem
ções gráficas. fromClipboard, ou diretamente vazia.
A título de exemplo deste livro utilizaremos o contexto gráfico da Note que instâncias da classe Pixmap dependem de recursos
janela de exemplos do help a semelhança de como é feito nos exemplos do sistema operacional, logo uma imagem armazenada em uma de suas
fornecidos pelo VisualWorks para não confundir a cabeça do leitor, mas a instâncias será perdida ao sair do sistema. Para corrigir este problema
frente no livro apresentaremos como capturar o contexto gráfico de qual- utilizamos instâncias da classe CachedImage.
quer janela. A captura do contexto gráfico da janela de exemplos do relp
do VisualWorks pode ser capturada como apresentado no exemplo A classe Mask é outra superfície gráfica onde se pode definir Máscaras
12.1.Como toda operação gráfica pode potencialmente alterar o contexto regiões geométricas dentro de uma área retangular. As máscaras con-
gráfico de um superfície gráfica, não devemos nunca armazenar um con- tém um array bidimencional, uma matriz, onde cada célula corresponde a
texto gráficos em uma variável de instanica ou de classe, mas para efeito um pixel desta área retangular. Cada pixel tem associado um valor alpha
de manipulação local do contexto gráfico dentro de um método podemos que varia entre 0 e 1 e representa o grau de cobertura. Os valores supor-
referencia-lo por uma variável temporária, como podemos ver no exem- tados são 1 (completamente coberto) e 0 (completamente descobertos).
plo 12.1. Note queeste exemplo só funcionará se o help houver sido car- Máscaras são utilizadas para definir regiões de trasparência e também
regado. para sobrepor imagens.
| gc | Uma janela é uma superfície gráfica que é agendada pelo geren- Janelas
gc := (Examples.ExamplesBrowser prepareScratchWindow) ciador de janela de sua máquina. Se desenvolvermos uma aplicação no
graphicsContext. VisualWorks utilizando o Windows e depois abrirmos a mesma imagem
Exemplo 12.1 capiturando o contexto gráfico no Linux, ela funcionará da mesma maneira mais a aparência da aplica-
ção se adequará as características do sistema operacional. Essa carac-
terística pode ser observada na figura 12.3 abaixo. As janelas recebem
eventos e são a superfície gráfica mais comumente utilizada.
| win |
Figura 12.3 Exemplo de uma mesma janela no Windows e no Linux sob KDE
win := ScheduledWindow new.
win minimumSize: (size := 500 @ 300).
A classe Window possui algumas subclasses que apresentam
win open
características específicas o que faz com que uma instância da classe
Exemplo 12.2 criando uma janela em branco
Window dificilmente seja criada. A classe ScheduledWindow é uma
das especializações da classe Window e possui em adição as funciona-
lidades como controlar seu tamanho máximo e mínimo. Ela também pos-
sui um controller (controllers fazer parte do paradigma MVC e serão 12.3 Objetos Gráficos
vistos em um capítulo específico) que fornece um menu com todas as A maioria dos objetos gráficos aqui apresentados se encontram
operações padrão de uma janela e possui um componente visual que organizados sob o protocolo Graphics-Geometry. Eles fazem parte do
serve para que componentes gráficos possam ser adicionados a classe. framework gráfico do VisualWorks e são de fácil manipulação. Nas sub-
Note que apenas um componente gráfico pode ser adicionado a uma ins- seções seguintes seguiremos o seguinte padrão: apresentaremos cada
tância da classe ScheduledWindow. um dos objetos gráficos explicando detalhes tais como métodos para cri-
Uma instância da classe ScheduledWindow é criada utilizando ação, alteração de atributos e apresentação em um contexto gráfico. Em
as mensagens new ou model:label:minimumSize:. Caso se seguida apresentaremos alguns exemplos para elucidar a teoria estu-
deseje alterar alguns atributos gráficos como o label, o ícone etc, existem dada.
mensagens apropriadas, ela pode ser aberta utilizando a mensagem Todo o framework para apresentação de objetos gráficos no
open ou openIn: que se responsabilizam por agendar a janela a cole- VisualWorks foi projetado para apresentar informação gráfica em duas
dimensões. Existem alguns esforços no sentido de manipular informa- apresentar nossos textos na tela. O exemplo 12.4 na página 233 mostra
ções gráficas em três dimensões, como é o caso do projeto sun que é como podemos fazer isso.
brevemente discutido ao final deste capítulo. Mais informações poderão
ser encontradas na referência bibliográfica ao final deste capítulo. "exemplo de utilização da classe Text"
|text gc|
Textos Textos são para o VisualWorks tratados como objetos gráficos gc := (Examples.ExamplesBrowser
em muitos contextos e podem ser perfeitamente apresentados em qual- prepareScratchWindow) graphicsContext.
quer contexto gráfico. Particularmente instâncias da classe Text e Com-
posedText são de maior interesse no contexto gráfico. Elas provem text := Core.Text string: 'Smalltalk Completo'
características de formatação adicionais as encontradas na classe emphasis: #(#bold #large).
String. Porém instâncias da classe String podem ser convertidas para text displayOn: gc at: 10@40.
instâncias da classe Text enviando a mensagem ‘asText’. text := Core.Text string: 'Smalltalk é 100% OO'
emphasis: #italic.
Instancias da classe Text podem ter sua aparência mudada de text displayOn: gc at: 10@55.
diverças formas. Para criar um texto por exemplo em negrito poderíamos Exemplo 12.3 Desenhando texto formatado em um contexto gráfico
enviar a mensagem ‘emphasis:’ passando como argumento o símbolo
#bold. A tabela 12.3 sumariza todos os tipos de mudanças suportadas Porém também podemos apresentar instâncias da classe
pela classe Text: String. Para isso utilizamos a mensagem ‘displayString: at:’. esta men-
sagem espera como parâmetros uma string e o ponto de ínicio para apre-
#bold #italic sentação. O melhor de tudo é que mesmo instâncias da classe String
#serif #small podem ter sua aparência alterada, pois instâncias de GraphicsContext
implementam tratamento do tipo e estilo de fonte.
#underline #strickeOut
#sansSerif #large Note que é sempre melhor utilizar instâncias da classe Text pois
como sabemos qualquer operação gráfica pode alterar os atributos do
Tabela 12.3 Estilos de texto
contexto gráfico não garantindo desta forma que no momento da apre-
Em casos onde desejamos alterar a aparência de um texto em sentação de strings os parâmetros estejam corretamente definidos. Exis-
mais de um aspecto tmabém podemos utilizar a mensagem ‘emphasis:’ tem outras mensagens úteis definidas na classe Text que sumarizamos
porém passando como argumento um array contendo os símbolos relati- na tabela 12.4.
vos as modificações desejadas.
Uma das grandes vantágens da classe Text sobre a classe Existe uma classe chamada LineSegment no framework gráfico Linhas
String além do fato dela poder sem enfatizada de diverças formas está que representa um segmento de linha. Ela é a abstração geométrica do
no fato de que Text implementa a mensagem ‘display: on:’, o que fornece conceito da menor distância entre dois pontos.
regularidade concomitante as outras classes que representam objetos Podemos criar instâncias da classe LineSegment enviando a
gráficos, desta forma, para escrevermos utilizar esta mensagem para mensagem de classe ‘from: to:’ ou ‘with: with:’. Usamos a primeira
quando existe a necessidade de se fazer diferenciação entre o ponto ini-
Método Descrição
permite que se defina a posição inicial e final onde
emphasizeFrom: to: with: se deseja enfatizar e aceita um ou vários tipos de
ênfases.
retorna um símbolo ou array de simbolo indi-
emphasisAt: quando qual ou quais tipos de enfase o caracter
cujo indice é passado como argumento possui.
aceita associações entre o simbolo #color e uma
emphasizeAllWith:
cor correspondente para colorir o texto.
allBold coloca todo o texto em negrito
verifica se o texto passado como argumento está
sameEmphasisAs: enfatizado de maneira igual ao texto que recebe a
Figura 12.4 Resultado do código do exemplo anterior mensagem.
Tabela 12.4 Métodos que mudam o estilo de uma instância de Text
cial e o final da linha. Porém não houver esta necessidade, ou ainda se
ela for indesejada, a segunda mensagem é a melhor opção. Método Descrição
Instancias da classe LineSegment são úteis no caso de dese- length retorna o comprimento da linha (módulo)
jarmos desenhar repretitivamente este objeto, mas também para perfa- verifica se a linha intercepta um retângulo que deve ser
zer operações geométricas como verificar se a linha intercepta um outlineIntersects:
passado como argumento
retangulo, inquiri-la sobre seu comprimento, etc. A tabela 12.5 apresenta
start retorna o ponto inicial da linha
alguns destes método.
end retorna o ponto final da linha
Como veremos mais a diante neste capítulo, objetos gráficos
Tabela 12.5 Métodos implementados por LineSegment
podem ser desenhados apenas delineados ou preenchidos, porém no
caso das linhas apenas a opção delineada é permitida. Para se desenhar
Uma das grandes vantagens da biblioteca de classes do Visu- Polígonos
linhas na tela podemos utilizar tanto uma instanica da classe LineSeg-
alWorks é sua regularidade. A semelhança do que ocorre com linhas,
ment ou o método displayLineFrom:to: da classe GraphicsCon-
polígonos podem ser desenhados de duas formas, a primeira é utilizando
text. As vantágens de se criar uma instância de LineSegment é a
instâncias da classe Polyline enviando a mensagem displayStroke-
mesma apresentada no caso dos textos.No caso em que desejamos
dOn:, a segunda é enviando a mensagem displayPolygon: ou
desenhar uma linha através de instâncias da classe LineSegment deve-
displayPolyline: ao contexto gráfico alvo. Em verdade o que as
mos utilizar a mensagem displayStrokedOn: e passar como argu-
mensagens displayFilledOn: e displayStrokedOn: é chamar
mento o contexto gráfico de destino. O exemplo 12.4 apresenta as duas
o método displayPolygon: ou o método displayPolyline: do
formas de criação de linhas e a utilização do método displayStroke-
contexto gráfico respectivamente, passado como argumento. Vale a
dOn: Linhas ainda podem ser transladadas e aumentadas. Estas opera-
pena dar uma olhada nestes métodos. Esta mesma estratégia de forne-
ções serão vistas mais à frente neste capítulo.
|line gc|
gc := (Examples.ExamplesBrowser prepareScratchWindow)
graphicsContext.
line := LineSegment
with:(400-cont)@0
with: 400@cont.
line displayStrokedOn: gc.
].
cer várias opções para uma mesma tarefa sem almentar a complexidade
da implementação é utilizada comumente em toda a biblioteca de clas-
ses.
A classe Polyline é utilizada para criar tanto polígonos como
coleções de linhas conexas (polylines). Porém em casos onde uma cole-
ção de linhas não ser fechada, ou seja, o ponto inicial coicidir com o final,
que atitude é tomada no caso de chamarmos o método displayFil-
ledOn: ? Figura 12.5 Desenho de linhas cruzadas gerado pelo código do exemplo anterior
Simples, implicitamente o ponto final da coleção de pontose interessante é alterar a mensagem display-StrokedOn: por
ligado ao ponto inicial, desta forma o coleção de linhas se fecha tor- displayFilledOn:. Faça isso e verifique o resultado.
nando-se um polígono e pode ser preenchida. Então podemos dizer que
Pológonos e coleções de pontos podem ser usados das mais
apenas poligonos podem ser preenchidos.
diversas formas. Lançando mão deles e de um pouquinho de matemática
Para criar tanto poligonos como coleções de linhas devemos podemos até mesmo criar curvas. A título de exemplo apresentamos um
enviar a mensagem vertices: à classe Polyline passando como programa que pode ser visto no exemplo 12.6. Ele cria uma curva ape-
argumento uma coleção de pontos. Em geral essa coleção pode ser uma nas utilizando uma instância de Polyline.
instância da classe OrderedCollection.
Existem muitos outros métodos úteis implementados na classe
O exemplo 12.5 mostra como podemos criar e apresentar Polyline, eles poder ser vistos na tabela 12.6 na página 238.
poligonos e coleções de pontos em um contexto gráfico. Um experimento
Método Descrição
vertices retorna uma instância de Array contendo todos os pontos
do poligono
verticesDo: avalia o bloco passado como argumento para cada par de
vértices do polígono
edgesDo: avalaia o bloco passado como argumento para cada ponto
do polígono
outlineIntersects: verificar se o polígono intercépta o retângulo passado
como argumento quando em forma de linhas
regionIntersects: o mesmo que o anterior porém quando preenchido
Tabela 12.6 Métodos implementados por Polyline
desenha-lo preenchido envie a mensagem displayFilledOn:. A
classe GraphicsContext também implementa o método displayRec-
tangle: para desenho de retângulos. O exemplo 12.7 mostra como
podemos criar e apresentar alguns retângulos.
|rect gc|
gc := (Examples.ExamplesBrowser prepareScratchWindow)
graphicsContext.
Figura 12.6 Resultado da execução do código de geração de retângulos
rect := Rectangle vertex: 10@10 vertex: 100@100.
rect displayFilledOn: (gc paint: (ColorValue red)). Existem também classes para representar alguns tipos de cur- Curvas Bézier
vas. O VisualWorks implementa as classes Bezier e Spline que são dois e Spline
gc paint: (ColorValue green). tipos de curvas muito utilizadas na prática. Como são curvas e não se
(110@10 extent: 50@50) displayStrokedOn: gc. espera que sejam fechadas elas não implementam o método ‘displayFil-
ledOn:’. Então para apresentam qualque uma destas curvas devemos
rect := Rectangle origin: 10@110 corner: 160@200. utilizar a mensagem ‘displayStrokedOn:’.
gc displayRectangle: rect at: 100@100.
Foge do escopo deste livro uma detalhada explicação sobre a
Exemplo 12.7 Criando e mostrando retângulos
fundamentação matemática destas curvas, mas caso o leitor deseje
Existem ainda muitos outros métodos úteis implementados pela saber mais pode consultar a bibliografia ao final do livro, em especial o
classe Rectangle. A tabela 12.7 na página 240 sumariza alguns deles. livro de computação gráfica. O exemplo 12.8 mostra como podemos criar
uma curva de Bézier e mostra-la na tela e o exemplo 12.9 mostra uma
curva spline cúbica.
|bez gc|
gc := (Examples.ExamplesBrowser prepareScratchWindow)
graphicsContext.
Transforma- Todos os objetos geométricos apresentados até aqui possuem | rct gc|
ções geomé- métodos para gerenciamento de transformações geométricas. Todas gc := (Examples.ExamplesBrowser
tricas estas classes possuem algumas transformações básicas salvo a classe prepareScratchWindow) graphicsContext.
Rectangle que possui uma gama de métodos mais elaboradas, em parte rct := Rectangle origin: 10@10 corner: 100@100.
por sua simplicidade geométrica e mais iportante que isso, pela sua rct displayStrokedOn: gc.
extensa aplicabilidade por toda a biblioteca de classes. A seguir apresen- (rct translatedBy: 100@100) displayStrokedOn: gc.
taremos as transformações básicas que todas as classes geométricas Exemplo 12.11 movimentando retângulos do contexto gráfico
implementam e em seguida apresentaremos mais algumas específicas
da classe Rectangle. Método Descrição
Podemos por exemplo ecalar qualquer objeto geométrico com o Espera um ponto ou escalar como argumento e retorna
scaledBy:
auxílio da mensagem scaledBy: . Esta mensagem espera como argu- um novo retângulo expandido.
mento um ponto que será multiplicado pelas coordenadas do objeto geo- Espera um ponto, escalar ou retangulo como argumento e
métrico. O exemplo 12.10 mostra como podemos escalonar uma figura. expandedBy: retorna um novo retângulo que esta fora do retângulo que
recebeu a mensagem por delta.
| rct gc| Espera um ponto, escalar ou retangulo como argumento e
insetBy:
gc := (Examples.ExamplesBrowser retorna um novo retângulo contido em delta.
prepareScratchWindow) graphicsContext. verifica se o retângulo que recebeu a mensagem interseci-
rct := Rectangle origin: 10@10 corner: 100@100. intersect: ona o retângulo passado como argumento e retorna um
rct displayStrokedOn: gc. boleano.
(rct scaledBy: 2@3) displayStrokedOn: gc
retorna um novo retângulo que contém tanto o retângulo
Exemplo 12.10 Escalonamento de um retângulo
merge: que recebe a mensagem como o que é passado como
Outra transformação geométrica suportada é a translação. Utili- argumento.
zando a mensagem trasnlatedBy: que espera como argumento um retorna uma coleção de retângulos que não estão contidos
ponto, podemos movimentar uma figura geométrica pelo contexto grá- areasOutside: dentro do retângulo passado como argumento e que estão
fico. O ponto passado como argumento para a mensagem indica o mon- dentro do retângulo que recebe a mensagem.
tante em pixels que a imagem será deslocada. Se o valor das Modifica o canto inferior direito do retângulo de modo que
coordenadas for positivo, a figura será deslocada para baixo e para a moveBy: sua área se adeque relativa a uma translação idicada pelo
direita, em contrapartida, se o valor for negativo, a figura será deslocada ponto passado como argumento
para cima e esquerda. O exemplo 12.11 mostra como podemos deslocar Move o retângulo de mode que o canto superior direito
moveTo:
um retângulo. seja o ponto passado como argumento
Como dissemos anteriormente, a classe Rectangle possui ainda retorna um novo retângulo que é transladado entre a sub-
align:with:
algumas outras rotinas de transformações geométricas. Por seu funcio- tração dos pontos passados como argumento.
namento ser intuitivo, apenas as listaremos na tabela 12.8 e fornecere- Tabela 12.8 Algumas outros métodos da classe Rectangle
mos uma breve explicação.
Algumas destas mensagens podem não ser intuitivas, por isso Para apresentarmos a instancia de GraphicsAttributesWra-
sugerimos que o leitor experimente alguns exemplos, utilizando-os para pper devemos utilizar a mensagem displayOn: at: que espera
uma melhor compreenção de seu funcionamento. como argumento um contexto gráfico e um ponto a partir de onde será
desenhado o objeto. O exemplo 12.12 mostra como estas tarefaz podem
Wrappers Wrappers gráficos permitem que empacotemos objetos para ser executadas.
gráficos e facilitar seu processo de apresentação em om contexto gráfico. Duas
wrappers de classes são de particular interesse, a classe StrokinWrapper e a classe |gc rect wrp atr|
atributos FillingWrapper. Elas permitem-nos que definamos se um objeto gráfico gc := (Examples.ExamplesBrowser
gráficos dever ser apresentado apenas delineado ou preenchido. A utilização de prepareScratchWindow) graphicsContext.
wappers permite ao visualWorks fornecer uma interface de apresentação rect := Rectangle origin: 10@10 corner: 100@ 200.
uniforme para todos os objetos gráficos. A utilização de wrappers gráfi- wrp := GraphicsAttributesWrapper on: rect asFiller.
cos foi apresentada dutante a apresentação dos objetos geométricos em atr := GraphicsAttributes new paint: ColorValue red.
wrp attributes: atr.
geral. em suma devemos utilizar as mensagens asStroker ou asFil-
wrp displayOn: gc at: 0@0.
ler para obter um objeto geométrico empacotado dentro de um wra-
Exemplo 12.12 utilizando wrappers de atributos gráficos
pper.
Não devemos armazenar o contexto gráfico diretamente em uma
variável, pois como ele é contantemente alterado, não corespoderá ao 12.4 Imagens
que esperavamos que fosse. Então como podemos armazenar as confi-
gurações gráficas de um objeto que criamos? Devemos ter que manual- Imagens são matrizes de pixels contendo cores a seprem apre-
mente setar todas as propriedades toda vez que formos desenhar sentadas em uma área retângulor dentro de um contexto gráfico. Tem
nossos objetos gráficos? Embora esta seja uma alternativa, o Smalltalk como características serem armazenadas dentro do arquivo imagem. Por
fornece-nos uma maneira mais simples de resolver este problema. Pode- este motivo, imagens podem ser utilizadas para armazenar Pixmaps e
mos utilizar um wrapper gráfico. A classe que implementa wrappers gráfi- máscaras. Elas podem ser baseadas em cores ou índices, o que significa
cos é GraphicsAttributesWrapper. A idéia por traz é simples. Devemos que podem conter a cor do pixel a ser apresentado ou uma entrada em
criar nosso objeto gráfico normalmente utilizando as mensagens asS- uma paletta de cores.
troker ou asFiller. Isso nos retornará um objeto geométrico empacotado. Imagens são comumente utilizadas para criar cursores e icones,
Em seguida devemos criar uma instancia de GraphicsAttributesWra- assuntos estes que serão arordados mais a frente neste capítulo. A
pper impacotando o wraper anterior que contém o objeto geométrico. De classe abstrata Image define a interface para a criação de imagens.
posse do wrapper de atributos gráficos devemos criar uma instancia de Porém quem realente cria as imagens são suas subclasses concretas
GraphicsAttributes que conterá os atributos gráficos a serem atribuidos que realmente fazem o trabalho, criando desta forma imagens de diferen-
ao objeto geométrico previamente criado. Isso pode ser feito através da tes resoluções. A figura 12.8 mostra a hierarquia das classes de ima-
mensagem é paint: e espera como parâmetro uma cor ou um padrão. gens.
Por ultimo devemos instalar os atributos gráficos na instancia de Gra-
phicsAttributesWrapper. Isso depo ser feito através da mensagem attri- Imagens são armazenadas dentro do arquivo imagem do Small-
butes: passando a instancia de GraphicsAttributes como argumento. talk. Desta forma são vistas como recursos. Existem vantágens e des-
No exemplo anterior, a imagem criada não continha qualquer fiquemos o tamanho da imagem (que deve ser um ponto onde a coorde-
desenho, apenas definimos a paletta das possíveis cores que ela pode nada x indica o numero de linhas e a coordenada y o numero de
conter e seu tamanho. Podemos também definir explicitamente qual será colunas), o número de bits por pixel, a paletta a ser utilizada e os bits da
o desenho que a imagem conterá. O exemplo 12.15 criar um X dentro de figura.
um retângulo. Neste método, duas considerações devem ser feitas. A palavra
chave bits: espera como argumento uma instancia de ByteArray.
| gc image | Este objeto deve conter todos os bits da imagem. Estes bits devem estar
gc := (ExamplesBrowser prepareScratchWindow) graphicsContext. organizados em bytes, então como no exemplo 12.15 o número de bits
por pixel é 1, cada byte representará 8 pixels. Caso o número de bits por
image := Image
pixel fosse 24, precisaíamos de 3 bytes para representar cada pixel.
extent: 16@16
depth: 1 Agora vejamos o conceito de pad. O Smalltalk espera que as
palette: CoveragePalette monoMaskPalette linhas de uma imagem sejam multipas de 32 bits, isso por motivos de
bits: #[ performance.Então quando o número de bytes nas linhas da imagem não
2r11111111 2r11111111 forem multiplos de 32 devemos especificar um valor de pad, que fará a
2r11000000 2r00000011 correção. Estes valores devem ser 8, 16 ou 24, que são respectivamente
2r10100000 2r00000101 1, 2 ou 3 bytes. Se por exemplo em uma imagem as linhas contiverem 3
2r10010000 2r00001001
bytes (24 bits) o valor de pad deverá ser 8 pois é o que falta para o
2r10001000 2r00010001
número de bits na linha ser multiplo de 32.
2r10000100 2r00100001
2r10000010 2r01000001 O exemplo 12.16 mostra uma figura com 3 bytes por linha, logo
2r10000001 2r10000001 o valor de pad deve ser 8 para completar um número multiplo de 32 bits
2r10000001 2r10000001 por linha. Quando o número de bits por linha é multiplo de 32, ou seja,
2r10000010 2r01000001 32, 64, 128, etc, não existe a necessidade de se especificar um valor de
2r10000100 2r00100001 pad, logo devemos utilizar a mensagem extent: depth: palette:
2r10001000 2r00010001 bits:.
2r10010000 2r00001001
2r10100000 2r00000101
2r11000000 2r00000011 No capítulo sobre arquivos externos vimos uma forma de ler Abrindo
2r11111111 2r11111111] uma imagem no formato PGM, lendo-a passo a passo. Existe também a imagens de
pad: 16. possibilidade se abrirmos imagens contidas em arquivos em alguns for- arquivos
matos padrão utilizando métodos de mais alto nível. Para tal, utilizamos a
image displayOn: gc at: 10@10. classe ImageReader. Ela nos pertimte que facilmente abramos imagens
Exemplo 12.15 criando uma imagem bit a bit tipo .bmp, .gif, .tiff, etc. O exemplo 12.17 abre uma imagem tipo bmp. A
figura 12.9 mostra a execução do exemplo 12.17.
No exemplo anterior, utilizamos a mensagem extent:
Agora que já vimos como criar e abrir uma imagem, vejamos
depth: palette: bits: pad:.Esta mensagem espera que especi-
mais alguns conceitos. Em uma imagem, cada pixel possui um valor que
| gc image |
gc := (ExamplesBrowser prepareScratchWindow) graphicsContext.
image := Image
extent: 24@16
depth: 1
palette: MappedPalette whiteBlack
bits: #[
2r11111111 2r11111111 2r11111111
2r11000000 2r00000011 2r11111111
2r10100000 2r00000101 2r11111111
2r10010000 2r00001001 2r11111111
2r10001000 2r00010001 2r11111111
2r10000100 2r00100001 2r11111111
2r10000010 2r01000001 2r11111111
2r10000001 2r10000001 2r11111111
2r10000001 2r10000001 2r11111111
2r10000010 2r01000001 2r11111111
2r10000100 2r00100001 2r11111111
2r10001000 2r00010001 2r11111111
2r10010000 2r00001001 2r11111111
2r10100000 2r00000101 2r11111111
2r11000000 2r00000011 2r11111111 Figura 12.9 execução do exemplo 12.17
2r11111111 2r11111111 2r11111111]
pad: 8. uma tabela de cores são usados para permitir que imagens de mesma
resolução apresentem cores distintas. Por exemplo, uma imagem de
image displayOn: gc at: 10@10. depth 4 pode possuir até 16 cores simultaneamente. Mas quais dentre
Exemplo 12.16 Imagem com 3 bytes por linha todas as cores possíveis são essas tal 16 cores? A resposta é simples,
qualquer uma. na imagem ficam apenas armazenados indices para a
| gc image | tabela de cores que serão trocados por uma cor propriamente dita no
gc := (ExamplesBrowser prepareScratchWindow) graphicsContext. momento em que a imagem for ser desenhada em uma superfície de
image := (ImageReader fromFile:'e:\priest.bmp') image. apresentação.Isso nos permite por exemplo criarmos uma imagem depth
image displayOn: gc at: 10@10 4 em escala de roxo e outra em escala de laranja. O tipo de paleta deter-
Exemplo 12.17 Abrindo uma imagem de um arquivo mina em que tipo de superfície de apresentação a imagem pode ser
desenhada os lida. Se a imagem é baseada em índices de cores dize-
pode ser uma entrada em uma tabela de cores (paletta) ou uma entrada
mos que ela é compatível com Pixmaps janelas e , já se a imagem é
em uma tabela de coeficiente de transparência. Valores de entrada em
baseada em coeficientes de transparência, ela será compatível com ins- | gc image ico|
tancias de Mask. gc := (ExamplesBrowser prepareScratchWindow) graphicsContext.
De posse de uma imagem podemos obter facilmente uma super- image := Image
fícei de apresentação bastando enviar a mensagem asRetainedMe- extent: 16@16
diun.O exemplo 12.17 abre uma imagem a partir de um arquivo, vamos depth: 1
palette: CoveragePalette monoMaskPalette
modifica-lo no exemplo 12.18 para obtermos uma instancia de Pixmap a
bits: #[
partir da imagem.
2r11111111 2r11111111
2r11000000 2r00000011
| image | 2r10100000 2r00000101
image := (ImageReader fromFile:'e:\priest.bmp') image. 2r10010000 2r00001001
image asRetainedMedium 2r10001000 2r00010001
Exemplo 12.18 Obtendo um pixmap através de uma imagem 2r10000100 2r00100001
2r10000010 2r01000001
2r10000001 2r10000001
12.5 Icones 2r10000001 2r10000001
2r10000010 2r01000001
Icones também são suportados pelo Smalltalk. A classe que 2r10000100 2r00100001
implemementa suas funcionalidades é Icon. Para trabalharmos com ico- 2r10001000 2r00010001
nes devemos ter uma imagem que possua uma paletta de transparên- 2r10010000 2r00001001
cias. Isso pode ser conseguido especificando-se a paletta da sequinte 2r10100000 2r00000101
maneira: 2r11000000 2r00000011
2r11111111 2r11111111]
CoveragePalette monoMaskPalette pad: 16.
De posse da imagem com paletta de transparências podemos ico := Icon image: image.
então criar uma instancia da classe Icon enviando a mensagem image: ico displayOn: gc at: 10@10.
para a classe Icon. O argumento deve ser uma imagem. Um ícone será Exemplo 12.19 icone a partir de uma imagem com paletta de transparências
retornado, e o mesmo pode ser associado a uma aplicação.
ocorrendo, ou quando o cursor do mouse está sobre algum objeto espe-
O exemplo 12.19 cria uma instância da classe Icon a partir da cial. No Smalltalk, existe a classe Cursos que nos permite alterar o cursor
imagem já muito usada de um X dentro de um quadrado. atual e também criar novos cursores. Para tal, devemos possuir uma
imagem com paletta de transparências.Existe ainda, muitos cursores
padrão que podem ser vistos na tabela 12.9.
12.6 Cursores Primeiro veremos como podemos utilizar os cursores padrão
Em aplicações profissionais, é muito comum alterarmos a apa- para alterar o cursor do mouse. Em seguida veremos como criar nosso
rência do cursor do mouse para indicar que algum processamento está próprio cursor onde também explicaremos o que vem a ser um hot spot.
Utilizando os Todos os cursores apresentados na tabela 12.9 são implementa- ponda ao nome do cursor. Este campo não é necessário podendo ser
cursores dos na classe Cursor como variáveis compartilhadas de classe mas atribuido nil.
padrão podem ser acessado através de métodos de classe. Estes métodos
estão organizados sob o protocolo constants e são exatamente iguais |cur colorIm mskIm |
aos nomes dos cursores padrão apresentados na tabela 12.9. por exem- colorIm := Image
plo, para criarmos um cursor para coleta de lixo poderiamos avaliar a extent: 16@16
sequinte expressão: depth: 1
palette: MappedPalette whiteBlack
Cursor garbage bits:#[2r11111111 2r111111112r11000000 2r00000011
Para setarmos o cursor padrão do mouse podemos utilizar as 2r10100000 2r00000101 2r10010000 2r00001001
seguintes mensagens: 2r10001000 2r00010001 2r10000100 2r00100001
2r10000010 2r01000001 2r10000001 2r10000001
beCursor
2r10000001 2r10000001 2r10000010 2r01000001
show 2r10000100 2r00100001 2r10001000 2r00010001
showWhile: 2r10010000 2r00001001 2r10100000 2r00000101
2r11000000 2r00000011 2r11111111 2r11111111 ]
A mensagem beCursor indica a máquina virutal para usar o
pad: 16.
cursor que recebeu a mensagem como o cursor padrão. Já a menságem mskIm := Image
show muda imediatamente a aparência do cursor do mouse para a do extent: 16@16
cursor que recebeu a mensagem. Por último, a menságem sho- depth: 1
wWhile: espera um bloco como parâmetro e fará com que o cursor palette: CoveragePalette monoMaskPalette
tenha a aparência do cursor que recebeu a mensagem enquanto o bloco bits:#[2r11111111 2r11111111 2r11000000 2r00000011
retornar verdadeiro. 2r10100000 2r00000101 2r10010000 2r00001001
2r10001000 2r00010001 2r10000100 2r00100001
Criando um Caso os cursores padrão do Smalltalk apresentados neste capí- 2r10000010 2r01000001 2r10000001 2r10000001
cursor tulo não sejam suficientes, podemos criar nossos próprios cursores atra- 2r10000001 2r10000001 2r10000010 2r01000001
2r10000100 2r00100001 2r10001000 2r00010001
vés da mensagem image: mask: hotSpot: name:. A palavra
2r10010000 2r00001001 2r10100000 2r00000101
chave image: espera como argumento uma figura com uma paletta de
2r11000000 2r00000011 2r11111111 2r11111111 ]
cores, já a palavra chave mask: espera uma figura de mesmo tamanho pad: 16.
mas com uma paletta de coeficientes de transparência. Isso para que o cur := Cursor image: colorIm mask: mskIm hotSpot: 4@4 name:
cursor tenha aquela aparência de que está sobre as janelas e qualquer 'quadrado'.
outra coisa na tela. A palavra chave hotSpot: espera um ponto como cur showWhile: [(Delay forSeconds: 3) wait].
argumento e indica qual vai ser o ponto de ação do cursor. Se indicarmos Exemplo 12.20 Criando um cursor programacionalmente
o hotSpot como 0@0 o canto superior esquedo será tipo como ponto de
ação e assim por diante. Por último, name: espera uma string que corres-
Capítulo 13 &ULDQGR*8,V
,QWHUDWLYDPHQWH
do UIPainter, tais como definir propriedades para widgets, como utiliza- windowSpec
las, apresentar o conceito de recursos e também trabalhar com multiplas "UIPainter new openOnClass: self andSelector: #windowSpec"
janelas.
<resource: #canvas>
^#(#{UI.FullSpec}
13.2 Salvando a Janela como um Recurso #window:
#(#{UI.WindowSpec}
O UIPainter trabalha em cooperação com o UIBuilder para criar #label: 'Canvas Exemplo'
interfaces gráficas. O que o UIPainter faz na realidade, é criar uma des- #bounds: #(#{Graphics.Rectangle} 412 284 618 449))
crição textual da interface, indicando os widgets presentes e também sua #component:
formatação. De posse desta descrição, o UIBuilder a traduz e transforma #(#{UI.SpecCollection}
em objetos, criando assim uma GUI.. #collection: #(
#(#{UI.SequenceViewSpec}
#layout: #(#{Graphics.Rectangle} 8 10
108 110 )
#useModifierKeys: true
#selectionType: #highlight )
#(#{UI.ActionButtonSpec}
#layout: #(#{Graphics.Rectangle} 137
130 186 155 )
#model: #btnOk
#label: 'OK'
#defaultable: true ) ) ) )
Exemplo 13.1 Definição de uma interface em sintaxe Smalltalk
gramador modifique este recurso de outra forma que não seja utilizando
Figura 13.1 Janela-exemplo o UIPainter.
Por exemplo, imagine que tenhamos criado a GUI mostrada na Para identificarmos se uma classe possui algum recurso de
figura 13.1 . O UIPainter cria então uma descrição textual para ela que interface devemos olhar no lado da implementação de classes da refe-
pode ser vista no exemplo 13.1. rida classe, procurarmos por um protocolo interface specs e verificarmos
se algum dos recursos listados possui um icone como o apresentado na
Para salvarmos uma janela como um recurso devemos executar
figura 13.2
a operação INSTALL. O que ela faz na realidade é criar a descrição tex-
tual da janela.
Note que qualquer alteração que for feita no arquivo textual refli-
tirá diretamente na aparência da tela, logo, não aconselhamos que o pro-
do mouse sobre o mesmo e selecionar a opção properties. Isso fará com sagem de classe (que aqui deverá ser um símbolo com # na frente) que
que a janela apresentada na figura 13.4 seja aberta. retornará a imagem. Desta forma uma imagem será colocada sobre o
Na figura 13.4 vemos as propriedades de um botão. Neste botão. O campo ID indica um ponto de acesso ao widget através do
exemplo já podemos identificar algumas das mais importantes proprieda- UIBuilder. Devemos definir este campo se desejamos acessar o widget
des de um widget. A janela de propriedades é composta por um note- em questão programacionalmente. Ele também é conhecido como o
book para cada grupo de propriedades, ou seja, existem as propriedades nome do widget.
básicas do widget, seu esquema de cores, seu esquema de posiciona- Basicamente, todos os widgets possuem a aba basics com as
mento, etc. mesmas propriedades. Algumas outras propriedades mais avançadas
O campo string define a palavra ou grase que aparecerá no podem ser acessadas e definidas na aba Details. As abas Valitation e
botão. porém ainda podemos criar botôes com imagens. Neste caso notification servem para que definamos métodos que devem ser executa-
devemos selecionar o check box supplied byApplication. dos quando o estado do widget é alterado ou quando ele recebe o foco.
Em Color podemos defimor as cores do widget. Ele trabalha com um
esquema de foreground e gackground, inidicando a cor de fundo do wid-
get e a cor de frente. Em botôes o background define a cor do botão e o
foreground a cor do texto. A aba position merece uma atenção especial e
será abordada na próxima seção. Por último, a aba Dop Target permite-
nos configurar o esquema de drag and dop suportado pelo Smalltalk.
"----------------------------------------------------------"
"Difinição da classe"
Smalltalk defineClass: #Teste2
superclass: #{UI.ApplicationModel}
indexedType: #none
private: false
instanceVariableNames: 'ck1 lstStrings edtString '
classInstanceVariableNames: ''
imports: ''
category: 'UIApplications-New'
Figura 13.9 Janela do exemplo de value holders "----------------------------------------------------------"
"métodos de instancia"
interesse para entendermos como funciona o esquema de value holders. "----------------------------------------------------------"
A idéia é adicionar a string contida no input box na lista de strings do list add
box. O método add será executado toda vez que o botão for clicado e os lstStrings listHolder value add: (edtString value).
outros métodos servem unica e exclusivamente para acessar o valor do "----------------------------------------------------------"
input box e do list box. edtString
^edtString isNil
Agora, lembremos do mecanismo de encadeamento de mensa- ifTrue:
gens visto no capítulo 5 para podermos entender bem como o método [edtString := String new asValue]
add funciona. Em primeira instancia, enviamos a mensagem lis- ifFalse:
tHolder para o list box. Isso nos retornara um value holder contendo [edtString]
um objeto tipo List. Em seguida enviamos a mensagem value para o "----------------------------------------------------------"
value holder previamente obtido. Destaforma teremos em mão uma ins- lstStrings
tancia da classe List. Para adicionarmos um ítem a uma lista devemos ^lstStrings isNil
utilizar a mensagem add: , e para obtermos a string contida no input ifTrue:
[lstStrings := SelectionInList new]
box devemos enviar a mensagem value. Desta forma a string contida no
ifFalse:
input box será adicionada ao list box.
[lstStrings]
Vemos que praticamente só utilizamos a mensagem value e Exemplo 13.2 código do exemplo de value holders
valueHolders para perfazer esta nossa pequena tafera. Este mecanismo
é bem uniforme funcionando para praticamente todos os widgets do fra- taxe e quais variáveis um determinado objeto contém. Para fazer isso
mework de interfaces do VisualWorks. utilize a técnica do self halt vista anteriormente.
Uma boa prática de programação em Smalltalk é inspecionar
todo e qualquer tipo de objeto. Isso facilita enormemente a vida do pro-
gramador, pois desta forma ele não necessitará saber exatamente a sin-
Nome Icone Descrição & Dicas Nome Icone Descrição & Dicas
Group Box Serve para agrupar radio buttons ou para deixar sua Table Permite que agrupemos informações em forma tabutar.
interface mais profissional Bem chatinho de ser utilizado.
Region Permite que algumas formas geométricas sejam adicio- Dataset Automatiza algumas tarefas para manipulação de dados
nadas a sua interface. Dê uma olhada na aba Details da em um banco de dados.
janela de propriedades Note Book Permite que organizemos várias informações ou widgets
Slider Componente para variação de valores dentro de uma em um mesmo espaço na tela. Utilizado na janela de
faixa pré-definida. Ele é por exemplo utilizado na janela propriedades.
de posicionamento de widgets. View Holder Este componente é muito útil para quando criamos
Tabela 13.1 Funcionalidades de Programação Visual de Interfaces em VisualWorks alguma aplicação MVC e desejamos roda-la dentro de
nossa interface. É a abstraçao do View no referido
modelo
Subcanvas Como um canvas normal. Permite que abramos outras
interfaces dentro de nossa janela principal. Também
serve para embelezar a interface.
Spin Button Botão de incremento e decremento
13.9 Exercícios
1. Crie uma aplicação simples e mande instala-la. Em seguida descubra
sob que categoria a mesma foi criada.Como faríamos para salvar
nossa aplicação sob uma categoria pré-escolhida?
-DQHODVGHGLiORJR
2. Na aplicação anterior teste alguns dos widgets. Coloque-os no can-
vas e veja suas propriedades. Capítulo 14
3. No capítulo 11 ciramos uma aplicação para calcular o período a partir
de uma frequência pré-estabelecida. Crie agora um front end para o
mesmo.
4. Para executarmos uma aplicação com interface gráfica, podemos uti-
lizar o resouce finder, abri-la diretamente do UIPainter e ainda existe
uma outra maneira que por sinal, é a mais usada. Descubra como
devemos proceder para abrir uma aplicação por exemplo no works-
pace. (Dica verifique a hierarquia de classes. Selecione sua aplicação
e execute o comando spawn hiearchy. O método que estamos procu-
rando está na classe ApplicationModel)
5. Existe alguma variante do método encontrado no exercício anterior?
Se sim, liste-as.
6. Crie uma aplicação contendo uma barra de botôes na parte superior
da janela e um quandro de desenhos na parte inferior. Faça com que
a barra de ferramentas ocupe sempre o mesmo tamanho e po quadro Neste capítulo você vai aprender a utilizar as diferentes janelas de
de desenhos o restante da tela. (lembre-se do esquema de posiciona-
diálogo oferecidas por VisualWorks. Caixas de diálogo são janelas simplifi-
mento relativo). Para o quadro de desenhos utilize por exemplo um
cadas, que servem para apresentação de simples informações, tomada de
subcanvas.
decisões e entrada de dados simples. Elas são usadas com muita freqüên-
cia e sua utilização dá uma aparência mais profissional para suas aplica-
ções.
Aviso. Vamos abordá-las uma a uma verificando como elas são instanci- alfa: novoAlfa
adas e o que elas podem nos fornecer.
(novoAlfa >= 0 & novoAlfa <=1)
ifFalse:[
14.2 Janelas de Aviso (warn boxes) Dialog warn: 'O valor do Alfa deve \estar entre zero e um.'
withCRs.
O uso das caixas de aviso é normalmente utilizada quando se ]
deseja retornar alguma informação para o usuário, como por exemplo ifTrue:[
uma confirmação de sucesso de uma operação. alfa := novoAlfa.
].
Exemplo 14.1 Método mostrando uma mensagem de erro que abre uma caixa de aviso
alteraAlfa
"método para a alteração do Alfa do perceptron"
Figura 14.2 Janelas de diálogo: Uma janela de pesquisa inválida, janela para escolha do tipo |novoAlfa|
de variáveis e uma janela de saida do ambiente.
novoAlfa := Dialog request:
'Preencha o campo com um novo Alfa'.
14.4 Janelas de Requisição (input boxes) self perceptron Alfa: (novoAlfa asNumber).
Exemplo 14.2 Código para a janela anterior
Em outros casos, pode ser requerido que o usuário digite uma
string em resposta a uma pergunta. A aparência padrão da janela é com-
posta por três regiões onde temos uma string explicativa que indica ao
usuário o que ele deve digitar, uma caixa de entrada para que a string
seja digitada e dois botões, um para cancelar a operação e outro para
confirmá-la.
Várias outras coisas podem ser feitas com janelas de requisição
tais como se definir uma resposta padrão ou definir uma ação a ser
tomada quando a opção cancelar é selecionada. Nestes casos, se asso-
cia ao botão cancelar um bloco que será avaliado caso o botão cancelar Figura 14.4 Janela para pesquisa de classes
seja selecionado.
Um outro exemplo de janelas de requisição que o leitor se depa-
rará a todo o momento em que estiver utilizando o ambiente de desenvol- 14.5 Janelas de Multiplas Seleções
vimento do VisualWorks será a janela para procura de uma classe. Quando a lista de seleções a que o usuário deve responder for
muito extensa e não puder ser representada por botões, uma opção são
as janelas de múltiplas sepeções. Nestes tipos de janelas, uma caixa de
listagem é apresentada contendo todas as possíveis seleções. O número
0HQXV
máximo de opções mostradas deve ser informado assim como o bloco a
ser validado caso o botão de cancelar seja clicado. A cada item da lista Capítulo 15
um valor deve ser associado..
Menu Editor A ferramenta Menu Editor permite que criemos e testemos rapi-
damente menus. Ela possui várias facilidades para reposicionamento de
itens, deleção, adição e alteração de ítens. Ela permite que definamos
um menu previamente criado como um recurso do sistema que pode ser
associado a vários widgets como veremos mais a frente neste capítulo.
O menu editor pode ser acionado a partir do Visual Laucher
selecionando o item de menu <Tools> >> <Menu Editor> ou a partir do
UIPainter selecionando o item de menu <Tools> >> <Menu Editor>.
Ele ainda pode ser aberto de uma terceira maneira. Se selecio-
narmos o recurso referente ao menu no system browser e clicarmos com
o botão direito do mouse sobre ele, temos então a opção <edit
resource>. Ao selecionarmos esta opção o menu editor será aberto com
a especificação do menu que o recurso representa.
Figura 14.1 O Menu Editor sobre um menu vazio
Logo que ele é aberto, temos a janela de definição de ítens em
branco para a criação de um novo menu, mas caso desejemos editar um deverá adotar e no campo value escreva um símbolo1. Quando este item
menu pré-existente basta que selecionemos o item de menu <Menu> >> de menu for selecionado um método de mesmo nome que este símbolo
<Load>. Isso fará que uma janela seja aberta para que endiquemos qual será executado. Explicaremos isso mais a frente neste capítulo.
menu de qual classe queremos editar. Uma maneira mais fácil de editar
Para criarmos subitens ao item previamente criado basta clicar-
um menu pré-existente é selecionar o recurso correspondente ao menu
mos no segundo botão da esquerda para a direita (veja figura 15.2 ). Um
no Resource Finder.
novo subitem será então adicionado.
Criando um Após abrirmos o menu editor podemos imediatamente começar Quando criamos um item de menu apenas para organizarmos
novo menu a criar os ítens do menu. Para isso utilizamos os 3 botões apresentados subitens não existe a necessidade de se definir um valor (campo value
na fig14.2. O primeiro botão da esquerda para a direita adiciona um novo visto anteriormente) para este item. Fica sendo necessário então apenas
item ao menu. Ao clicarmos neste botão um novo item será adicionado a definirmos o campo default.
lista da esqueda do menu editor. Ele aprarecerá como <new item>.
Podemos então nomear o item e definirmos um método a ser invocado
1. Lembre-se que simbolos devem começar com o caracter #, caso este caracter não
quando este item de menu for selecionado. Isso pode ser feito na parte seja digirado, o menu editor o inclui. Lembre-se de respeitar as regras para criação de
direita do menu editor. No campo Default, escreva o nome que o item símbolos vistas no capítulo 3.
resource. Outro dado interessante sobre recursos é que eles nada mais
Cria novo ítem Cria novo ítem de menu são que métodos. No caso de recursos tipo menu, o que eles fazem é
de menu abaixo como subítem do item
retornar uma instância da classe Menu.
do selecionado atualmente selecionado
Insere separador
abaixo do item
selecionado
Classe na qual
o menu será
Figura 15.2 Botões para a criação de itens de menu instalado como
recurso
Finder,
Barras para separação de itens podem ser facilmente criadas cli-
para pro-
cando no terceiro botão da esquerda para direita apresentado na figura curar por
15.2 . Eles não precisam ter nenhum campo definido, ficando a parte outra classe
direita do menu editor desabilitada. para instalar
Seletor do método
o menu
de classe que
Reposicio- Caso criemos um item ou subitem de menu em local errado vai definir o menu
nando, exclu- podemos movimentá-lo para que fique no local desejado, isso pode ser (se selecionado)
indo e feito através dos botões apresentados na figura 15.3 . Estes botões per-
editando mitem-nos por exemplo transformar um ítem em subitem e vice-versa.
Definindo Os menus que estamos acostumados a ver possuem ítens habi- possuir uma marca de checado (Initially On / Initially Off). A parte inferior
propriedades litados e desabilitados, ítens checados e ítens com imagens. O menu desta aba permite que iniciemos um item de menu abilitado ou desabili-
editor suporta todas estas funcionalidades para seus ítens de menu elas tado. O padrão caso não alteremos nada nas proriedades é o apresen-
podem ser definidas no momento em que criamos o menu ou alteradas tado na figura.
posteriormente programacionalmente. Na figura 15.7 vemos a aba de detalhes do item de menu seleci-
onado. Nela podemos definir um caracter de atalho para acesso ao item
de menu pelo teclado juntamene com a tecla <ALT>. Também existe uma
caixa nomeada label image. Ela permite que definamos uma imagem
para o item de menu. Como toda imagem em smalltalk é tratada como
um recurso, devemos indicar qual a classse onde o recurso está insta-
lado e qual o método que representa o recurso.
Nesta seção nos preocuparemos em apresentar como definir Instancias da classe Menu representam uma lista de instancias A classe
estes tipos de propriedades deixando as alterações no menu em tempo da classe MenuItem que por sua vez são apresentadas em um menu. Menu
de execução para mais adiante neste capítulo. Note que uma instancia isolada da classe MenuItem não é de muita utili-
dade. Os ítens de um menu podem ser agrupados nas mais variadas for-
Quando selecionamos um item de menu que acabamos de criar
mas, exatamente como vimos anteriormente neste capítulo.
a parte direita do menu editor fica abilitada. É nesta região do menu edi-
tor que poderemos definir como deverão aparecer os itens do menu. A Duas das variáveis de instancia da classe Menu nos são de par-
figura 15.6 mostra uma das abas de propriedades para os itens de menu. ticular interesse. A variável items é uma lista de instancias da classe
Nela podemos indicar se o item deve ser simples (none) ou se ele deve MenuItem que contém uma string com o textos que serão apresentados
"exemplo de menu com valores de retorno" value: define o valor de retorno do item
|menu|
color retorna a cor do item
menu := Menu labels: color: define a cor do item
'circulo\esfera\quadrado\cubo' withCRs beOff deseleciona o item caso esteja selecionado
lines: #(4)
values: #('azul' 'verde' 'amarelo' 'laranja' ). beOn seleciona o item caso ele não esteja
hasindicator verifica se o item é do tipo checked
Transcript show: (menu startUp).
isOff verifica se o item esta deselecionado
Exemplo 15.2 Código para gerar dinamicamente um menu com valores de retorno
isOn verifica se o item esta selecionado
submenu retorna o submenu que o item representa
submenu: define o um submenu para o item
hasSubmenu verifica se o item tem um submenu
Tabela 15.1 Algumas mensagens para acesso e alteração de ítens de menu
Figura 15.8 Menu gerado pelo código do exemplo 15.2 A classe MenuBuilder tem como objetivo facilitar a criação de A classe
menus em relação a direta utilização da classe Menu. Ela provê métodos MenuBuilder
tabela 15.1 algumas mensagens úteis para perfazer alterações como
para a criação de menus item a item eliminando a necessidade de se
abilitar e desabilitar itens, checa-los, etc.
definir um array para labels e outro para valores como vimos no caso em
que criamos menus a partir da classe Menu, embora essa forma de cria-
Mensagem Função ção de menus seja também suportada.
enable abilita o item caso esteja desabilitado
Para criarmos um menu utilizando a classe MenuBuilder deve-
desable desabilita o item caso esteja habilitado mos primeiro criar uma instancia desta classe e em seguida enviarmos
isEnable retorna um booleano indicando se o item está habilitado mensagem para criação e configuração de itens e subitens de menu.
nameKey retorna o ID
nameKey: define um ID
position retorna a posição do item
label detorna o label do item
label: altera o label do item
Figura 15.9 Menu criado utilizando a classe MenuBuilder
value retorna o valor de retorno do item
Tabela 15.1 Algumas mensagens para acesso e alteração de ítens de menu O exemplo 15.3 cria o menu apresentado na figura 15.9 .
Eles podem ser apresentados como barras de menu na parte superior de Menus popUp são utilizados exaustivamente por todo o ambi- Menus popUp
uma janela, também podem aparecem sob a forma de menus popUp e ente de desenvolvimento e são amplamente suportados pelos widgets
por último em forma de botões. para criação de GUIs. Em geral eles são definidos exatamente como
definimos barras de menu (visto no tópico anterior) porém caso o leitor
Barras de Barras de menu são apresentadas na parte superior das janelas. tenha alguma dúvida, reporte-se a bibliografia, ou ao help do Visu-
menu Elas são suportadas diretamente pelo canvas no UIPainter e podem ser alWorks, em geral o processo é bem simples.
adicionadas a janela através de sua janela de propriedades. A título de exemplo vamos criar uma janela e a ela adicionar
Na janela de propriedade existe um botão de checagem nome- uma caixa de listagem, em seguida tomaremos o exemplo14.3 e ligare-
ado enable, se ele estiver checado o campo menu será habilitado. mos o mesmo à caixa de listagem.
Nele devemos digitar o nome do recurso que implementa o menu. Para que o exemplo 14.3 possa ser utilizado deveremos modifi-
car sua última linha de código como é apresentado no exemplo 14.6.
Devemos então criar um método de instância sob um protocolo qualquer,
contendo o código para a criação do menu e por último definirmos a pro-
priedade menu da caixa de listagem com um simbolo igual ao nome
deste método.
^menu menu
Exemplo 15.6 Modificação do código
15.5 Exercícios
1. Crie um menu contendo os seguintes items utilizando o menu editor:
arquivo editar ajuda
abrir recortar sobre
salvar colar
------- copiar
fechar desfazer
Figura 15.12 Exemplo de utilização de menu 2. Defina um símbolo de retorno para cada um dos itens deste menu.
3. Selecione algumas imagens e atribua-as a estes itens de menu.
4. Faça o mesmo sugerido nos exercícios 1 e 2 porém agora utilizando
15.4 Acessando Menus o MenuBuilder.
5. Crie uma janela e defina o menu priviamente criado como uma barra
Em muitos casos haverá a necessidade de se alterar um menu de menu.
dinâmicamente, para tal faz-se necessário um bom entendimento das
6. Adicione a janela criada no exercício anterior uma caixa de listagem e
classes Menu, MenuItem e, em alguns casos da classe MenuBuilder. O ligue o menu criado no exercício 1 a ela.
conhecimento básico sobre estas 3 classes já foi visto, agora resta-nos
explicar como fazer referência a menus.
Para menus criados através do menu editor devemos enviar a
mensagem ‘menuAt:’ para o builder, passando como argumento um
símbolo identico ao nome do recurso que implementa o menu. A retorno
desta mensagem será uma referência ao menu que desejamos acessar.
Já de posse de uma referência ao menu podemos então acessar
seus ítens através do envio das mensagens ‘menuItemLabeled:’ ou
‘atNameKey:’. estas mensagens esperam como argumentos o label do
item ou o ID do mesmo, respectivamente.
Capítulo 16 2SDUDGLJPD09&
0RGHO9LHZ&RQWUROOHU
16.2 Model
Model
O MODEL se responsabiliza por todo o rocessamento inerente a
aplicação em específico. Nele devem estar contidos todos os algorítmos,
procedimentos, tarefas para a mudança do estado da aplicação. Por
exemplo, em uma ferramenta de busca de substrings dentro de um texto,
o MODEL da aplicação se responsabilizaria pelo algorítmo de busca da ValueModel
substring. Uma vez encontrada a substring a tarefa do MODEL está fin-
dada restando apenas a sinalizxação do final do trabalho. O retorno do
resultado da pesquisa então fica sobre a responsabilidade do VIEW.
ValueHolder
Hierarquia de O model de uma aplicação pode ser extremamente simples
classes como por exemplo uma string, ou pode ser complexo ao extremo, como
por exemplo todo um conjunto de objetos para a criação e formatação de
páginas em HTML. O MODEL usualmente é um único objeto e sua com- PluggableAdaptor
plexidade rezide no fato dele poder ser composto por outros tantos obje-
tos.
Então dizemos que um MODEL deve possuir duas caracteríscti-
ApplicationModel
cas básicas:
• Possuir a capacidade de reter referêcias aos seus dependentes
• Prover todo o processamento necessário para o funcionamento Figura 16.2 Hierarquia de classes de Model
da aplicação
instância. Isso torna mais rápido a notificação dos dependentes, porém
A classe A classe Model é subclasse de Object e tem como função imple- acarreta uma maior utilização de espaço.
Model mentar um mecanismo para pesquisa de dependentes mais rápido que o Outras características específicas ao Model são adicionadas em
provido pela classe Object. Na classe object os dependentes são regis- suas muitas subclasses, porém tenha em mente que um objeto direta-
trados em um único didionário que é uma variável estática a classe. A mente filho de Object pode ser utilizado como Model de sua aplicação.
medida que o número de dependentes de várias aplicações vão sendo devemos apenas ter em mente que esta não é a melhor maneira.
adicionados, este dicionário tente a crescer de tamanho o que acarreta Existem várias classes que podemos utilizar como base para o
uma demota considerada na tarefa de pesquisar e informar os depen- modelo de nossa aplicação. A hierarquia de classes que se controe sob a
dentes de uma alteração ocorrida no onbjeto. Em vez de manter apenas classe Model fornece uma gama bem variada de opções com várias
um dicionário, a classe Model mantem seus dependentes em uma variá- características distintas. Em geral utilizamos a classe Model quando
vel de instancia (dependents) que apenas contém os dependentes da nenhuma de suas classes especializadas
vel a reutilização. Também este é o fato pelo qual temos poucos compor-
tamentos genéricos implementados nas classes que geralemente
utilizamos como controllers de nossas aplicações. Controller
Convenções Aqui vai uma nota histórica sobre o Smalltalk mais que poderá 3. Não se preocupe em que pontos do modelo da aplicação os depen-
do mouse ser de grande utilizada a você durante as suas navegadas pela biblioteca dentes deverão ser informados das alterações no estado do modelo,
de classes do VisualWorks. deixe isto para mais a frente,
4. Teste sua aplicação através do Workspace e do Transcript. Este
Por razões históricas foi associado uma cor a cada botão do
passo é opcional, porém tente não pulá-lo pois é um ótimo momento
mouse.
para encontrar erros na estrutura de sua aplicação e nos algorítmos
O botão da esquerda, também conhecido como botão de sele- que ela contém.
ção e chamado de red button. 5. Construa a interface da aplicação, ou seja, crie as suas classes Views
O botão do meio, também conhecido como botão de operação e filhas de alguma das classes encontradas na biblioteca de classes.
Se você não encontrar nenhuma que se adeque a sua aplicação, uti-
chamado de yellow button.
lize a classe View por ser a mais genérica.
O botão da direita, também conhecido como botão das opera- 6. Adicione o seu view previamente criado a uma janela, usualmente a
ções da janela e chamado de blue button. uma instancia da classe ScheduledWindow. Lembre-se que é impera-
Press - prencionado e segurado. tivo que seu view esteja contido em uma janela, pois elas são a
maneira padrão de saída gráfica dentro do VisualWorks.
release - quando um botao e solto 7. Defina o layout da aplicação utilizando as técnicas de posicionamento
click - presciona e solta sem mover o mouse vistas no capítulo sobre janelas.
double-click - clica o botao duas vezes sem mover o mouse. 8. Crie os controllers para gerenciar a entrada do usuário. Lembre-se
que cada view deve possuir seu próprio controller. Escolha dentre os
disponíveis na biblioteca de classes. Se nenhum das classes se
encaixarem escolha a classes mais genérica Controller. Se o view ao
16.5 Receita qual o controller fizer par for passivo defina o controller como uma
instancia da classe NoController.
Aqui vamos apresentar uma pequena receita para a criação de
9. Teste a interface instanciando-a e inspecionando-a para verificar se
aplicações em Smalltalk utilizando o mecanismo MVC. Note que o que
todos os controllers estão corretos e para verificar também se o
apresentaremos aqui não e de forma nenhuma uma série de passos rig-
layout da interface está correto.
dos para serem seguidos e sim apenas uma maneira de cadenciar a
10.Defina os tratamentos das entradas do usuário nas classes Control-
construção de suas aplicações. Os passos seguintes visam diminuir o
ler.
tempo de desenvolvimento e facilitar a criação rápida de um protótipo de
11.Por último defina em que pontos do modelo da aplicação mensagens
suas aplicações.
de alteração do estado interno devem ser passadas aos dependen-
1. Comece pelo domínio da sua aplicação. Escolha a superclasse de tes.
sua aplicação com base nas funcionalidades já implementadas na 12.Teste, e refine o programa.
biblioteca de classes que se encaixem com o seu problema. Se
nenhuma das classes lhe parecer útil, utilize a classe Model.
Neste capítulo apresentamos toda a fundamentação teórica por Onde
2. Se o domínio de sua aplicação for coposto por várias classes, faça-as
traz do modelo MVC. De posse deste conhecimento, veremos no pró- encontrar
todos como instancias da sua classe principal (como definido anteri-
ximo capítulo uma aplicação simples para a criação interativa de um trei- exemplos ?
ormente).
&RQVWUXLQGRXPD
nador de neurônios artificiais. O seguinte capítulo está organizado em
forma de um tutorial e foi escrito visando revisar a maioria dos conceitos Capítulo 17
discutidos durante todo o livro.
$SOLFDomR6LPXODGRU
GH5HGHV1HXUDLV
+1
0
net
Figura 17.1 Modelo computacional do neurônio de Hebb
Figura 17.2 Função de ativação em degrau ou limiar
Este modelo tem o seguinte problema, ele consegue apenas
classificar apenas problemas bem simples, ou como são conhecidos,
O algorítmo para o treino do Perceptron se dá em quatro passos Algoritmo do
problemas linearmente separáveis. Se Estruturássemos vários destes
básicos: Perceptron
Perceptrons em camadas eles resolveriam este problema, mais nestes
casos não existe um algoritmo para aprendizado automático. Um modelo 1. inicializar os pesos das entradas aleatoriamente (variamos entre o
mais completo é o Multilayer Perceptron que resolve este problema. valor 0 e o valor 1)
Sob o protocolo de instância accessing inclua os seguintes Sob o protocolo de infância processing, adicione os métodos
métodos. Note que aqui redefinimos o método fornecaSaida: que era de que seguem. Note que aqui estão redefinidos vários dos métodos que
responsabilidade da subclasse. eram de responsabilidade das subclasses de NeuronioArtificia.l
iniciaPesoBias
"Inicia aleatoriamente o peso do bias, valor entre 0 e 1"
“********************************“
initialize: numEntradas
"inicia informações sobre o perceptron"
Sob o protocolo de instância initialize-release adicione o que provê um comportamento padrão para comunicação entre o objeto e
seguinte método que se responsabilizará pela correta inicialização de a janela. A este tipo especial de objeto damos o nome de wrapper1.
todos os atributos da classe. A Classe ScheduledWindow é um dos 3 tipos de superfícies grá-
ficas suportadas pelo VisualWorks. Além dela ainda temos Pixmap e
initialize: numEntradas conjDeTreinamento: umConjDeTreino Mask. Objetos gráficos só podem ser apresentados sobre uma superfí-
saidasDesejadas: conjDeSaidas cies gráfica. ScheduledWindow éum tipo especial de janela. Possui um
numEpocas := 0.
controller que fornece as funcionalidades esperadas de uma janela, tais
conjDeTreinamento := umConjDeTreino.
como movê-la e redimensioná-la.
conjSaidas := conjDeSaidas.
perceptron := Perceptron new: numEntradas .
Exemplo 17.13 Método que inicializa o estado interno do objeto
alteraAlpha
|novoAlpha|
O seguinte método cria uma janela adiciona o view a ela e apre- novoAlpha := Dialog request: 'Preencha o campo com um novo
senta a mesma na tela. Deixe para incluir este método após criar as clas- alpha'.
self perceptron alpha: (novoAlpha asNumber).
ses PerceptronView e PerceptronController, pois ao aceitar o seguinte
conjDeTreinamento
método, o compilador irá reclamar devido ao fato das referidas classes
^conjDeTreinamento.
ainda não existirem. conjSaidas
^conjSaidas.
open numEpocas
"cria uma janela e adiciona " ^numEpocas.
| wrapper window percView| perceptron
window := ScheduledWindow ^perceptron
model: self Exemplo 17.15 Métodos de acesso do perceptron
label: 'Inspertor do perceptron'
minimumSize: 350@250.
percView := PerceptronView new.
percView model: self.
wrapper := BorderedWrapper on: percView.
wrapper insideColor: ColorValue white.
wrapper borderWidth: 3.
percView controller: PerceptronController new.
window component: wrapper.
window open.
Exemplo 17.14 método para a criação e abertura de uma janela
17.8 PerceptronController
objeto pai A função do controller é prover interação do usuário com a apli-
cação capturando e tratando as entradas do mouse e do teclado e infor-
mando ao view e ao model do esquema MVC que uma entrada ocorreu.
Nesta nossa primeira aplicação apenas utilizaremos o controller para
capturar os cliques do botão direito do mouse e a ele associarmos um
menu para perfazer ações na nossa aplicação.
dependente 1 dependente 2
indexedType: #objects
private: false
instanceVariableNames: ''
classInstanceVariableNames: ''
imports: ''
category: 'Aplicacoes Perceptron'
A superclasse que utilizamos é ControllerWithMenu, que é uma Todo o resto do mecanismo de comunicação entre as outras Comunicação
especialização da classe Controller e que adiciona a funcionalidade de duas partes da aplicação, o View e o Model já são herdadas, necessita-
associar um menu ao botão direito do mouse. mos então apenas criar os métodos referentes aos itens de menu.
inspectModel
self model inspect.
“---------------------------------------“
Capítulo 18 &ULDomRGH
inspectView
self view inspect.
“---------------------------------------“
$SOLFDo}HVSDUD
inspectController
self inspect. :::
Exemplo 17.23 Métodos para a inspeção dos objetos model, view, controller
componente descrição
host.domain Indica o nome do servidor e seu domínio
Indica a porta de comunicação que deverá ser utilizada. Deve ser
port
a mesma que a configurada no VisualWave Web Serber.
Prefixo reconhecido pelo TinyHttpServer. De início são reconheci-
dos três prefixos:
• echo - retorna informações das requisições ao servidor
pathPrefix
para o browser. Serve para testar conecções.
• lauch - inicia aplicações
• submit - interação com aplicações em funcionamento.
Indica a aplicação a ser iniciada. Deve ter a mesma grafia que o
path
nome da classe.
Tabela 18.1 componentes do endereço de uma aplicação web no VisualWave
http://localhost:8008/launch/Tools.CodingAssistant
Figura 18.8 Janela do VisualWave Server Console Exemplo 18.1 Abrindo o CodingAssistant em um browser
dentro do nosso arquivo imagem. O endereço para acesso das aplica- Este resultado um tanto quanto pobre de tradução de interfaces
ções, que deve ser digitado em um browser de páginas possui a seguinte pelo VisualWave ocorre unica e exclusivamente porque o CodingAssis-
sintaxe: tant não foi projetado para ser executado na web.
http://host.domain:port/pathPrefix/path
A tabela 18.1 detalha cada uma das partes do endereço
18.4 Como Escrever Aplicações Web?
O exemplo 18.1 mostra como podemos abrir o CodingAssintant
em um browser. Note na figura 18.9 a diferença de formatação existente O mais interessante do VisualWave é que ele permite que escre-
entre a aplicação aberta no Smalltalk e no Internet Explorer. vamos nossas aplicações web exatamente igual ao processo de escre-
ver aplicações desktop.
Note que muito da formatação do CodingEditor foi perdida ao
abrirmos o mesmo no browser. Ocorre também que o botão que estava Porém como o VisualWave traduz os widgets para HTML, exis-
desabilitado não foi apresentado. Isso ocorre porque para o VisualWave, tem alguns widgets que não são traduzidos corretamente. Por exemplo,
quando um componente está desabilitado ele é interpretado como com- um grid é traduzido como uma tabela com radio buttons em cada célula.
ponente invisível. Desta forma, a melhor maneira de se escrever uma aplicação
para web em Smalltalk é ir testando passo-a-passo a aprarência e o fun-
cionamento de sua aplicação.
Como alguns dos widgets padão do smalltalk não possuem um Widgets não
euqivalente em HTML, eles simplesmente não são suportados. Quando suportados
posicionamos um destes widgets não suportados em um canvas eles
ficarão invisíveis. Para saber mais sobre como o VisualWave suporta os
widgets posicione qualquer widget em um canvas e então verifique suas
propriedades. Com o VsualWave instalado, novas abas de propriedades
serão adicionadas. Veja a chamada Web notes. A seguir vemos uma lista
dos widgets que não são suportados:
• ComboBox
• GroupBox
• DataSet
• Region
Figura 18.9 CodingAssintant aberto no Smalltalk e o internet explorer.
• Slider
Existem algumas outras dicas que devem ser observadas ao se • Notebook
escrever uma aplicação web: • SubCanvas
• Como o processamento da aplicação fica do lado do servidor, Existem alguns problemas também em relação a propriedades
devemos evitar automações de interface, tipo formatar iterativa- de widgets que não são suportadas. O leitor pode encontrar toda a infor-
mente um input field, isso porque no VisualWave se espera que mação sobre compatibilidade de widgets e HTML na aba web notes
vários widgets sejam preenchidos e só então os processa. O citada anteriormente.
processamento é feito na ordem dos tabs.
/LVWDGH)LJXUDV
6. SPICE:
YASUMATSU, Kazuki. A Translation Method from Smalltalk into
Interoperable C Code. 1996, 101f. Dissertação (Doutorado em Engenha-
ria) - Graduate School of Engineering Science of Osaka University, Osaka.
Menus
O Menu Editor sobre um menu vazio 285
Botões para a criação de itens de menu 286
Botões para reposicionamento dos itens de menu 286
Janela para instalação de um menu como recurso 287
Ícone que representa um menu como recurso 287
Aba de propriedades do Menu Editor 288
Aba de propriedades Details do Menu Editor 290
Menu gerado pelo código do exemplo 15.2 292
Menu criado utilizando a classe MenuBuilder 293
Menu produzido pelo código do exemplo 15.4 295
Definindo uma barra de menu 296
Exemplo de utilização de menu 298
Mensagens e Métodos
Regras para formação de mensagens 104
Mensagens binárias mais comuns 106
Regras de precedência de menságens 114
Protocolos comumente utilizados pela biblioteca de classes 126
Processos e Semáforos
Métodos para a criação de instancias da classe Delay 195
Menus
Criação de Aplicações para WWW
Código para gerar dinamicamente um menu simples 290
Abrindo o CodingAssistant em um browser 341
Código para gerar dinamicamente um menu com valores de retorno 292
Construindo um menu utilizando recursos da classe MenuBuilder 294
Construindo um menu usando código para menus padronizados 295
Menu-exemplo 295
Modificação do código 297