Ting du kan gjore i Smalltalk.

Mange ting som er vanskelig eller umulig a lose pa andre programmeringssprak, er enkle eller trivielle i et sv rt reflekterende system som Smalltalk. Mange av monstrene som samlet og beskrevet av gjengen pa fire er ikke nodvendig eller er mye enklere i Lisp eller i Smalltalk.

Dette dokumentet vil vise noe av denne typen – det handler ikke om ting du kan gjore i Smalltalk som du ogsa kan gjore pa noe annet sprak, men om ting som er veldig lett gjort i Smalltalk, men kjorer deg galt pa andre sprak.

Selv om du allerede er en smalltalker, kan det ogsa v re interessant a lese og fa nye ideer.

Smalltalk gir sv rt kraftige refleksjons- og manipulasjonsfunksjoner pa objektets referanse niva. For eksempel er det mulig a finne alle forekomster av en klasse: alle avledede forekomster: og kvitte seg med dem: Denne ene linjen vil hjelpe firefox i sin fjerningskode: V r sikker pa at jeg er helt klar over at ovenstaende bare er en hack for a fikse feil som faktisk er andre steder. Men det synes ganske klart a v re * MEGET * vanskelig a fikse disse feilene i utgangspunktet. Derfor vil en opprydding pa tabulasjonstid hjelpe mye, og etter min mening er en losning og reparasjon mye bedre enn den nav rende maten a handtere denne typen minnelekkasje via en «krasj soppelkasse».

I vanlig Lisp har jeg ofte onsket a iterere gjennom feltene i en struktur – a kaste ut referanser til et slettet objekt, for eksempel, eller finn felt som ikke er initialisert. Jeg vet at strukturene er bare vektorer under. Og likevel kan jeg ikke skrive en generell funksjon som jeg kan ringe pa noen struktur. Jeg kan bare fa tilgang til feltene etter navn, fordi det er en struktur som skal bety.

I Smalltalk kan du fa tilgang til et objekts spor ved hjelp av «instVarAt:», «instVarAt: put:» og «instVarNamed:» meldinger. Navnene pa sporene hentes med «allInstanceVariableNames», antall spor ved «instSize».

Dermed kan en feilsokingsmetode for a dumpe * innholdet av noe * objektet v re: selvfolgelig kan du ogsa skrive en blokk (aka-funksjon) for dette: og iterere over en samling objekter som skal dumpes med: a dumpe transskriptet, prov : Vennligst bruk IKKE slike ting i vanlig kode – det bor bare v re begrenset til feilsoking og stottekode. Hvis det brukes for mye, kan det gjore programmet vanskelig a forsta, vanskelig a feilsoke og sv rt vanskelig a vedlikeholde. Ogsa, du mister mange av IDEs fine og nyttige hjelpefunksjoner (sendere, implementatorer, tilgangsfunnere etc.).

Dynamisk genererte blokker.

Du kan (og bor) analysere koden for meldingene som sendes, for a sikre at ingen darlige meldinger (dvs. bare tillatt) blir introdusert hvis kodingen stammer fra en bruker: for eksempel a verifisere at brukeren ikke injiserer darlig kode inn i en skriptmotor: Bruk dette som grunnlag for a skrive ditt eget spreadsheet; Skriv om du onsker det, skriv din egen parser som legger til riktig operatorpreferanse, eller bruk den innebygde JavaScript-parseren.

For kontrollkode som ovenfor, kan de innebygde Parser- eller RBParser-rammene brukes. Deretter reflektere over parseTree i stedet for enten kilde- eller byte-kode.

Dynamisk genererte metoder.

Dynamisk genererte klasser.

Dynamisk genererende kode uten a pavirke ChangeFile / ChangeList.

En tilsvarende forekomstfremstillingsmetode kan v re:

Det faktum at vi kan legge til vare egne tilleggsopprettelsesmetoder (med et annet navn enn det vanlige «nye»), overvakes ofte av ikke-smatalere:

Fordelen med a v re et fullt dynamisk tastet sprak sikrer at denne koden selv virker uendret om ti ar, da femti nye klasser og underklasser for kontroll har blitt lagt til i ulike deler av et storre system.

Noen har hevdet «hvorfor vil man fortsette etter en hoyning» – men det er den typiske «Jeg er en hammer – alt ma v re en negle» -stilling – eller med andre ord: «Hvis alt jeg kan bruke til a heve for, er a signalere ikke -probleable vanskelige situasjoner, hvorfor vil jeg fortsette etter et unntak? «.

En mer intelligent spott er a se et unntak som «noe uventet skjedde – kan noen hjelpe?». eller til og med: «noe uventet skjedde – er det noen som er interessert?».

Hvis du ser pa unntak fra dette perspektivet, er det fornuftig a sende varsler, advarsler, fremdriftsinformasjon etc. alt ved hjelp av unntaksmekanismen. For eksempel, i Smalltalk / X, utfores alle informasjons- og fremdriftsvarsler ved a heve en varsling.

Enda mer praktisk er situasjonen dersom noe objekt dypt ned i det kallende hierarkiet trenger mer informasjon for a handtere en unormal situasjon. For eksempel kan en kompilator kanskje vite om det er greit a kompilere kode med stygg eller gammel stilkode i den. Hvis kompilatoren blir utfort i den interaktive IDE, og en bruker har oppstatt kompileringsoperasjonen, er det praktisk a apne et lite dialogvindu og spor brukeren. Men hvis kompileringen er innenfor en batchoperasjon, og 3000 filer skal kompileres, spor du ikke brukeren for hver metode. I Smalltalk / X brukes en sakalt Query – dette er et slags unntak som – hvis ikke behandlet, fortsetter med en standardverdi, men kan handteres og returnere en verdi som forespurt fra brukeren. Pa alle sprak uten gjennomforbare unntak, ma du overfore slike opplysninger enten via argumenter langs hver kalt funksjon, eller ved a sette globale eller andre statiske flagg, noe som senere gjor det vanskelig a bruke kompilatoren i en multithreaded operasjon.

Hvis du beregner verdier i et 32bit-miljo, ma du v re veldig forsiktig med a ikke generere feilresultater. Situasjonen er mindre av et problem med 64bit heltall (men fortsatt tilstede). Det krever imidlertid at programmereren alltid tenker pa konsekvensene og aldri glemmer a skrive «lang lenge» i stedet for «int». Programmorer ma ogsa alltid vite verdien av deres heltall – noe som kan v re vanskelig hvis du skriver en gjenbrukbar bibliotekskomponent, og du har ingen kontroll over innkommende verdier. Et annet problem er avrundingsfeil pa grunn av flytende punkt aritmetikk. En programmerer ma alltid tenke ikke bare pa typen («int», vs, «lang», vs. «lang lang»), men ogsa verdiene av mellomresultater.

For a illustrere dette, prov a vurdere et trivielt uttrykk som «a / b * c» med a, b, c som heltall. Uten mye a tenke, ville du skrive i C: (ja, du ville skrive det pa den maten, ikke sant?)

Na, hva med «a = 1», «b = 2», «c = 5»?.

Hvert barn forteller deg: «Vel, resultatet er 5/2 (eller 2,5, hvis du vil).

Men ikke sa den avanserte programmereren; Han ville si: «Vel, i teorien. Men i den virkelige verden er resultatet null, pa grunn av helhetskorting». Programmerer har en tendens til a «gjore dyder ut av nodvendigheter» og klandre seg selv for apenbare mangler i spraksystemet. Ekte programmorer kjenner systemets begrensninger. BTW, situasjonen er ikke bedre i C ++, Java og C # verdenen.

La oss fortsette for var underholdning; du kan tenke pa hvordan du kan fikse dette og skrive: god prove.

Men hva forventer du som svar, hvis du gir det «a = 100000001», «b = 100000000», «c = 100000000»?

Overraskelse, overraskelse: vi far «100000000». Vel, nok nok; hvem bryr seg om den lille feilen. Hvem bryr seg om den tapte penny – bare overfor den til kontoen min (ja, det er hva bankene vanligvis gjor)!

Ok, du sier, kan vi kvitte seg med avrundingsfeilen, og ga tilbake til heltallskoden. For a unnga trunking, la oss multiplisere forst: hores bedre ut, hva far vi?

Problemet med disse sprakene er at koden ser bra ut, men beregner noe radikalt forskjellig fra det du leser. Operasjonen som utfores i den ovennevnte koden, er faktisk: I Smalltalk kan du beregne en sa stor ting – men da vil du ogsa skrive det ned pa den maten!

Konklusjon: Det er sv rt vanskelig (men ikke umulig) a skrive matematiske korrekte beregninger uten et riktig numerisk klassehierarki.

Opphavsrett og kopi; 2007-2009 eXept Software AG, alle rettigheter forbeholdt.