Photo by Jack Anstey on Unsplash

An áttekintés a blokkok végrehajtási környezetéről

Mehdi Farsi

Follow

Sep 20, 2019 – 3 min read

Ebben a cikkben a következő témákat fogjuk megvizsgálni:

  • scopes and blocks
  • flat scope guard in class/module

Először is bátran böngészd át a Scope Gates in Ruby: Part II cikket.

Befejezés előtt

Örömömre szolgál, hogy megoszthatom veled legújabb projektünket: Fun Facts about Ruby – Volume 1

Kérem, nyugodtan terjessze a hírt és ossza meg ezt a linket! 🙏

Köszönjük, hogy időt szakított ránk!

A Rubyban egy blokk hozzáférhet a külső hatókörhöz

Ebben a példában a outer_scope_variable változóhoz férünk hozzá a blokkunkon belül. A blokkunk akkor is hozzáférhet ehhez a változóhoz, ha a változót main szintű hatókörben deklaráltuk. Ebben az esetben azt mondjuk, hogy a blokk laposítja a hatóköröket. Ezért szoktuk ezt a mechanizmust így hívni: Flat Scope.

A másik oldalon a blokk izolált hatóköröket hoz létre – még akkor is, ha a self értéke a blokkon belül a main objektum marad.

Ezért a blokkon belül definiált helyi változókat nem tudjuk elérni

Ezért a block_variable-hoz nem tudunk hozzáférni a külső hatókörből. Most, hogy jobban megismertük a lapos hatókör fogalmát a Rubyban, nézzük meg, hogy ez a fogalom befolyásolja-e az osztálydefiníciót.

osztály, modul és blokk

A Rubyban az, amit általában osztálynak hívunk, a színfalak mögött a Class osztály egy példánya

Itt a Hello és Greeting osztályokat két különböző módon hozzuk létre:

  • a class kulcsszó használatával
  • azzal, hogy a Class osztály egy példányát hozzárendeljük a Greeting konstanshoz

Megjegyezzük, hogy a Class.new metódusnak egy blokkot adunk át. Ez a blokk az osztály tartalmaként lesz értelmezve. Normális esetben egy osztály nem férhet hozzá a külső hatókörben definiált változókhoz – mivel a class kulcsszó megváltoztatja a self értékét, és létrehoz egy izolált hatókört.

Mivel tehát egy blokkot használunk a Greeting osztályunk létrehozásához, akkor a flat scope mechanizmust kell tudnunk használni. Valóban?

Itt láthatjuk, hogy a self értéke megváltozik, ha a class vagy a Class.new kulcsszót használjuk.

Az Class#message blokkunk a def kulcsszó használata miatt továbbra is izolált a main objektumtól. Valóban, mivel a blokkunk a metódus kontextusában kerül végrehajtásra, akkor a blokk az adott objektumon belül – és nem egy magasabb hatókörrel, mint a main objektum.

Ez az oka annak, hogy a message-on belül nem férünk hozzá a outer_variable-hez.

De ha a define_method-t használjuk a message definiálására, akkor a hatókör ellaposodik

Mivel a define_method(:message) egy blokkot vesz argumentumként, ennek a blokknak a hatókörét ellaposítjuk, és ez a metódus hozzáfér outer_variable-hez.

Voilà!

Articles

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.