Zichtsfeer, zoals kamers in een huis
toen we het over variabelen hadden, vermeldden we dat het meest voorkomende type variabelen de “lokale variabele” is, zonder verder uit te leggen waarom ze lokaal zijn. Lokaal voor wat? Waar? We zijn eindelijk klaar om dat meer uit te leggen.
aangezien we nu over methoden hebben gesproken, kunnen we ook een ander belangrijk concept bespreken: scopes.
Wikipedia zegt: “in programmeren is het bereik van een naam het deel van een programma waar de naam geldig is: waar de naam kan worden gebruikt om naar iets te verwijzen.”(enigszins aangepast aan onze eigen terminologie)
namen zijn bekend (of gedefinieerd) in een bepaalde scope, en Onbekend (of ongedefinieerd)buiten deze scope.
u kunt denken aan een scope als van een bol, een bubbel, of een ruimte (met nowindows, en deuren gesloten): bepaalde namen, zoals variabele namen, zijn “bekend” en”zichtbaar” in de ruimte. Andere namen, bekend en zichtbaar in een andere kamer zijn niet bekend in deze kamer, maar alleen in de andere kamer.
elke keer dat er een methode aanroep is, en de stroom van uitvoering het lichaam van de Method binnenkomt, komt het een nieuwe scope, of “room”binnen. Dingen die” lokaal “zijn in de scope van deze methode (dat wil zeggen dingen die” binnen ” van de kamer zijn), zijn alleen zichtbaar in deze scope. Daarbuiten zijn ze onbekend.
ongedefinieerde lokale variabele of methode
Dit is ook een goede gelegenheid om te praten over een foutmelding die je het vaakst kunt zien. Je ziet het bijvoorbeeld elke keer als je een typefout hebt gemaakt en een variabele of methodenaam verkeerd hebt gespeld.
beschouw deze code:
def add_two(number) number + 2endputs add_two(3)puts number
de regel puts add_two(2)
zal 5
uitvoeren, maar de regel puts number
zal een fout veroorzaken.
Dit komt omdat de variabele number
die het nummer 3
krijgt wanneer we de methode een lokale variabele noemen. Het is lokaal om het bereik van de methode. Hetis gemaakt wanneer de stroom van uitvoering de methode binnenkomt.
buiten deze scope, wanneer de uitvoerstroom is teruggekeerd van de methode de scope van de methode is vernietigd, en alle lokale variabelen zijn verdwenen. De lokale variabele number
is daarom niet bekend, en Ruby geeft een foutmelding metundefined local variable or method 'number'
.
Als u even nadenkt over deze foutmelding, heeft het zin voor u?
we hebben stilletjes het feit overgeslagen dat in Ruby zowel lokale variablenamen als methodenamen op dezelfde manier worden geschreven: het zijn gewoon gewone woorden.Hier bijvoorbeeld:
number = 2puts number
number
is een lokale variabele, en wordt gebruikt in de regel puts number
.
echter, hier:
def number 2endputs number
number
is de naam van een methode. En het kan worden gebruikt (aangeroepen) op exact dezelfde manier: puts number
Dit komt omdat Ruby, wanneer het een programma uitvoert, het ene statement na het andere evalueert. En als het een gewoon woord tegenkomt zoals number
dan zal het eerst controleren of het, binnen de huidige scope, een lokale variabele met dezelfde naam kent. Als dat zo is, zal het de waarde gebruiken die aan deze variabele is gekoppeld. Als er geen lokale variabele met deze naam, dan zal het zoeken naar een methode. Als er ook geen methode is met deze naam zal het de foutmeldingundefined local variable or method 'number'
oproepen.
dus de foutmelding is vrij nauwkeurig, maar klinkt ook een beetje ingewikkeld. Wat het eigenlijk probeert te zeggen is:
je hebt het woord “nummer” hier gebruikt, en ik weet het niet (in deze scope). Wilde je een lokale variabele gebruiken? Of een methode?
slaat dat ergens op?
terug naar het onderwerp local scopes. Laten we eens kijken naar een ander voorbeeld:
number = 1def add_to(number) number + 2endputs add_to(3)
wat denk je dat de uitvoer zal zijn? Wordt het 3
, of 5
? Iets anders?
Als u de code uitvoert, zult u zien dat het 5
is.
de reden hiervoor is dat we het nummer 1
in de outer scope toewijzen aan avariable number
, maar deze variabele wordt dan nooit gebruikt: de enige andere regel in de outer scope is de laatste regel puts add_to(3)
, en deze regel gebruikt de variabele number
.
in plaats daarvan, wanneer de controlestroom de methode invoert add_to
zal Ruby een nieuwe lokale scope aanmaken, en zal het een nieuwe lokale variabele definiëren number
die het nummer 3
toegewezen krijgt dat aan de methode is doorgegeven. Deze nieuwe variabelenumber
is lokaal voor de scope van de methode, en daarom is dit een andervariabel dan die op de allereerste regel, in de buitenste scope.
We vonden het volgende een goede metafoor voor scopes:
wanneer Ruby een methode binnengaat, is het alsof ze een glanzende nieuwe kamer binnengaat in ahouse. Met haar, Ze brengt de objecten die worden doorgegeven als argumenten aan themethod call. In het voorbeeld hierboven brengt ze een object dat het nummer 3
is.
zodra Ruby de methode invoert, plakt ze post-it notities op de objects, volgens de lijst met argumenten uit de methode definitie. In ons voorbeeld is dat de naam number
. Dus vanaf nu is er in deze ruimte een bekende lokale variabele die een waarde heeft toegewezen: het object (nummer) 3
met de post-it note number
erop.
in ons voorbeeld zijn de outer scope en de scope van de methode add_two
twee verschillende kamers, en er zijn twee verschillende post-it noten geplakt op twee verschillende nummers, die toevallig dezelfde naam op hen hebben.