Fotografie de Jack Anstey pe Unsplash

An overview of the execution context of blocks

Mehdi Farsi

Follow

Sep 20, 2019 – 3 min citește

În acest articol, vom explora următoarele subiecte:

  • scoape și blocuri
  • flat scope guard in class/module

În primul rând, nu ezitați să parcurgeți Scope Gates in Ruby: Partea a II-a.

Înainte de a începe

Sunt încântat să vă împărtășesc cel mai recent proiect al nostru: Fun Facts about Ruby – Volumul 1

Vă rugăm să nu ezitați să răspândiți vestea și să distribuiți acest link! 🙏

Mulțumim pentru timpul acordat!

În Ruby, un bloc poate accesa domeniul exterior

În acest exemplu, putem accesa variabila outer_scope_variable în cadrul blocului nostru. Blocul nostru are acces la această variabilă, chiar dacă variabila este declarată la un domeniu de nivel main. În acest caz, spunem că blocul aplatizează domeniile de cuprindere. Acesta este motivul pentru care numim în mod obișnuit acest mecanism: Flat Scope.

Pe de altă parte, blocul creează un scope izolat – chiar dacă valoarea lui self în cadrul blocului rămâne obiectul main.

Deci nu putem accesa variabilele locale definite în cadrul blocului

În acest caz, nu putem accesa block_variable din scope-ul exterior. Acum că suntem mai familiarizați cu noțiunea de flat scope în Ruby, să vedem dacă această noțiune are un impact asupra definirii claselor.

Clasă, modul și bloc

În Ruby, ceea ce se numește în mod obișnuit o clasă este, în spatele scenei, o instanță a clasei Class

Aici, creăm clasele Hello și Greeting în două moduri diferite:

  • folosind cuvântul cheie class
  • prin atribuirea unei instanțe a clasei Class la constanta Greeting

Rețineți că transmitem un bloc metodei Class.new. Acest bloc va fi interpretat ca fiind conținutul clasei. În mod normal, o clasă nu poate accesa variabilele definite în domeniul de cuprindere exterior – deoarece cuvântul cheie class schimbă valoarea lui self și creează un domeniu de cuprindere izolat.

Atunci, deoarece folosim un bloc pentru a crea clasa noastră Greeting, atunci ar trebui să putem folosi mecanismul domeniului de cuprindere izolat. Serios?

Aici putem vedea că valoarea lui self se schimbă atunci când folosim class sau Class.new.

De asemenea, blocul nostru Class#message este încă izolat de obiectul main datorită folosirii cuvântului cheie def. Într-adevăr, deoarece blocul nostru este executat în contextul metodei, atunci blocul își aplatizează domeniul de aplicare în cadrul acestui obiect dat – și nu cu un domeniu de aplicare mai mare ca obiectul main.

De aceea nu avem acces la outer_variable în cadrul message.

Dar dacă folosim define_method pentru a defini message atunci domeniul de cuprindere este aplatizat

Aici, deoarece define_method(:message) primește ca argument un bloc, domeniul de cuprindere al acestui bloc este aplatizat și această metodă are acces la outer_variable.

Voilà!

Articles

Lasă un răspuns

Adresa ta de email nu va fi publicată.