>9971
>
>
Set 20, 2019 – 3 min leia-se
Neste artigo, vamos explorar os seguintes tópicos:
>
- cópios e blocos
- guarda de escopo plano em classe/módulo
Primeiro, sinta-se livre para navegar pelos Portões de Escopo em Ruby: Parte II artigo.
Antes de começar
Estou entusiasmado por partilhar consigo o nosso último projecto: Fun Facts about Ruby – Volume 1
Por favor, sinta-se à vontade para espalhar a palavra e compartilhar este link! 🙏
Obrigado pelo seu tempo!
Em Ruby, um bloco pode acessar o escopo externo
Neste exemplo, podemos acessar a variável outer_scope_variable
dentro do nosso bloco. Nosso bloco obtém acesso a esta variável mesmo que a variável seja declarada em um nível de escopo main
. Neste caso, dizemos que o bloco achata o escopo. É por isso que normalmente chamamos este mecanismo: Flat Scope.
Por outro lado, o bloco cria um escopo isolado – mesmo que o valor de self
dentro do bloco permaneça o objeto main
.
Então não podemos acessar as variáveis locais definidas dentro do bloco
Aqui, não podemos acessar o block_variable
a partir do escopo externo. Agora que estamos mais familiarizados com a noção de escopo plano em Ruby, vamos ver se esta noção tem impacto na definição da classe.
Classe, módulo e bloco
Em Ruby, o que vulgarmente se chama uma classe é, por detrás da cena, uma instância da Class
classe
Aqui, criamos as classes Hello
e Greeting
de duas formas diferentes:
- usando a palavra-chave
class
- atribuindo uma instância da classe
Class
à Greeting
constante
Nota que estamos passando um bloco para o método Class.new
. Este bloco será interpretado como o conteúdo da classe. Normalmente uma classe não pode acessar variáveis definidas no escopo externo – como a palavra-chave class
muda o valor de self
e cria um escopo isolado.
Então, como usamos um bloco para criar nossa classe Greeting
, então devemos ser capazes de usar o mecanismo de escopo plano. Realmente?
Aqui podemos ver que o valor de self
muda quando usamos class
ou Class.new
.
Além disso, nosso Class#message
bloco ainda está isolado do objeto main
por causa do uso de def
palavra-chave. Na verdade, como o nosso bloco é executado no contexto do método, então o bloco achata o escopo dentro deste objeto dado – e não com um escopo maior como o objeto main
.
É por isso que não temos acesso a outer_variable
dentro de message
.
Mas se usarmos define_method
para definir message
então o escopo é achatado
Aqui, como define_method(:message)
toma um bloco como argumento, o escopo deste bloco é achatado e este método tem acesso a outer_variable
.
Voilà!