Un panoramica del contesto di esecuzione dei blocchi

In questo articolo, esploreremo i seguenti argomenti:
- scope e blocchi
- flat scope guard in classe/modulo
Prima, sentitevi liberi di consultare l’articolo Scope Gates in Ruby: Parte II articolo.
Prima di iniziare
Sono entusiasta di condividere con voi il nostro ultimo progetto: Fun Facts about Ruby – Volume 1
Sentitevi liberi di spargere la voce e condividere questo link! 🙏
Grazie per il tuo tempo!
In Ruby, un blocco può accedere all’ambito esterno
In questo esempio, possiamo accedere alla variabile outer_scope_variable
dentro il nostro blocco. Il nostro blocco ha accesso a questa variabile anche se la variabile è dichiarata in uno scope di livello main
. In questo caso, diciamo che il blocco appiattisce gli scope. Questo è il motivo per cui chiamiamo comunemente questo meccanismo: Flat Scope.
D’altra parte, il blocco crea uno scope isolato – anche se il valore di self
all’interno del blocco rimane l’oggetto main
.
Quindi non possiamo accedere alle variabili locali definite all’interno del blocco
Qui, non possiamo accedere al block_variable
dallo scope esterno. Ora che abbiamo più familiarità con la nozione di ambito piatto in Ruby, vediamo se questa nozione ha un impatto sulla definizione della classe.
Classe, modulo e blocco
In Ruby, ciò che comunemente si chiama classe è, dietro la scena, un’istanza della classe Class
Qui, creiamo le classi Hello
e Greeting
in due modi diversi:
- utilizzando la parola chiave
class
- assegnando un’istanza della classe
Class
alla costanteGreeting
Nota che stiamo passando un blocco al metodo Class.new
. Questo blocco sarà interpretato come il contenuto della classe. Normalmente una classe non può accedere alle variabili definite nell’ambito esterno – poiché la parola chiave class
cambia il valore di self
e crea un ambito isolato.
Quindi, poiché usiamo un blocco per creare la nostra classe Greeting
allora dovremmo essere in grado di usare il meccanismo dell’ambito piatto. Davvero?
Qui possiamo vedere che il valore di self
cambia quando si usa class
o Class.new
.
Inoltre, il nostro blocco Class#message
è ancora isolato dall’oggetto main
grazie all’uso della parola chiave def
. Infatti, poiché il nostro blocco viene eseguito nel contesto del metodo, allora il blocco appiattisce lo scopo all’interno di questo dato oggetto – e non con uno scopo superiore come l’oggetto main
.
Ecco perché non abbiamo accesso a outer_variable
dentro message
.
Ma se usiamo define_method
per definire message
allora lo scopo è appiattito
Qui, poiché define_method(:message)
prende un blocco come argomento, lo scopo di questo blocco è appiattito e questo metodo ha accesso a outer_variable
.
Voilà!