Che usi ha 'diventa:' Smalltalk?


12

Il become:messaggio in Smalltalk fa sì che un oggetto si trasformi in un altro, influenzando tutti i riferimenti ad esso.

Che usi ha questa funzionalità linguistica? Viene utilizzato nel codice reale? È solo una curiosità? È considerato una buona / cattiva pratica usarlo?

Risposte:


11

Gilad Bracha ne parla become:a lungo:

Una delle funzionalità più uniche e potenti di Smalltalk è anche una delle meno conosciute al di fuori della comunità Smalltalk. È un piccolo metodo chiamato diventare:.

Cosa diventa: fa è scambiare le identità del suo destinatario e il suo argomento. Cioè dopo

a diventa: b

tutti i riferimenti all'oggetto indicati da a prima del punto di chiamata si riferiscono all'oggetto indicato da b, e viceversa.

Prenditi un minuto per interiorizzare questo; potresti fraintenderlo come qualcosa di banale. Non si tratta di scambiare due variabili: si tratta letteralmente di un oggetto che diventa un altro. Non sono a conoscenza di nessun'altra lingua che abbia questa funzione. È una caratteristica di enorme potere - e pericolo.

Prendi in considerazione il compito di estendere il tuo linguaggio per supportare oggetti persistenti. Supponiamo che tu voglia caricare un oggetto dal disco, ma non vuoi caricare tutti gli oggetti a cui fa riferimento in modo transitorio (altrimenti, è solo deserializzazione di oggetti semplici). Quindi carichi l'oggetto stesso, ma invece di caricare i suoi riferimenti diretti, li sostituisci con oggetti husk.

Gli husky sostituiscono i dati reali sull'archiviazione secondaria. Questi dati vengono caricati pigramente. Quando in realtà è necessario invocare un metodo su un husk, il suo doesNotUnderstand: il metodo carica l'oggetto di dati corrispondente dal disco (ma di nuovo, non in modo transitorio).

Quindi, diventa :, sostituendo tutti i riferimenti alla buccia con riferimenti all'oggetto appena caricato e ritenta la chiamata.

Alcuni motori di persistenza hanno fatto questo genere di cose per decenni, ma di solito si basavano su un accesso di basso livello alla rappresentazione. Diventa: ti consente di farlo a livello di codice sorgente.

Ora vai a fare questo in Java. O anche in un altro linguaggio dinamico. Riconoscerai che puoi fare una forma generale di futuri in questo modo, e quindi pigrizia. Tutto senza accesso privilegiato ai meccanismi di attuazione. È utile anche per l'evoluzione dello schema, ad esempio quando aggiungi una variabile di istanza a una classe. Puoi "rimodellare" tutte le istanze secondo necessità.

Certo, non dovresti usare diventa: casualmente. Ha un costo, che può essere proibitivo in molte implementazioni. All'inizio Smalltalks, diventa: era economico, perché tutti gli oggetti venivano indicati indirettamente tramite una tabella degli oggetti. In assenza di una tabella di oggetti, diventa: attraversa l'heap in modo simile a un garbage collector. Più memoria hai, più costoso diventa: diventa.

Avere una tabella oggetti occupa l'archiviazione e rallenta l'accesso; ma ti offre molta flessibilità. Il supporto hardware potrebbe alleggerire le prestazioni. Il vantaggio è che molti problemi difficili diventano abbastanza trattabili se si è disposti a pagare il costo di indiretta tramite una tabella degli oggetti in primo piano. Ricorda: ogni problema nell'informatica può essere risolto con livelli extra di indiretta. Alex Warth ha alcuni lavori molto interessanti che rientrano in questa categoria, ad esempio.

Diventa: ha diverse varianti - un modo diventa: cambia l'identità di un oggetto A in quella di un altro oggetto B, in modo che i riferimenti ad A ora puntino a B; i riferimenti a B rimangono invariati. Spesso è utile diventare: alla rinfusa - trasmutare le identità di tutti gli oggetti in un array (unidirezionalmente o bidirezionalmente). Un gruppo diventa: ciò che fa magicamente atomicamente è ottimo per implementare aggiornamenti riflessivi su un sistema, per esempio. Puoi cambiare un intero insieme di classi e le loro istanze in una volta sola.

Puoi anche concepire il tipo di sicurezza che diventa:. Due vie diventano: è sicuro solo se il tipo di A è identico a quello di B, ma una via diventa: richiede solo che il nuovo oggetto sia un sottotipo di quello vecchio.

Potrebbe essere il momento di riconsiderare se avere una tabella di oggetti sia effettivamente una buona cosa.

In effetti ciò che ottieni è una forma di caricamento lento tramite ciò che equivale alla metaprogrammazione. Come sottolinea Bracha, questo può essere molto utile, ma è anche pericoloso poiché può avere un grave impatto sulle prestazioni.


Sarei più preoccupato per becomel'impatto sulla mia sanità mentale che sull'esecuzione del mio programma ...
Benjamin Hodgson,

Hardware support could ease the performance penalty.Di tutti i posti in cui l'ho sentito, la comunità Smalltalk è stata la più importante. Perché dovremmo "spendere" miglioramenti hardware per consentire paradigmi di programmazione idealistica quando potrebbe invece portare a un aumento delle prestazioni, a un ridotto consumo di energia o a una maggiore capacità.
Alexander - Ripristina Monica il

2

Non è molto usato. Nell'immagine Pharo 5 che ho aperto, ci sono 9 mittenti di #become :, 7 dei quali sono in unit test. Viene utilizzato nel compilatore nella generazione del codice e nella libreria di serializzazione Fuel per sostituire i proxy con il loro contenuto.


Interessante. A cosa servono i test unitari?
dpk,

per vedere se funziona ...
Stephan Eggermont,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.