An oversigt over blokers eksekveringskontekst
I denne artikel kommer vi til at udforske følgende emner:
- scopes og blokke
- flad scope guard i klasse/modul
Først er du velkommen til at kigge på Scope Gates i Ruby: Del II-artiklen.
Hvor vi går i gang
Jeg er glad for at dele vores seneste projekt med dig: Fun Facts about Ruby – Volume 1
Du er velkommen til at sprede budskabet og dele dette link! 🙏
Tak for din tid!
I Ruby kan en blok få adgang til ydre scope
I dette eksempel kan vi få adgang til outer_scope_variable
-variablen inden for vores blok. Vores blok får adgang til denne variabel, selv om variablen er deklareret på et main
-niveau scope. I dette tilfælde siger vi, at blokken flatterer scopes. Det er derfor, vi almindeligvis kalder denne mekanisme: Flat Scope.
På den anden side skaber blokken et isoleret scope – selv om værdien af self
inden for blokken fortsat er main
-objektet.
Så vi kan ikke få adgang til lokale variabler, der er defineret inden for blokken
Her kan vi ikke få adgang til block_variable
fra det ydre scope. Nu hvor vi er mere fortrolige med begrebet flat scope i Ruby, lad os se, om dette begreb påvirker klassedefinitionen.
Klasse, modul og blok
I Ruby er det, man almindeligvis kalder en klasse, bag scenen en instans af Class
-klassen
Her opretter vi Hello
– og Greeting
-klasserne på to forskellige måder:
- ved hjælp af nøgleordet
class
- ved at tildele en instans af
Class
-klassen tilGreeting
-konstanten
Bemærk, at vi overdrager en blok til Class.new
-metoden. Denne blok vil blive fortolket som indholdet af klassen. Normalt kan en klasse ikke få adgang til variabler, der er defineret i det ydre scope – da nøgleordet class
ændrer værdien af self
og skaber et isoleret scope.
Så da vi bruger en blok til at oprette vores Greeting
-klasse, burde vi kunne bruge den flade scope-mekanisme. Virkelig?
Her kan vi se, at værdien af self
ændres, når vi bruger class
eller Class.new
.
Dertil kommer, at vores Class#message
-blok stadig er isoleret fra main
-objektet på grund af brugen af def
-keywordet. Da vores blok nemlig udføres i konteksten af metoden, så flader blokken scope inden for dette givne objekt – og ikke med et højere scope som main
-objektet.
Det er derfor, at vi ikke har adgang til outer_variable
inden for message
.
Men hvis vi bruger define_method
til at definere message
, så bliver scope fladet ud
Her, da define_method(:message)
tager en blok som argument, bliver scope for denne blok fladet ud, og denne metode har adgang til outer_variable
.
Voilà!