Hlavní navigace

Ruby Eigenclass (Singleton Class)

12. 2. 2010 9:00 | Martin Popelák

Pri čítaní knihy Metaprogramming Ruby od Paolo Perrotta (pragprog.com) som narazil na zaujímavú informáciu, ktorá ma prekvapila a o ktorú by som sa tu rád podelil. Jedná sa o Eigenclass (niekedy nesprávne nazývaná aj Singleton Class). Poďme si teda postupne ozrejmiť o čo sa vlastne jedná.

Singleton metódy

Jedná sa o metódy, ktoré pridávame konkrétnej inštancii triedy a nie priamo triede. Napríklad:

str1 = "nejaky retazec"
str2 = "druhy retazec"

def str1.long_string?
  self.length > 10
end

str1.long_string? # => true
str2.long_string? # => NoMethodError
str1.singleton_methods # => ["long_string?"]

Metódy tried

Triedy sú tiež vlastne len objekty a názvy tried sú konštanty. Z toho vyplýva, že volanie metódy na triede a na objekte je zhodné:

objekt.metoda # volanie metódy na objekte odkazovanom premennou
Trieda.metoda_triedy # volanie metódy na objekte odkazovanom konštantou

Keďže volanie metódy na objekte funguje tak, že sa postupne prehľadáva trieda objektu a potom smerom hore v hierarchii tried, vzniká nám otázka, na akej triede sa definujú singleton metódy. Ak by to v našom prípade bola trieda String, fungovala by metóda long_string? pre každý objekt triedy String. Tak ako to teda je?

Eigenclass

Ruby nám niekedy neodkryje celú pravdu. Namiesto triedy, ktorú nám vracia metóda .class, môže mať objekt svoju vlastnú skrytú triedu. Tá sa nazýva eigenclass objektu. Môžme sa k nej dostať pomocou špeciálnej syntaxe založenej na kľúčovom slove class:

retazec = String.new
eigenclass = class << retazec
  self
end
eigenclass.class # => Class
eigenclass.to_s # => "#<Class:String>"

Na základe týchto poznatkov sa dozvedáme, že singleton-metódy sa v skutočnosti definujú na eigenclass daného objektu. Tak isto metóda instance_eval() upravuje eigenclass daného objektu. Zaujímavé, však? Ak máte radi podobné zaujímavosti a chcete preniknúť do tajov metaprogramovania a pozrieť sa Ruby viac pod kapotu, rozhodne túto knižku odporúčam.