La rubena metaklaso

La metaklaso estas interesa temo en Rubeno. Ĉiu objekto havas metaklason kaj ĝi situas inter objekto kaj sia klaso, sed ĝi ŝajnas kaŝiĝi. La metaklaso ne estas rekte atingebla per la sintakso, oni sole nerekte povas efiki ĝin. Kio ĝi estas kaj kiel ĝi utilas?

Kunteksto

En la Rubena programlingvo, ĉio estas objekto. Ŝajnas memevidenta, eĉ se tio ne veras en Ĝavo aŭ Pitono, kie la bazaj datumtipoj ne estas objektoj. Interese, en Rubeno ĉiu objekto ankaŭ havas klason, kiu ne nepre sekvas el ĉio estas objekto. Kiam oni kreas klason, tiu klaso estas objekto de la klaso KlasoClass.

Ĉu ekzistas la Metaklaso?

Se la metaklaso kaŝiĝas inter la objekto kaj la klaso, ĉu ĝi nur estas malekstera rubena afero. Fakte ne, estas kelkaj metodoj atingi ĝin. Jen ekzemplo:

class Homo
  def initialize(familia_nomo)
    @familia_nomo = familia_nomo
  end

  def familia_nomo
    @familia_nomo
  end
end

ludwik = Homo.new("Zamenhof")
marjorie = Homo.new("Boulton")

De tie, ni povas voki familia_nomo kaj ĝi liveras al ni kion ne anticipas.

ludwik.familia_nomo #=> "Zamenhof"
marjorie.familia_nomo #=> "Boulton"

Sed, familia_nomo apartenas al la klaso Homo. Por malfermi la metaklason, ni bezonas uzi specifin sintakson class << objekto.

class << ludwik
  def persona_nomo
    "Ludwik"
  end
end

Poste, ludwik havos funkcion persona_nomo

ludwik.persona_nomo #=> "Ludwik"

sed ne marjorie

marjorie.persona_nomo
> NoMethodError: undefined method `persona_nomo' for #<Homo:0x007fbbfc229e98 @familia_nomo="Boulton">
>    from (irb):31
>    from /usr/bin/irb:11:in `<main>'

Kial? Ni difinis persona_nomo je la metaklaso de ludwik kaj la metaklaso apartenas al ludwik kaj ne apartenas al marjorie.

Ĉu valoras?

Meti funkciojn je la metaklaso de objekto rompas reuzadon de funkciojn je klasoj, kiu estas forto de objektemaj/klasaj sistemoj, ĉu ne? Je datumobjektoj, jes, almenaŭ mi uzas ilin malofte. Sed, ĉu vi memoras dum la kunteksta sekcio ke eĉ klasoj estas objektoj de la klaso Class? Klasa nivelo funkcioj fakte apartenas al la metaklaso de la objekto de la Class, oj. Eble ekzemplo helpos:

Por aldoni funkcion al klason, ni povas difini ĝin sekve:

class Homo
  def self.planedo
    "La Tero"
  end
end

Tio egalas al:

class << Homo
  def planedo
    "La Tero"
  end
end

Do ĉiu klasa nivela funkcio estas funkcio je metaklaso. La samaĵoj estas

ludwik estas objekto de la klaso Homo,

Homo estas objekto de la klaso Class

Kaj

persona_nomo estas funkcio je la metaklaso de ludwik

planedo estas funkcio je la metaklaso de Homo

La metaklaso uziĝas multe en ĉiutaga programado, eĉ se la programistoj ne notas tion. Estas multe pli diri pri la metaklaso, sed mi pensas ke tio sufiĉas por nun.