In-Depth Ruby: Moduler & Include vs. Extend

Ruby gir en konstruksjon kalt en Module som er liksom som en tynn Klasse. Først Kan Ruby devs se På Moduler som En» søppelskuff » med kode som bare kastes rundt og brukes til å organisere filer, men det er en metode for denne galskapen. Ruby-klassenClass arver fra Module og legger til ting som instantiering, egenskaper, etc-alle ting du normalt ville tro en klasse ville ha – Fordi Module er bokstavelig talt en forfedre av Class, betyr Dette At Moduler kan behandles som klasser på noen måter.

Viktigst å forstå er hvordan Ruby stamfar kjeden fungerer. Som alle oop-språk støtter Ruby arv. Når du arver fra en klasse, legges superklassen til i stamfarskjeden din. Du kan se forfedrene til enhver klasse ved å ringe ancestors på den:

class Foo < BarendFoo.ancestors#=> 

som nevnt kan du finne Modulei matrisen Class.ancestors.

Når du include en modul i klassen din, blir modulen lagt til klassens forfederkjede – akkurat som en klasse. Dette gjør include bare en form for arv, det er ikke noe spesielt med det.

module Barendclass Foo include BarendFoo.ancestors#=> 

alle metodene iBar legges til Foo som instansmetoder. Fordi Bar er i kjeden, kan du til og med ringe super fra det å ringe metoder over det i kjeden, enten de er definert På Moduler eller Klasser.

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

selv omBarer en modul,superringer fortsatt opp kjeden og såBaz#hello kalles også. Det er verdt å merke seg at Bar legges til forfedrekjeden foran Baz. Når en modul er inkludert, er det alltid lagt direkte på toppen av det er inkludert klasse. Dette kan bli forvirrende når du legger til flere moduler, siden de er inkludert i «omvendt» rekkefølge:

class Foo include A include BendFoo.ancestors#=> 

når A er inkludert, settes den inn direkte over Foo. Men når B er inkludert, er det også satt inn direkte over Foo, så det ender opp landing før A.

include vs extend

include er lett nok å forstå, det legger modulens metoder som instans metoder til det er inkludert klasse. Du kan tenke på extend gjør det samme, men i stedet legger metodene som klassemetoder.

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

prepend

I tillegg til å inkludere / utvide, Legger Ruby 2.0+ tilprepend – metoden. prepend ligner på include, men setter i stedet inn modulen før inkludert-klassen i arvskjeden.

class Foo include Bar prepend BazendFoo.ancestors#=> 

I Ruby kan du åpne hvilken som helst klasse og omdefinere metodene på Den-det virker ikke nyttig å overstyre metoder på en klasse ved hjelp av en forhåndsdefinert modul i motsetning til å omdefinere dem. Hvorprepend kommer til nytte er når du fortsatt trenger den opprinnelige implementeringen av metoden, fordi forhåndsdefinerte moduler kan overstyre metoder, men fortsatt bruke super for å ringe den opprinnelige implementeringen.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.