Foto: Jack Anstey na Unsplash

An Přehled kontextu provádění bloků

Mehdi Farsi

Sledovat

20. září, 2019 – 3 minuty čtení

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à!

Articles

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.