în profunzime Ruby: module & Include vs.Extend

Ruby oferă o construcție numităModule care este un fel de clasă subțire. La început, Ruby devs s-ar putea uita la module ca un „sertar junk” de cod, care este doar aruncat în jurul și utilizate pentru a organiza fișiere, dar există o metodă de această nebunie. Clasa RubyClass moștenește de laModule și adaugă lucruri precum instanțierea, proprietățile etc. – toate lucrurile pe care în mod normal credeți că le-ar avea o clasă. Deoarece Moduleeste literalmente un strămoș alClass, aceasta înseamnă că modulele pot fi tratate ca clase în anumite moduri.

cel mai important pentru a înțelege este modul în care funcționează lanțul strămoș Rubin. Ca toate limbile OOP, Ruby acceptă moștenirea. Când moștenești dintr-o clasă, superclasa este adăugată lanțului tău strămoș. Puteți vizualiza strămoșii oricărei clase apelând ancestors pe ea:

class Foo < BarendFoo.ancestors#=> 

după cum sa menționat, puteți găsi Module în matrice Class.ancestors.

cândinclude un modul în clasa dvs., modulul este adăugat la lanțul strămoș al clasei dvs. – la fel ca o clasă. Acest lucru face include doar o formă de moștenire, nu există nimic special în acest sens.

module Barendclass Foo include BarendFoo.ancestors#=> 

toate metodele dinBar sunt adăugate laFoo ca metode de instanță. Deoarece bara este în lanț, puteți apela chiar super de la acesta pentru a apela metode deasupra acestuia în lanț, indiferent dacă sunt definite pe Module sau clase.

class Baz def hello p 'world' endendmodule Bar def hello p 'hello' super endendclass Foo < Baz include BarendFoo.new.hello#=> hello world

chiar dacăBareste un modul,superîncă apelează lanțul și astfelBaz#hello se mai numește. Este demn de remarcat faptul că Bar se adaugă lanțului strămoș în fața Baz. Atunci când un modul este inclus, acesta este întotdeauna adăugat direct pe partea de sus a acesteia, inclusiv clasa. Acest lucru poate deveni confuz atunci când adăugați mai multe module, deoarece acestea sunt incluse în ordinea ” inversă:

class Foo include A include BendFoo.ancestors#=> 

cândA este inclus, acesta este introdus direct deasupraFoo. Dar când B este inclus, este introdus și direct deasupra Foo, deci ajunge să aterizeze înainte de A.

include vs extinde

include este destul de ușor de înțeles, se adaugă metodele modulului ca metode de instanță pentru a include clasa. Vă puteți gândi la extend făcând același lucru, dar adăugând în schimb metodele ca metode de clasă.

module Bar def hello p 'hello' endendclass Foo extend BarendFoo.hello # no .new!# => 'hello'

prepend

pe lângă includerea/extinderea, Ruby 2.0+ adaugă metodaprependprepend este similar cu include, dar în schimb introduce modulul înainte de clasa inclusiv în lanțul de moștenire.

class Foo include Bar prepend BazendFoo.ancestors#=> 

în Ruby puteți redeschide orice clasă și redefini metodele de pe ea-nu pare util să înlocuiți metodele pe o clasă folosind un modul prepended, spre deosebire de redefinirea lor. Undeprepend vine la îndemână este atunci când mai aveți nevoie de implementarea inițială a metodei, deoarece modulele prefabricate pot suprascrie metodele, dar încă folosescsuper pentru a apela implementarea inițială.

Lasă un răspuns

Adresa ta de email nu va fi publicată.