| |   |
| 80 | 80 | |
| 81 | 81 | \begin{code}{@TEST} |
| 82 | 82 | 3 + 4 --> 7 "envia '+ 4' para 3, resultando em 7" |
| 83 | | 20 factorial --> 2432902008176640000 "envia factorial, resultando em um numero grande" |
| 83 | 20 factorial --> 2432902008176640000 !\textit{"envia factorial, resultando em um número grande"}! |
| 84 | 84 | \end{code} |
| 85 | | %FIXME: "numero" sem acento! sessão "code" não aceita unicode ou 'latex escapes' |
| 86 | 85 | %FIXME: word wrapping da última frase está ruim |
| 87 | 86 | |
| 88 | 87 | A representação de \ct{20 factorial} certamente é diferente da representação de \ct{7}, mas porque ambos |
| … | … | |
| 172 | 172 | \needlines{7} |
| 173 | 173 | \begin{method}[dist:]{a distância entre dois pontos} |
| 174 | 174 | Point>>>dist: aPoint |
| 175 | | "Responde a distancia entre aPoint e o receptor." |
| 175 | !\textit{"Responde a distância entre aPoint e o receptor."}! |
| 176 | 176 | | dx dy | |
| 177 | 177 | dx := aPoint x - x. |
| 178 | 178 | dy := aPoint y - y. |
| … | … | |
| 182 | 182 | \begin{code}{@TEST} |
| 183 | 183 | 1@1 dist: 4@5 --> 5.0 |
| 184 | 184 | \end{code} |
| 185 | | %FIXME: "distancia" sem acento! sessão "code" não aceita unicode ou 'latex escapes' |
| 186 | 185 | |
| 187 | 186 | O motivo principal para preferir encapsulamento baseado em instância ao invés de encapsulamento |
| 188 | 187 | baseado em classe é que a primeira permite a coexistência de implementações diferentes da mesma abstração. |
| … | … | |
| 251 | 251 | |
| 252 | 252 | \needlines{5} |
| 253 | 253 | \begin{code}{@TEST | aColor |} |
| 254 | | aColor := Color blue. "Metodo blue no lado da classe" |
| 254 | aColor := Color blue. !\textit{"Método blue no lado da classe"}! |
| 255 | 255 | aColor --> Color blue |
| 256 | | aColor red --> 0.0 "Metodo de acesso red, no lado da instancia" |
| 257 | | aColor blue --> 1.0 "Metodo de acesso blue, no lado da instancia" |
| 256 | aColor red --> 0.0 !\textit{"Método de acesso red, no lado da instância"}! |
| 257 | aColor blue --> 1.0 !\textit{"Método de acesso blue, no lado da instância"}! |
| 258 | 258 | \end{code} |
| 259 | | %FIXME: termos sem acento! sessão "code" não aceita unicode ou 'latex escapes' |
| 260 | 259 | |
| 261 | 260 | Você define uma classe preenchendo o modelo oferecido no \subind{system browser}{lado da instância}. |
| 262 | 261 | Quando você aceita este modelo, o sistema cria não só a classe que você definiu, como também |
| … | … | |
| 508 | 508 | |
| 509 | 509 | \begin{method}[MagnitudeLessThan]{\ct{Magnitude>>><}} |
| 510 | 510 | Magnitude>>>< aMagnitude |
| 511 | | "Responde se o receptor e menor que o argumento." |
| 511 | !\textit{"Responde se o receptor é menor que o argumento."}! |
| 512 | 512 | ^self subclassResponsibility |
| 513 | 513 | \end{method} |
| 514 | | %FIXME: comentário sem acento (... receptor é ...) |
| 515 | 514 | |
| 516 | 515 | \noindent |
| 517 | 516 | Em contraste, o método \mthind{Magnitude}{>=} é concreto; ele é definido em termos de \ct{<}: |
| 518 | 517 | |
| 519 | 518 | \begin{method}[Magnitude>=]{\ct{Magnitude>>>>=}} |
| 520 | 519 | >= aMagnitude |
| 521 | | "Responde se o receptor e maior ou igual ao argumento." |
| 520 | !\textit{"Responde se o receptor é maior ou igual ao argumento."}! |
| 522 | 521 | ^(self < aMagnitude) not |
| 523 | 522 | \end{method} |
| 524 | | %FIXME: comentário sem acento (... receptor é ...) |
| 525 | 523 | O mesmo é verdadeiro para outros métodos de comparação. |
| 526 | 524 | |
| 527 | 525 | A classe \clsind{Character} é uma subclasse de \ct{Magnitude}; ela sobreescrever o método |
| … | … | |
| 529 | 529 | |
| 530 | 530 | \begin{method}[CharacterLessThan]{\ct{Character>>><}} |
| 531 | 531 | Character>>>< aCharacter |
| 532 | | "Responde true se o valor do receptor < o valor de aCharacter." |
| 532 | !\textit{"Responde true se valor do receptor < valor de aCharacter."}! |
| 533 | 533 | ^self asciiValue < aCharacter asciiValue |
| 534 | 534 | \end{method} |
| 535 | | %FIXME: comentário sem acento (... receptor é ...) |
| 536 | 535 | |
| 537 | 536 | %--------------------------------------------------------- |
| 538 | 537 | \subsection{Traits} |
| … | … | |
| 629 | 629 | Uma vez que diferentes objetos podem ter métodos diferentes para responder à mesma mensagem, |
| 630 | 630 | o método deve ser escolhido \emph{dinamicamente}, quando a mensagem é recebida. |
| 631 | 631 | \begin{code}{@TEST} |
| 632 | | 3 + 4 --> 7 "envia a mensagem + com argumento 4 para o inteiro 3" |
| 633 | | (1@2) + 4 --> 5@6 "envia a mensagem + com argumento 4 para o ponto (1@2)" |
| 632 | 3 + 4 --> 7 "envia a mensagem + com argumento 4 para o inteiro 3" |
| 633 | (1@2) + 4 --> 5@6 "envia a mensagem + com argumento 4 para o ponto 1@2" |
| 634 | 634 | \end{code} |
| 635 | 635 | \noindent |
| 636 | 636 | Como conseqüência, nós podemos enviar a \emph{mesma mensagem} para diferentes objetos, cada qual |
| … | … | |
| 725 | 725 | |
| 726 | 726 | \begin{method}[defaultColor]{Um método implementado localmente} |
| 727 | 727 | EllipseMorph>>>defaultColor |
| 728 | | "responde o estilo de cor/preenchimento padrao para o receptor" |
| 728 | !\textit{"responde o estilo de cor/preenchimento padrão do receptor"}! |
| 729 | 729 | ^ Color yellow |
| 730 | 730 | \end{method} |
| 731 | | %FIXME: "padrao" sem acento |
| 732 | 731 | \cmindex{EllipseMorph}{defaultColor} |
| 733 | 732 | |
| 734 | 733 | Em contraste, se nós enviarmos a mensagem \ct{openInWorld} para \ct{anEllipse}, o método não |
| … | … | |
| 737 | 737 | |
| 738 | 738 | \begin{method}[openInWorld]{Um método herdado} |
| 739 | 739 | Morph>>>openInWorld |
| 740 | | "Adiciona este morph ao mundo. Se em um MVC, entao oferece uma Morphic window para ele." |
| 740 | !\textit{"Adiciona este morph ao mundo. Se em um MVC, então oferece uma Morphic window para ele."}! |
| 741 | 741 | self couldOpenInMorphic |
| 742 | 742 | ifTrue: [self openInWorld: self currentWorld] |
| 743 | 743 | ifFalse: [self openInMVC] |
| 744 | 744 | \end{method} |
| 745 | | %FIXME: "entao" sem acento |
| 746 | 745 | \cmindex{Morph}{openInWorld} |
| 747 | 746 | |
| 748 | 747 | \begin{figure}[htb] |
| … | … | |
| 754 | 754 | \end{figure} |
| 755 | 755 | |
| 756 | 756 | %--------------------------------------------------------- |
| 757 | | \subsection{Returning self} |
| 757 | \subsection{Retornando si mesmo} |
| 758 | 758 | |
| 759 | | Notice that \ct{EllipseMorph>>>defaultColor} (\mthref{defaultColor}) explicitly returns \ct{Color yellow} whereas \ct{Morph>>>openInWorld} (\mthref{openInWorld}) does not appear to return anything. |
| 759 | Note que \ct{EllipseMorph>>>defaultColor} (\mthref{defaultColor}) retorna explicitamente |
| 760 | \ct{Color yellow} onde \ct{Morph>>>openInWorld} (\mthref{openInWorld}) |
| 761 | não parece retornar qualquer valor. |
| 760 | 762 | |
| 761 | | Actually a method \emph{always} answers a message with a value\,---\,which is, of course, an object. |
| 762 | | The answer may be defined by the \ct{^} construct in the method, but if execution reaches the end of the method without executing a \ct{^}, the method still answers a value: it answers the object that received the message. |
| 763 | | We usually say that the method ``answers \self'', because in Smalltalk the pseudo-variable \self represents the receiver of the message, rather like \ct{this} in \ind{Java}. |
| 764 | | \index{variable!pseudo} |
| 765 | | \index{return} |
| 766 | | \seeindex{caret}{return} |
| 763 | Na verdade, um método \emph{sempre} responde à uma mensagem com um valor\,---\,que é, obviamente, um objeto. |
| 764 | A resposta pode ser definida pelo operador \ct{^} dentro do método, mas se a execução chegar ao |
| 765 | fim do método sem executar um \ct{^}, o método ainda assim retorna um valor: o objeto que recebeu |
| 766 | a mensagem é retornado. |
| 767 | Nós, em geral, dizemos que o método ``retorna \self'', porque em \st a pseudo-variável \self representa |
| 768 | o receptor da mensagem, tal qual \ct{this} em \ind{Java}. |
| 769 | \index{variável!pseudo} |
| 770 | \index{retorno} |
| 771 | \seeindex{circunflexo}{retorno} |
| 767 | 772 | |
| 768 | | This suggests that \mthref{openInWorld} is equivalent to \mthref{openInWorldReturnSelf}: |
| 773 | Isto sugere que \mthref{openInWorld} é equivalente à \mthref{openInWorldReturnSelf}: |
| 769 | 774 | |
| 770 | 775 | \needlines{5} |
| 771 | | \begin{method}[openInWorldReturnSelf]{Explicitly returning self} |
| 776 | \begin{method}[openInWorldReturnSelf]{Retornando self explicitamente} |
| 772 | 777 | Morph>>>openInWorld |
| 773 | | "Add this morph to the world. If in MVC, |
| 774 | | then provide a Morphic window for it." |
| 778 | !\textit{"Adiciona este morph no mundo. Se em um MVC, |
| 779 | então oferece um Morphic window para ele."}! |
| 775 | 780 | self couldOpenInMorphic |
| 776 | 781 | ifTrue: [self openInWorld: self currentWorld] |
| 777 | 782 | ifFalse: [self openInMVC]. |
| 778 | | ^ self "Don't do this unless you mean it!" |
| 783 | ^ self !\textit{"Não faça isso, a não ser que voce realmente queira!"}! |
| 779 | 784 | \end{method} |
| 785 | Por que não é bom escrever \ct{^ self} explicitamente? |
| 786 | Bem, quando você retorna algo explicitamente, você está comunicando que o retorno é de interesse ao remetente. |
| 787 | Quando você explicitamente retorna \self, você está dizendo que espera que o remetente use o objeto retornado. |
| 788 | Este não é o caso aqui, portanto, é melhor não retornar \self explicitamente. |
| 780 | 789 | |
| 781 | | Why is writing \ct{^ self} explicitly not a good thing to do? |
| 782 | | Well, when you return something explicitly, you are communicating that you are returning something of interest to the sender. |
| 783 | | When you explicitly return \self, you are saying that you expect the sender to use the returned value. |
| 784 | | This is not the case here, so it is best not to explicitly return \self. |
| 785 | | |
| 786 | | This is a common idiom in \st, which Kent Beck refers to as ``Interesting return value'' \cite{Beck97a}: |
| 790 | Este é um idioma comum em \st, que Kent Beck chama de ``Valor de retorno interessante \footnote{``\emph{Interesting return value}''}'' \cite{Beck97a}: |
| 787 | 791 | \index{Beck, Kent} |
| 788 | 792 | |
| 789 | | \important{Return a value only when you intend for the sender to use the value.} |
| 793 | \important{Retorne um valor somente quando sua intenção é que o remetente use-o.} |
| 790 | 794 | |
| 791 | 795 | %--------------------------------------------------------- |
| 792 | | \subsection{Overriding and extension} |
| 793 | | |
| 794 | | If we look again at the \ct{EllipseMorph} class hierarchy in \figref{openInWorldLookup}, we see that the classes \ct{Morph} and \mbox{\ct{EllipseMorph}} both implement \ct{defaultColor}. |
| 795 | | In fact, if we open a new morph (\ct{Morph new openInWorld}) we see that we get a blue morph, whereas an ellipse will be yellow by default. |
| 796 | | \index{method!overriding} |
| 797 | | \index{method!extension} |
| 798 | | \seeindex{overriding}{method, overriding} |
| 799 | | \seeindex{extension}{method, extension} |
| 800 | | |
| 801 | | We say that \ct{EllipseMorph} \emph{overrides} the \ct{defaultColor} method that it inherits from \ct{Morph}. |
| 802 | | The inherited method no longer exists from the point of view of \ct{anEllipse}. |
| 803 | | |
| 804 | | Sometimes we do not want to override inherited methods, but rather \emph{extend} them with some new functionality, that is, we would like to be able to invoke the overridden method \emph{in addition to} the new functionality we are defining in the subclass. |
| 805 | | In \st, as in many object-oriented languages that support single inheritance, this can be done with the help of \super sends. |
| 806 | | |
| 807 | | The most important application of this mechanism is in the \ct{initialize} method. |
| 808 | | Whenever a new instance of a class is initialized, it is critical to also initialize any inherited instance variables. |
| 809 | | However, the knowledge of how to do this is already captured in the \ct{initialize} methods of each of the superclass in the inheritance chain. |
| 810 | | The subclass has no business even trying to initialize inherited instance variables! |
| 811 | | |
| 812 | | It is therefore good practice whenever implementing an initialize method to send \ct{super initialize} before performing any further \ind{initialization}: |
| 796 | \subsection{Sobreescrita e extensão} |
| 797 | |
| 798 | Se nós olharmos novamente a hierarquia da classe \ct{EllipseMorph} na \figref{openInWorldLookup}, |
| 799 | veremos que as classes \ct{Morph} e \mbox{\ct{EllipseMorph}} implementam \ct{defaultColor}. |
| 800 | |
| 801 | De fato, se nós abrirmos um novo morph (\ct{Morph new openInWorld}) nós veremos um morph azul, por outro |
| 802 | lado, uma elipse será amarela por padrão. |
| 803 | \index{método!sobreescrevendo} |
| 804 | \index{método!extensão} |
| 805 | \seeindex{sobreescrevendo}{método, sobreescrevendo} |
| 806 | \seeindex{extensão}{método, extensão} |
| 807 | |
| 808 | Nós dizemos que \ct{EllipseMorph} \emph{sobreescreve} o método \ct{defaultColor} que é herdado por \ct{Morph}. |
| 809 | O método herdado não mais existe do ponto de vista do \ct{anEllipse}. |
| 810 | |
| 811 | As vezes, nós não queremos sobreescrever métodos herdados, mas sim, \emph{extender} eles com alguma |
| 812 | funcionalidade nova. Ou seja, nós gostariamos de poder invocar o método sobreescrito \emph{além} da nova |
| 813 | funcionalidade que estamos definindo na subclasse. |
| 814 | Em \st, assim como em várias linguagens orientadas à objeto que suportam herança singular, isso pode |
| 815 | ser feito com a ajuda de \emph{super sends}. |
| 816 | |
| 817 | A aplicação mais importante deste mecanismo está no método \ct{initialize}. |
| 818 | Sempre que uma instância de uma classe é inicializada, inicializar qualquer variável de instância herdada é crítico. |
| 819 | Porém, o conhecimento de como fazer isso já existe nos métodos \ct{initialize} de cada superclasse |
| 820 | na cadeia da hierarquia. |
| 821 | A subclasse não deve sequer tentar inicializar variáveis de instância herdadas! |
| 822 | |
| 823 | É, portanto, boa prática enviar \ct{super initialize} antes de processar qualquer \ind{inicialização} posterior |
| 824 | ao implementar um método \emph{initialize}. |
| 813 | 825 | \index{super!initialize} |
| 814 | 826 | |
| 815 | 827 | \needlines{6} |
| 816 | 828 | \begin{method}[morphinit]{Super initialize} |
| 817 | 829 | BorderedMorph>>>initialize |
| 818 | | "initialize the state of the receiver" |
| 830 | "inicializa o estado do receptor" |
| 819 | 831 | super initialize. |
| 820 | 832 | self borderInitialize |
| 821 | 833 | \end{method} |
| 822 | 834 | |
| 823 | | \important{An \ct{initialize} method should always start by sending \ct{super initialize}.} |
| 835 | \important{Um método \ct{initialize} deve sempre começar enviando \ct{super initialize}.} |
| 824 | 836 | |
| 825 | 837 | %--------------------------------------------------------- |
| 826 | | \subsection{Self sends and super sends} |
| 838 | \subsection{\emph{Self sends} e \emph{super sends}} |
| 839 | |
| 840 | Nós precisamos de \super \subind{super}{send}{}s para compor o comportamento herdado que |
| 841 | de outra forma seria sobreescrito. A forma usual de compor métodos, sejam herdados ou não, |
| 842 | por outro lado, é por meio de \self \subind{self}{send}{}s. |
| 827 | 843 | |
| 828 | | We need \super \subind{super}{send}{}s to compose inherited behaviour that would otherwise be overridden. |
| 829 | | The usual way to compose methods, whether inherited or not, however, is by means of \self \subind{self}{send}{}s. |
| 844 | Como \self sends diferem de \super sends? |
| 845 | Como \self, \super representa o receptor da mensagem. |
| 846 | A única coisa que muda é a busca do método. |
| 847 | Ao invés da busca iniciar na classe do receptor, ela inicia na superclasse da classe do método |
| 848 | onde o \super send acontece. |
| 830 | 849 | |
| 831 | | How do \self sends differ from \super sends? |
| 832 | | Like \self, \super represents the receiver of the message. |
| 833 | | The only thing that changes is the \ind{method lookup}. |
| 834 | | Instead of lookup starting in the class of the receiver, it starts in the superclass of the class of the method where the \super send occurs. |
| 850 | Note que \super \emph{não} é a superclasse! |
| 851 | É um erro comum e natural pensar isso. |
| 852 | Também, é um erro pensar que a busca do método inicia na superclasse do receptor. |
| 853 | Nós veremos precisamente como isso funciona no próximo exemplo. |
| 835 | 854 | |
| 836 | | Note that \super is \emph{not} the superclass! |
| 837 | | It is a common and natural mistake to think this. |
| 838 | | It is also a mistake to think that lookup starts in the superclass of the receiver. |
| 839 | | We shall see with the following example precisely how this works. |
| 855 | Considere a mensagem \ct{initString}, que nós podemos enviar para qualquer morph: |
| 840 | 856 | |
| 841 | | Consider the message \ct{initString}, which we can send to any morph: |
| 842 | 857 | \begin{code}{@TEST | anEllipse | anEllipse := EllipseMorph new.} |
| 843 | 858 | anEllipse initString --> '(EllipseMorph newBounds: (0@0 corner: 50@40) color: Color yellow) setBorderWidth: 1 borderColor: Color black' |
| 844 | 859 | \end{code} |
| 845 | | The return value is a string that can be evaluated to recreate the morph. |
| 860 | O valor de retorno é uma string que pode ser executada para recriar o morph. |
| 846 | 861 | |
| 847 | | How exactly is this result obtained through a combination of \self and \super sends? |
| 848 | | First, \ct{anEllipse initString} will cause the method \ct{initString} to be found in the class \ct{Morph}, |
| 849 | | as shown in \figref{initStringLookup}. |
| 862 | Como exatamente isso é o resultado obtido por meio da combinação de \self e \super sends? |
| 863 | Em primeiro lugar, \ct{anEllipse initString} fará com que o método \ct{initString} seja |
| 864 | encontrado na classe \ct{Morph}, como mostrado na \figref{initStringLookup}. |
| 850 | 865 | |
| 851 | 866 | \begin{figure}[htb] |
| 852 | 867 | \begin{center} |
| … | … | |
| 877 | 877 | Morph>>>initString |
| 878 | 878 | ^ String streamContents: [:s | self fullPrintOn: s] |
| 879 | 879 | \end{method} |
| 880 | | The method \cmind{Morph}{initString} performs a \self send of \ct{fullPrintOn:}. |
| 881 | | This causes a second lookup to take place, starting in the class \ct{EllipseMorph}, and finding \mthind{BorderedMorph}{fullPrintOn:} in \ct{BorderedMorph} (see \figref{initStringLookup} once again). |
| 882 | | What is critical to notice is that the \self send causes the method lookup to start again in the class of the receiver, namely the class of \ct{anEllipse}. |
| 880 | O método \cmind{Morph}{initString} executa um \self send de \ct{fullPrintOn:}. |
| 881 | Isso faz com que uma segunda busca de método aconteça, iniciando na classe \ct{EllipseMorph}, |
| 882 | e encontrando \mthind{BorderedMorph}{fullPrintOn:} em \ct{BorderedMorph} |
| 883 | (veja a \figref{initStringLookup} novamente). |
| 884 | O que é importante notar é que o \self send faz com que a busca do método inicie novamente na |
| 885 | classe do receptor, ou seja, na classe do objeto \ct{anEllipse}. |
| 883 | 886 | |
| 884 | | \important{A \self send triggers a \emph{dynamic} method lookup starting in the class of the receiver.} |
| 887 | \important{Um \self send ativa uma busca de método \emph{dinâmica} iniciando na classe do receptor.} |
| 885 | 888 | |
| 886 | 889 | \needlines{4} |
| 887 | | \begin{method}[fullPrintOn]{Combining \super and \self sends} |
| 890 | \begin{method}[fullPrintOn]{Combinando \super e \self sends} |
| 888 | 891 | BorderedMorph>>>fullPrintOn: aStream |
| 889 | 892 | aStream nextPutAll: '('. |
| 890 | 893 | !\textbf{super fullPrintOn: aStream.}! |
| 891 | 894 | aStream nextPutAll: ') setBorderWidth: '; print: borderWidth; |
| 892 | 895 | nextPutAll: ' borderColor: ' , (self colorString: borderColor) |
| 893 | 896 | \end{method} |
| 894 | | At this point, \ct{BorderedMorph>>>fullPrintOn:} does a \super send to extend the |
| 895 | | \ct{fullPrintOn:} behaviour it inherits from its superclass. |
| 896 | | Because this is a \super send, the lookup now starts in the superclass of the class where the \super send occurs, namely in \ct{Morph}. |
| 897 | | We then immediately find and evaluate \ct{Morph>>>fullPrintOn:}. |
| 897 | Neste ponto, \ct{BorderedMorph>>>fullPrintOn:} faz um \super send para extender |
| 898 | o comportamento de \ct{fullPrintOn:} herdado de sua superclasse. |
| 899 | Uma vez que isso é um \super send, a busca do método inicia na superclasse da classe onde |
| 900 | o \super send acontece, ou seja, em \ct{Morph}. |
| 901 | Nós, então, encontramos e executamos imediatamente \ct{Morph>>>fullPrintOn:}. |
| 898 | 902 | |
| 899 | | Note that the \super lookup did not start in the superclass of the receiver. |
| 900 | | This would have caused lookup to start from \ct{BorderedMorph}, resulting in an infinite loop! |
| 903 | Note que a busca do método em \super não iniciou na superclasse do receptor. |
| 904 | Isso faria com que a busca do método iniciasse em \ct{BorderedMorph}, resultando em um \emph{loop} |
| 905 | infinito! |
| 901 | 906 | |
| 902 | | \important{A \super send triggers a \emph{static} method lookup starting in the superclass of the class of the method performing the \super send.} |
| 907 | \important{Um \super send ativa uma busca de método \emph{estática} iniciando na superclasse da classe do método executando o \super send.} |
| 903 | 908 | |
| 904 | | If you think carefully about \super send and \figref{initStringLookup}, you will realize that \super bindings are static: all that matters is the class in which the text of the \super send is found. |
| 905 | | By contrast, the meaning of \self is dynamic: it always represents the receiver of the currently executing message. This means that \emph{all} messages sent to \self are looked-up by starting in the receiver's class. |
| 909 | Se você pensar cuidadosamente sobre o \super send e a \figref{initStringLookup}, você verá que |
| 910 | a ligação das chamadas de métodos \super são estáticas: tudo o que importa é a classe na qual |
| 911 | o texto do \super send é encontrado. |
| 912 | Em contraste, o significado de \self é dinâmico: ele sempre representa o receptor da mensagem sendo executada. |
| 913 | Isso significa que \emph{todas} as mensagens enviadas a \self são buscadas iniciando na classe do receptor. |
| 906 | 914 | |
| 907 | 915 | %--------------------------------------------------------- |
| 908 | | \subsection{Message not understood} |
| 916 | \subsection{Mensagem não entendida} |
| 909 | 917 | |
| 910 | | What happens if the method we are looking for is not found? |
| 911 | | \index{message!not understood} |
| 918 | O que acontece se um método que nós buscamos não for encontrado? |
| 919 | \index{mensagem!not understood} %FIXME: deixa "not understood" mesmo? |
| 912 | 920 | |
| 913 | | Suppose we send the message \ct{foo} to our ellipse. |
| 914 | | First the normal method lookup would go through the inheritance chain all the way up to \clsind{Object} (or rather \clsind{ProtoObject}) looking for this method. |
| 915 | | When this method is not found, the \ind{virtual machine} will cause the object to send \ct{self doesNotUnderstand: #foo}. |
| 916 | | (See \figref{fooNotFound}.) |
| 921 | Suponha que nós enviemos a mensagem \ct{foo} para nossa elipse. |
| 922 | Primeiro, a busca de método iria percorrer normalmente a cadeia de herança completamente até a classe |
| 923 | \clsind{Object} (ou melhor, \clsind{ProtoObject}) procurando por este método. |
| 924 | Quando ele não for encontrado, a \ind{máquina virtual} fará com que o objeto envie \ct{self doesNotUnderstand: #foo}. |
| 925 | (Veja a \figref{fooNotFound}.) |
| 917 | 926 | |
| 918 | 927 | \begin{figure}[htb] |
| 919 | 928 | \begin{center} |
| 920 | 929 | \ifluluelse |
| 921 | 930 | {\includegraphics[width=\textwidth]{fooNotFound}} |
| 922 | 931 | {\includegraphics[width=0.8\textwidth]{fooNotFound}} |
| 923 | | \caption{Message \lct{foo} is not understood\label{fig:fooNotFound}} |
| 932 | \caption{Mensagem \lct{foo} não é entendida\label{fig:fooNotFound}} |
| 924 | 933 | \end{center} |
| 925 | 934 | \end{figure} |
| 926 | 935 | |
| 927 | | Now, this is a perfectly ordinary, dynamic message send, so the lookup starts again from the class \ct{EllipseMorph}, but this time searching for the method \ct{doesNotUnderstand:}. |
| 928 | | As it turns out, \ct{Object} implements \ct{doesNotUnderstand:}. |
| 929 | | This method will create a new \ct{MessageNotUnderstood} object which is capable of starting a Debugger in the current execution context. |
| 930 | | |
| 931 | | Why do we take this convoluted path to handle such an obvious error? |
| 932 | | Well, this offers developers an easy way to intercept such errors and take alternative action. |
| 933 | | One could easily override the method \mthind{Object}{doesNotUnderstand:} in any subclass of \ct{Object} and provide a different way of handling the error. |
| 934 | | |
| 935 | | In fact, this can be an easy way to implement automatic delegation of messages from one object to another. |
| 936 | | A \ct{Delegator} object could simply delegate all messages it does not understand to another object whose responsibility it is to handle them, or raise an error itself! |
| 936 | Agora, isso é uma mensagem dinâmica perfeitamente normal como todas as outras. Portanto, a busca |
| 937 | de método inicia novamente a partir da classe \ct{EllipseMorph}, mas desta vez, procurando pelo |
| 938 | método \ct{doesNotUnderstand:}. |
| 939 | Acontece que \ct{Object} implementa \ct{doesNotUnderstand:}. |
| 940 | Este método irá criar um novo objeto \ct{MessageNotUnderstood} que é capaz de iniciar um \emph{Debugger} |
| 941 | %FIXME: depurador?? |
| 942 | no contexto de execução atual. |
| 943 | |
| 944 | Por que nós tomamos este caminho tortuoso para lidar com um erro tão óbvio? |
| 945 | Bem, isso oferece aos desenvolvedores uma forma fácil de interceptar tais erros e definir ações alternativas. |
| 946 | Pode-se facilmente sobreescrever o método \mthind{Object}{doesNotUnderstand:} em qualquer |
| 947 | subclasse de \ct{Object} e oferecer uma forma diferente de lidar com este erro. |
| 948 | |
| 949 | De fato, esta pode ser uma maneira fácil de implementar delegação automática de mensagens de um objeto |
| 950 | para outro. Um objeto \ct{Delegator} poderia simplesmente delegar todas as mensagens que ele não entende |
| 951 | para outro objeto cuja responsabilidade é lidar com eles, ou ele mesmo ativar um erro! |
| 937 | 952 | |
| 938 | 953 | %========================================================= |
| 939 | 954 | \section{Shared variables} |
| toggle raw diff |
--- a/PortugueseBook/Model/Model.tex
+++ b/PortugueseBook/Model/Model.tex
@@ -80,9 +80,8 @@ como você faz para qualquer outro objeto.
\begin{code}{@TEST}
3 + 4 --> 7 "envia '+ 4' para 3, resultando em 7"
-20 factorial --> 2432902008176640000 "envia factorial, resultando em um numero grande"
+20 factorial --> 2432902008176640000 !\textit{"envia factorial, resultando em um número grande"}!
\end{code}
-%FIXME: "numero" sem acento! sessão "code" não aceita unicode ou 'latex escapes'
%FIXME: word wrapping da última frase está ruim
A representação de \ct{20 factorial} certamente é diferente da representação de \ct{7}, mas porque ambos
@@ -173,7 +172,7 @@ Porém, as variáveis de instância do outro ponto devem ser acessadas enviando
\needlines{7}
\begin{method}[dist:]{a distância entre dois pontos}
Point>>>dist: aPoint
- "Responde a distancia entre aPoint e o receptor."
+ !\textit{"Responde a distância entre aPoint e o receptor."}!
| dx dy |
dx := aPoint x - x.
dy := aPoint y - y.
@@ -183,7 +182,6 @@ Point>>>dist: aPoint
\begin{code}{@TEST}
1@1 dist: 4@5 --> 5.0
\end{code}
-%FIXME: "distancia" sem acento! sessão "code" não aceita unicode ou 'latex escapes'
O motivo principal para preferir encapsulamento baseado em instância ao invés de encapsulamento
baseado em classe é que a primeira permite a coexistência de implementações diferentes da mesma abstração.
@@ -253,12 +251,11 @@ no lado da instância.
\needlines{5}
\begin{code}{@TEST | aColor |}
-aColor := Color blue. "Metodo blue no lado da classe"
+aColor := Color blue. !\textit{"Método blue no lado da classe"}!
aColor --> Color blue
-aColor red --> 0.0 "Metodo de acesso red, no lado da instancia"
-aColor blue --> 1.0 "Metodo de acesso blue, no lado da instancia"
+aColor red --> 0.0 !\textit{"Método de acesso red, no lado da instância"}!
+aColor blue --> 1.0 !\textit{"Método de acesso blue, no lado da instância"}!
\end{code}
-%FIXME: termos sem acento! sessão "code" não aceita unicode ou 'latex escapes'
Você define uma classe preenchendo o modelo oferecido no \subind{system browser}{lado da instância}.
Quando você aceita este modelo, o sistema cria não só a classe que você definiu, como também
@@ -511,20 +508,18 @@ e outros para comparar objetos. Estes mpetodos são herdados pelas subclasses. O
\begin{method}[MagnitudeLessThan]{\ct{Magnitude>>><}}
Magnitude>>>< aMagnitude
- "Responde se o receptor e menor que o argumento."
+ !\textit{"Responde se o receptor é menor que o argumento."}!
^self subclassResponsibility
\end{method}
-%FIXME: comentário sem acento (... receptor é ...)
\noindent
Em contraste, o método \mthind{Magnitude}{>=} é concreto; ele é definido em termos de \ct{<}:
\begin{method}[Magnitude>=]{\ct{Magnitude>>>>=}}
>= aMagnitude
- "Responde se o receptor e maior ou igual ao argumento."
+ !\textit{"Responde se o receptor é maior ou igual ao argumento."}!
^(self < aMagnitude) not
\end{method}
-%FIXME: comentário sem acento (... receptor é ...)
O mesmo é verdadeiro para outros métodos de comparação.
A classe \clsind{Character} é uma subclasse de \ct{Magnitude}; ela sobreescrever o método
@@ -534,10 +529,9 @@ A classe \clsind{Character} é uma subclasse de \ct{Magnitude}; ela sobreescreve
\begin{method}[CharacterLessThan]{\ct{Character>>><}}
Character>>>< aCharacter
- "Responde true se o valor do receptor < o valor de aCharacter."
+ !\textit{"Responde true se valor do receptor < valor de aCharacter."}!
^self asciiValue < aCharacter asciiValue
\end{method}
-%FIXME: comentário sem acento (... receptor é ...)
%---------------------------------------------------------
\subsection{Traits}
@@ -635,8 +629,8 @@ O receptor, então, decide como responder selecionando seu próprio \emph{métod
Uma vez que diferentes objetos podem ter métodos diferentes para responder à mesma mensagem,
o método deve ser escolhido \emph{dinamicamente}, quando a mensagem é recebida.
\begin{code}{@TEST}
-3 + 4 --> 7 "envia a mensagem + com argumento 4 para o inteiro 3"
-(1@2) + 4 --> 5@6 "envia a mensagem + com argumento 4 para o ponto (1@2)"
+3 + 4 --> 7 "envia a mensagem + com argumento 4 para o inteiro 3"
+(1@2) + 4 --> 5@6 "envia a mensagem + com argumento 4 para o ponto 1@2"
\end{code}
\noindent
Como conseqüência, nós podemos enviar a \emph{mesma mensagem} para diferentes objetos, cada qual
@@ -731,10 +725,9 @@ A classe \ct{EllipseMorph} implementa \ct{defaultColor}, portanto o método apro
\begin{method}[defaultColor]{Um método implementado localmente}
EllipseMorph>>>defaultColor
- "responde o estilo de cor/preenchimento padrao para o receptor"
+ !\textit{"responde o estilo de cor/preenchimento padrão do receptor"}!
^ Color yellow
\end{method}
-%FIXME: "padrao" sem acento
\cmindex{EllipseMorph}{defaultColor}
Em contraste, se nós enviarmos a mensagem \ct{openInWorld} para \ct{anEllipse}, o método não
@@ -744,12 +737,11 @@ um método \ct{openInWorld} seja encontrado na classe \ct{Morph} (ver \figref{op
\begin{method}[openInWorld]{Um método herdado}
Morph>>>openInWorld
- "Adiciona este morph ao mundo. Se em um MVC, entao oferece uma Morphic window para ele."
+ !\textit{"Adiciona este morph ao mundo. Se em um MVC, então oferece uma Morphic window para ele."}!
self couldOpenInMorphic
ifTrue: [self openInWorld: self currentWorld]
ifFalse: [self openInMVC]
\end{method}
-%FIXME: "entao" sem acento
\cmindex{Morph}{openInWorld}
\begin{figure}[htb]
@@ -762,99 +754,114 @@ Morph>>>openInWorld
\end{figure}
%---------------------------------------------------------
-\subsection{Returning self}
+\subsection{Retornando si mesmo}
-Notice that \ct{EllipseMorph>>>defaultColor} (\mthref{defaultColor}) explicitly returns \ct{Color yellow} whereas \ct{Morph>>>openInWorld} (\mthref{openInWorld}) does not appear to return anything.
+Note que \ct{EllipseMorph>>>defaultColor} (\mthref{defaultColor}) retorna explicitamente
+\ct{Color yellow} onde \ct{Morph>>>openInWorld} (\mthref{openInWorld})
+não parece retornar qualquer valor.
-Actually a method \emph{always} answers a message with a value\,---\,which is, of course, an object.
-The answer may be defined by the \ct{^} construct in the method, but if execution reaches the end of the method without executing a \ct{^}, the method still answers a value: it answers the object that received the message.
-We usually say that the method ``answers \self'', because in Smalltalk the pseudo-variable \self represents the receiver of the message, rather like \ct{this} in \ind{Java}.
-\index{variable!pseudo}
-\index{return}
-\seeindex{caret}{return}
+Na verdade, um método \emph{sempre} responde à uma mensagem com um valor\,---\,que é, obviamente, um objeto.
+A resposta pode ser definida pelo operador \ct{^} dentro do método, mas se a execução chegar ao
+fim do método sem executar um \ct{^}, o método ainda assim retorna um valor: o objeto que recebeu
+a mensagem é retornado.
+Nós, em geral, dizemos que o método ``retorna \self'', porque em \st a pseudo-variável \self representa
+o receptor da mensagem, tal qual \ct{this} em \ind{Java}.
+\index{variável!pseudo}
+\index{retorno}
+\seeindex{circunflexo}{retorno}
-This suggests that \mthref{openInWorld} is equivalent to \mthref{openInWorldReturnSelf}:
+Isto sugere que \mthref{openInWorld} é equivalente à \mthref{openInWorldReturnSelf}:
\needlines{5}
-\begin{method}[openInWorldReturnSelf]{Explicitly returning self}
+\begin{method}[openInWorldReturnSelf]{Retornando self explicitamente}
Morph>>>openInWorld
- "Add this morph to the world. If in MVC,
- then provide a Morphic window for it."
+ !\textit{"Adiciona este morph no mundo. Se em um MVC,
+ então oferece um Morphic window para ele."}!
self couldOpenInMorphic
ifTrue: [self openInWorld: self currentWorld]
ifFalse: [self openInMVC].
- ^ self "Don't do this unless you mean it!"
+ ^ self !\textit{"Não faça isso, a não ser que voce realmente queira!"}!
\end{method}
+Por que não é bom escrever \ct{^ self} explicitamente?
+Bem, quando você retorna algo explicitamente, você está comunicando que o retorno é de interesse ao remetente.
+Quando você explicitamente retorna \self, você está dizendo que espera que o remetente use o objeto retornado.
+Este não é o caso aqui, portanto, é melhor não retornar \self explicitamente.
-Why is writing \ct{^ self} explicitly not a good thing to do?
-Well, when you return something explicitly, you are communicating that you are returning something of interest to the sender.
-When you explicitly return \self, you are saying that you expect the sender to use the returned value.
-This is not the case here, so it is best not to explicitly return \self.
-
-This is a common idiom in \st, which Kent Beck refers to as ``Interesting return value'' \cite{Beck97a}:
+Este é um idioma comum em \st, que Kent Beck chama de ``Valor de retorno interessante \footnote{``\emph{Interesting return value}''}'' \cite{Beck97a}:
\index{Beck, Kent}
-\important{Return a value only when you intend for the sender to use the value.}
+\important{Retorne um valor somente quando sua intenção é que o remetente use-o.}
%---------------------------------------------------------
-\subsection{Overriding and extension}
-
-If we look again at the \ct{EllipseMorph} class hierarchy in \figref{openInWorldLookup}, we see that the classes \ct{Morph} and \mbox{\ct{EllipseMorph}} both implement \ct{defaultColor}.
-In fact, if we open a new morph (\ct{Morph new openInWorld}) we see that we get a blue morph, whereas an ellipse will be yellow by default.
-\index{method!overriding}
-\index{method!extension}
-\seeindex{overriding}{method, overriding}
-\seeindex{extension}{method, extension}
-
-We say that \ct{EllipseMorph} \emph{overrides} the \ct{defaultColor} method that it inherits from \ct{Morph}.
-The inherited method no longer exists from the point of view of \ct{anEllipse}.
-
-Sometimes we do not want to override inherited methods, but rather \emph{extend} them with some new functionality, that is, we would like to be able to invoke the overridden method \emph{in addition to} the new functionality we are defining in the subclass.
-In \st, as in many object-oriented languages that support single inheritance, this can be done with the help of \super sends.
-
-The most important application of this mechanism is in the \ct{initialize} method.
-Whenever a new instance of a class is initialized, it is critical to also initialize any inherited instance variables.
-However, the knowledge of how to do this is already captured in the \ct{initialize} methods of each of the superclass in the inheritance chain.
-The subclass has no business even trying to initialize inherited instance variables!
-
-It is therefore good practice whenever implementing an initialize method to send \ct{super initialize} before performing any further \ind{initialization}:
+\subsection{Sobreescrita e extensão}
+
+Se nós olharmos novamente a hierarquia da classe \ct{EllipseMorph} na \figref{openInWorldLookup},
+veremos que as classes \ct{Morph} e \mbox{\ct{EllipseMorph}} implementam \ct{defaultColor}.
+
+De fato, se nós abrirmos um novo morph (\ct{Morph new openInWorld}) nós veremos um morph azul, por outro
+lado, uma elipse será amarela por padrão.
+\index{método!sobreescrevendo}
+\index{método!extensão}
+\seeindex{sobreescrevendo}{método, sobreescrevendo}
+\seeindex{extensão}{método, extensão}
+
+Nós dizemos que \ct{EllipseMorph} \emph{sobreescreve} o método \ct{defaultColor} que é herdado por \ct{Morph}.
+O método herdado não mais existe do ponto de vista do \ct{anEllipse}.
+
+As vezes, nós não queremos sobreescrever métodos herdados, mas sim, \emph{extender} eles com alguma
+funcionalidade nova. Ou seja, nós gostariamos de poder invocar o método sobreescrito \emph{além} da nova
+funcionalidade que estamos definindo na subclasse.
+Em \st, assim como em várias linguagens orientadas à objeto que suportam herança singular, isso pode
+ser feito com a ajuda de \emph{super sends}.
+
+A aplicação mais importante deste mecanismo está no método \ct{initialize}.
+Sempre que uma instância de uma classe é inicializada, inicializar qualquer variável de instância herdada é crítico.
+Porém, o conhecimento de como fazer isso já existe nos métodos \ct{initialize} de cada superclasse
+na cadeia da hierarquia.
+A subclasse não deve sequer tentar inicializar variáveis de instância herdadas!
+
+É, portanto, boa prática enviar \ct{super initialize} antes de processar qualquer \ind{inicialização} posterior
+ao implementar um método \emph{initialize}.
\index{super!initialize}
\needlines{6}
\begin{method}[morphinit]{Super initialize}
BorderedMorph>>>initialize
- "initialize the state of the receiver"
+ "inicializa o estado do receptor"
super initialize.
self borderInitialize
\end{method}
-\important{An \ct{initialize} method should always start by sending \ct{super initialize}.}
+\important{Um método \ct{initialize} deve sempre começar enviando \ct{super initialize}.}
%---------------------------------------------------------
-\subsection{Self sends and super sends}
+\subsection{\emph{Self sends} e \emph{super sends}}
+
+Nós precisamos de \super \subind{super}{send}{}s para compor o comportamento herdado que
+de outra forma seria sobreescrito. A forma usual de compor métodos, sejam herdados ou não,
+por outro lado, é por meio de \self \subind{self}{send}{}s.
-We need \super \subind{super}{send}{}s to compose inherited behaviour that would otherwise be overridden.
-The usual way to compose methods, whether inherited or not, however, is by means of \self \subind{self}{send}{}s.
+Como \self sends diferem de \super sends?
+Como \self, \super representa o receptor da mensagem.
+A única coisa que muda é a busca do método.
+Ao invés da busca iniciar na classe do receptor, ela inicia na superclasse da classe do método
+onde o \super send acontece.
-How do \self sends differ from \super sends?
-Like \self, \super represents the receiver of the message.
-The only thing that changes is the \ind{method lookup}.
-Instead of lookup starting in the class of the receiver, it starts in the superclass of the class of the method where the \super send occurs.
+Note que \super \emph{não} é a superclasse!
+É um erro comum e natural pensar isso.
+Também, é um erro pensar que a busca do método inicia na superclasse do receptor.
+Nós veremos precisamente como isso funciona no próximo exemplo.
-Note that \super is \emph{not} the superclass!
-It is a common and natural mistake to think this.
-It is also a mistake to think that lookup starts in the superclass of the receiver.
-We shall see with the following example precisely how this works.
+Considere a mensagem \ct{initString}, que nós podemos enviar para qualquer morph:
-Consider the message \ct{initString}, which we can send to any morph:
\begin{code}{@TEST | anEllipse | anEllipse := EllipseMorph new.}
anEllipse initString --> '(EllipseMorph newBounds: (0@0 corner: 50@40) color: Color yellow) setBorderWidth: 1 borderColor: Color black'
\end{code}
-The return value is a string that can be evaluated to recreate the morph.
+O valor de retorno é uma string que pode ser executada para recriar o morph.
-How exactly is this result obtained through a combination of \self and \super sends?
-First, \ct{anEllipse initString} will cause the method \ct{initString} to be found in the class \ct{Morph},
-as shown in \figref{initStringLookup}.
+Como exatamente isso é o resultado obtido por meio da combinação de \self e \super sends?
+Em primeiro lugar, \ct{anEllipse initString} fará com que o método \ct{initString} seja
+encontrado na classe \ct{Morph}, como mostrado na \figref{initStringLookup}.
\begin{figure}[htb]
\begin{center}
@@ -870,63 +877,78 @@ as shown in \figref{initStringLookup}.
Morph>>>initString
^ String streamContents: [:s | self fullPrintOn: s]
\end{method}
-The method \cmind{Morph}{initString} performs a \self send of \ct{fullPrintOn:}.
-This causes a second lookup to take place, starting in the class \ct{EllipseMorph}, and finding \mthind{BorderedMorph}{fullPrintOn:} in \ct{BorderedMorph} (see \figref{initStringLookup} once again).
-What is critical to notice is that the \self send causes the method lookup to start again in the class of the receiver, namely the class of \ct{anEllipse}.
+O método \cmind{Morph}{initString} executa um \self send de \ct{fullPrintOn:}.
+Isso faz com que uma segunda busca de método aconteça, iniciando na classe \ct{EllipseMorph},
+e encontrando \mthind{BorderedMorph}{fullPrintOn:} em \ct{BorderedMorph}
+(veja a \figref{initStringLookup} novamente).
+O que é importante notar é que o \self send faz com que a busca do método inicie novamente na
+classe do receptor, ou seja, na classe do objeto \ct{anEllipse}.
-\important{A \self send triggers a \emph{dynamic} method lookup starting in the class of the receiver.}
+\important{Um \self send ativa uma busca de método \emph{dinâmica} iniciando na classe do receptor.}
\needlines{4}
-\begin{method}[fullPrintOn]{Combining \super and \self sends}
+\begin{method}[fullPrintOn]{Combinando \super e \self sends}
BorderedMorph>>>fullPrintOn: aStream
aStream nextPutAll: '('.
!\textbf{super fullPrintOn: aStream.}!
aStream nextPutAll: ') setBorderWidth: '; print: borderWidth;
nextPutAll: ' borderColor: ' , (self colorString: borderColor)
\end{method}
-At this point, \ct{BorderedMorph>>>fullPrintOn:} does a \super send to extend the
-\ct{fullPrintOn:} behaviour it inherits from its superclass.
-Because this is a \super send, the lookup now starts in the superclass of the class where the \super send occurs, namely in \ct{Morph}.
-We then immediately find and evaluate \ct{Morph>>>fullPrintOn:}.
+Neste ponto, \ct{BorderedMorph>>>fullPrintOn:} faz um \super send para extender
+o comportamento de \ct{fullPrintOn:} herdado de sua superclasse.
+Uma vez que isso é um \super send, a busca do método inicia na superclasse da classe onde
+o \super send acontece, ou seja, em \ct{Morph}.
+Nós, então, encontramos e executamos imediatamente \ct{Morph>>>fullPrintOn:}.
-Note that the \super lookup did not start in the superclass of the receiver.
-This would have caused lookup to start from \ct{BorderedMorph}, resulting in an infinite loop!
+Note que a busca do método em \super não iniciou na superclasse do receptor.
+Isso faria com que a busca do método iniciasse em \ct{BorderedMorph}, resultando em um \emph{loop}
+infinito!
-\important{A \super send triggers a \emph{static} method lookup starting in the superclass of the class of the method performing the \super send.}
+\important{Um \super send ativa uma busca de método \emph{estática} iniciando na superclasse da classe do método executando o \super send.}
-If you think carefully about \super send and \figref{initStringLookup}, you will realize that \super bindings are static: all that matters is the class in which the text of the \super send is found.
-By contrast, the meaning of \self is dynamic: it always represents the receiver of the currently executing message. This means that \emph{all} messages sent to \self are looked-up by starting in the receiver's class.
+Se você pensar cuidadosamente sobre o \super send e a \figref{initStringLookup}, você verá que
+a ligação das chamadas de métodos \super são estáticas: tudo o que importa é a classe na qual
+o texto do \super send é encontrado.
+Em contraste, o significado de \self é dinâmico: ele sempre representa o receptor da mensagem sendo executada.
+Isso significa que \emph{todas} as mensagens enviadas a \self são buscadas iniciando na classe do receptor.
%---------------------------------------------------------
-\subsection{Message not understood}
+\subsection{Mensagem não entendida}
-What happens if the method we are looking for is not found?
-\index{message!not understood}
+O que acontece se um método que nós buscamos não for encontrado?
+\index{mensagem!not understood} %FIXME: deixa "not understood" mesmo?
-Suppose we send the message \ct{foo} to our ellipse.
-First the normal method lookup would go through the inheritance chain all the way up to \clsind{Object} (or rather \clsind{ProtoObject}) looking for this method.
-When this method is not found, the \ind{virtual machine} will cause the object to send \ct{self doesNotUnderstand: #foo}.
-(See \figref{fooNotFound}.)
+Suponha que nós enviemos a mensagem \ct{foo} para nossa elipse.
+Primeiro, a busca de método iria percorrer normalmente a cadeia de herança completamente até a classe
+\clsind{Object} (ou melhor, \clsind{ProtoObject}) procurando por este método.
+Quando ele não for encontrado, a \ind{máquina virtual} fará com que o objeto envie \ct{self doesNotUnderstand: #foo}.
+(Veja a \figref{fooNotFound}.)
\begin{figure}[htb]
\begin{center}
\ifluluelse
{\includegraphics[width=\textwidth]{fooNotFound}}
{\includegraphics[width=0.8\textwidth]{fooNotFound}}
-\caption{Message \lct{foo} is not understood\label{fig:fooNotFound}}
+\caption{Mensagem \lct{foo} não é entendida\label{fig:fooNotFound}}
\end{center}
\end{figure}
-Now, this is a perfectly ordinary, dynamic message send, so the lookup starts again from the class \ct{EllipseMorph}, but this time searching for the method \ct{doesNotUnderstand:}.
-As it turns out, \ct{Object} implements \ct{doesNotUnderstand:}.
-This method will create a new \ct{MessageNotUnderstood} object which is capable of starting a Debugger in the current execution context.
-
-Why do we take this convoluted path to handle such an obvious error?
-Well, this offers developers an easy way to intercept such errors and take alternative action.
-One could easily override the method \mthind{Object}{doesNotUnderstand:} in any subclass of \ct{Object} and provide a different way of handling the error.
-
-In fact, this can be an easy way to implement automatic delegation of messages from one object to another.
-A \ct{Delegator} object could simply delegate all messages it does not understand to another object whose responsibility it is to handle them, or raise an error itself!
+Agora, isso é uma mensagem dinâmica perfeitamente normal como todas as outras. Portanto, a busca
+de método inicia novamente a partir da classe \ct{EllipseMorph}, mas desta vez, procurando pelo
+método \ct{doesNotUnderstand:}.
+Acontece que \ct{Object} implementa \ct{doesNotUnderstand:}.
+Este método irá criar um novo objeto \ct{MessageNotUnderstood} que é capaz de iniciar um \emph{Debugger}
+%FIXME: depurador??
+no contexto de execução atual.
+
+Por que nós tomamos este caminho tortuoso para lidar com um erro tão óbvio?
+Bem, isso oferece aos desenvolvedores uma forma fácil de interceptar tais erros e definir ações alternativas.
+Pode-se facilmente sobreescrever o método \mthind{Object}{doesNotUnderstand:} em qualquer
+subclasse de \ct{Object} e oferecer uma forma diferente de lidar com este erro.
+
+De fato, esta pode ser uma maneira fácil de implementar delegação automática de mensagens de um objeto
+para outro. Um objeto \ct{Delegator} poderia simplesmente delegar todas as mensagens que ele não entende
+para outro objeto cuja responsabilidade é lidar com eles, ou ele mesmo ativar um erro!
%=========================================================
\section{Shared variables} |