An Přehled kontextu provádění bloků
V tomto článku se budeme zabývat následujícími tématy:
- obory a bloky
- plochý strážce oboru ve třídě/modulu
Nejprve si neváhejte prohlédnout Brány oboru v Ruby:
Než začneme
S radostí se s vámi podělím o náš nejnovější projekt: Zábavná fakta o Ruby – 1. díl
Prosím, neváhejte a sdílejte tento odkaz! 🙏
Děkuji vám za váš čas!
V jazyce Ruby může blok přistupovat k vnějšímu oboru
V tomto příkladu můžeme v rámci našeho bloku přistupovat k proměnné outer_scope_variable
. Náš blok získá přístup k této proměnné, přestože je proměnná deklarována v oboru úrovně main
. V tomto případě říkáme, že blok zplošťuje obory. Proto tento mechanismus běžně nazýváme:
Na druhé straně blok vytváří izolovaný obor – i když hodnota self
uvnitř bloku zůstává objektem main
.
Nemůžeme tedy přistupovat k lokálním proměnným definovaným uvnitř bloku
Tady nemůžeme přistupovat k block_variable
z vnějšího oboru. Nyní, když jsme se lépe seznámili s pojmem flat scope v jazyce Ruby, se podíváme, zda tento pojem ovlivňuje definici třídy.
Třída, modul a blok
V jazyce Ruby je to, čemu se běžně říká třída, za scénou instancí třídy Class
Tady vytváříme třídy Hello
a Greeting
dvěma různými způsoby:
- pomocí klíčového slova
class
- přiřazením instance třídy
Class
konstantěGreeting
Všimněte si, že metodě Class.new
předáváme blok. Tento blok bude interpretován jako obsah třídy. Normálně třída nemůže přistupovat k proměnným definovaným ve vnějším oboru – protože klíčové slovo class
mění hodnotu self
a vytváří izolovaný obor.
Protože tedy používáme blok k vytvoření naší třídy Greeting
, pak bychom měli být schopni použít mechanismus plochého oboru. Opravdu?“
Zde vidíme, že hodnota self
se mění při použití class
nebo Class.new
.
Takže náš blok Class#message
je stále izolovaný od objektu main
díky použití klíčového slova def
. Protože se totiž náš blok provádí v kontextu metody, pak blok zplošťuje rozsah v rámci tohoto daného objektu – a ne s vyšším rozsahem jako objekt main
.
Proto nemáme přístup k outer_variable
v rámci message
.
Pokud ale použijeme define_method
k definici message
, pak se rozsah zploští
Jelikož define_method(:message)
přijímá jako argument blok, rozsah tohoto bloku se zploští a tato metoda má přístup k outer_variable
.
Voilà!