Quais são os usos que o Smalltalk 'se tornou:' tem?


12

A become:mensagem no Smalltalk faz com que um objeto mude para outro, afetando todas as referências a ele.

Quais usos esse recurso de idioma tem? Ele é usado em código real? É apenas uma curiosidade? É uma prática boa / ruim usá-lo?

Respostas:


11

Gilad Bracha fala sobre become:um pouco:

Um dos recursos mais exclusivos e poderosos do Smalltalk também é um dos menos conhecidos fora da comunidade do Smalltalk. É um pequeno método chamado tornar-se:.

O que se torna: o faz é trocar as identidades de seu receptor e seu argumento. Ou seja, depois

a tornar-se: b

todas as referências ao objeto indicado por a antes do ponto de chamada referem-se ao objeto indicado por be vice-versa.

Reserve um minuto para internalizar isso; você pode entender isso como algo trivial. Não se trata de trocar duas variáveis ​​- é literalmente que um objeto se torna outro. Não conheço nenhum outro idioma que tenha esse recurso. É uma característica de enorme poder - e perigo.

Considere a tarefa de estender seu idioma para suportar objetos persistentes. Digamos que você queira carregar um objeto do disco, mas não deseja carregar todos os objetos aos quais ele se refere transitivamente (caso contrário, é apenas desserialização de objeto). Portanto, você carrega o próprio objeto, mas, em vez de carregar suas referências diretas, substitui-os por objetos husk.

As cascas substituem os dados reais no armazenamento secundário. Esses dados são carregados preguiçosamente. Quando você realmente precisa invocar um método em uma casca, seu método doesNotUnderstand: carrega o objeto de dados correspondente do disco (mas, novamente, não de maneira transitória).

Em seguida, torna-se :, substituindo todas as referências à casca por referências ao objeto recém-carregado e tenta novamente a chamada.

Alguns mecanismos de persistência fazem esse tipo de coisa há décadas - mas geralmente contam com acesso de baixo nível à representação. Tornar-se: permite fazer isso no nível do código-fonte.

Agora faça isso em Java. Ou mesmo em outra linguagem dinâmica. Você reconhecerá que pode fazer uma forma geral de futuros dessa maneira e, portanto, preguiça. Tudo sem acesso privilegiado ao funcionamento da implementação. Também é útil para a evolução do esquema - quando você adiciona uma variável de instância a uma classe, por exemplo. Você pode "remodelar" todas as instâncias, conforme necessário.

Claro, você não deve usar o transform: casualmente. Ele tem um custo, que pode ser proibitivo em muitas implementações. No início do Smalltalks, tornou-se: era barato, porque todos os objetos eram referenciados indiretamente por meio de uma tabela de objetos. Na ausência de uma tabela de objetos, torne-se: percorre a pilha de maneira semelhante a um coletor de lixo. Quanto mais memória você tiver, mais caro se torna: se torna.

Ter uma tabela de objetos ocupa o armazenamento e retarda o acesso; mas você compra muita flexibilidade. O suporte de hardware pode aliviar a penalidade de desempenho. A vantagem é que muitos problemas difíceis se tornam bastante tratáveis ​​se você estiver disposto a pagar o custo da indireção através de uma tabela de objetos com antecedência. Lembre-se: todo problema em ciência da computação pode ser resolvido com níveis extras de indireção. Alex Warth tem algum trabalho muito interessante que se encaixa nessa categoria, por exemplo.

Tornar-se: possui várias variações - de uma maneira, tornar-se: altera a identidade de um objeto A para a de outro objeto B, de modo que as referências a A agora aponte para B; as referências a B permanecem inalteradas. Muitas vezes, é útil tornar-se: em massa - transmutar as identidades de todos os objetos em uma matriz (unidirecionalmente ou bidirecionalmente). Um grupo se torna: o que faz mágica atomicamente é ótimo para implementar atualizações reflexivas em um sistema, por exemplo. Você pode alterar um conjunto inteiro de classes e suas instâncias de uma só vez.

Você pode até conceber o tipo safe tornar-se:. Tornar-se bidirecional: é seguro apenas para o tipo se o tipo de A for idêntico ao de B, mas tornar-se-á: apenas requer que o novo objeto seja um subtipo do antigo.

Talvez seja hora de reconsiderar se ter uma tabela de objetos é realmente uma coisa boa.

Efetivamente, o que você obtém é uma forma de carregamento lento através do que equivale a metaprogramação. Como Bracha aponta, isso pode ser muito útil, mas também é perigoso, pois pode ter um sério impacto no desempenho.


Eu estaria mais preocupado com becomeo impacto que está em minha sanidade mental do que no desempenho do meu programa ...
Benjamin Hodgson

Hardware support could ease the performance penalty.De todos os lugares que ouvi isso, a comunidade Smalltalk foi a mais proeminente. Por que devemos "gastar" as melhorias de hardware para permitir paradigmas de programação idealistas, quando, em vez disso, podem levar ao aumento do desempenho, à diminuição do uso de energia ou ao aumento da capacidade.
Alexander - Restabelece Monica

2

Não é muito usado. Na imagem do Pharo 5 que abri, existem 9 remetentes de #become :, 7 dos quais estão em testes de unidade. É usado no compilador na geração de código e na biblioteca de serialização do Fuel para substituir proxies pelo seu conteúdo.


Interessante. Para que os testes de unidade o usam?
DPK

para ver se ele funciona ...
Stephan Eggermont
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.