|
Seletades kuulajatele Ruby klasside ehitust, metaprogrammeerimist jmt, tekkis endalgi küsimus järgneva koodilõigu kohta, mida kohe ei suutnud ära vastata:
Küsimus: kuidas kutsuda välja meetod
Vihjeks niipalju, et maagia peitub Ruby operaatoris PS. tegemist kah nuputamisülesandega, mis mulle lihtsalt põnev tundus, kuid mille vastust ma ise juba (nüüdseks) tean. |
|
Kuna vastust ei laekunud, siis pean ilmselt ise ära vastama. Vastus ise on lühike, enamus on lihtsalt pikem selgitus, kuidas ja miks. Lühem variant on:
Pikem variant, mis natuke ka selgitab, miks see töötab:
Suusõnaliselt: meetod 'm3' defineeriti klassi A singleton klassi singleton klassi. Seletus: kogu Ruby maailm koosneb objektidest. Ka klassid ise on objektid (instantsid klassist Class). Ükski objekt pole kunagi suletud ja alati on võimalik neile täiendusi juurde teha. Kasvõi ühele ainukesele instantsile meetodit lisada:
Selline meetodi definitsioon tekitab uue meetodi punktiga viidatud objekti a_ sisse. Samast klassist tehtud teistele objektidele see välja ei paista. Siinkohal on hea tähele panna, et teistest keeltest tuntud _klassimeetodeid kui selliseid Rubys ei ole. Tühja kohta täidab meetodi definitsioon def self.m1, mis defineerib hoopis instantsimeetodi objektile self, mis sel hetkel (klassi defineerimise ajal) viitab klassi objektile endale, defineerides seega meetodi m1 klassi enda kui objekti "sisse", ilma, et see teistele klassidele (objektidele klassist Class) välja paistaks. Kuidas on aga võimalik, et üks meetod kuulub vaid ühele instantsile, mitte kõigile sama klassi objektidele? Ruby keeles on see lahendatud anonüümsete singleton klassidega (mitte segi ajada Singleton mustriga) - vajaduse tekkimisel lisatakse objektile uus ananüümne ülemklass, mis on ise alamklass algsest klassist. Nimi tuleneb sarnaselt Singleton mustrile asjaolust, et sellest klassist luuakse vaid üks objekt. Klasside põlvnemine visuaalselt:
Kõik laiendavad meetodid lisataksegi selle singleton klassi definitsiooni, nii et need saavad sellest klassist loodud ühe objekti osaks, kuid ei kuulu algse klassi A definitsiooni, seega ei paista välja teistele sama klassi objektidele. Kõik järgnevalt toodud koodiread avavad või tekitavad singleton klassi ning defineerivad meetodi selle klassi kirjelduses. Huvitav on märgata, et mitmed neist leiavad kasutust igapäevaselt, ilma, et singleton klasside olemasolu üldse oleks vaja teada:
Küsimuses kasutatigi just seda viimast konstruktsiooni 'class << a', kus avati objekti 'self' singleton klass. Lõpuks siis küsimuse kood kommenteeritud kujul:
Graafiliselt väljendudes:
|

Tundub, et vastustega just ei kiirustata. ;-) Enne kui vastuse lisan, annan veel ühe vihje: meetod 'm3' lisati Class objekti A Singleton klassile instantsimeetodiks. Nüüd küsimus, kuidas sellele Singleton klassile ligi pääseda?