Skip to content

Escopos

Leonel Sanches da Silva edited this page Feb 12, 2024 · 8 revisions

Escopos são momentos na execução de um programa em que certos elementos existem ou não, tais como variáveis, funções, objetos, etc., e são definidos por blocos de escopo.

Blocos de escopo normalmente são usados para definir funções, métodos e classes, mas Delégua suporta blocos de escopo órfãos, como no exemplo abaixo:

{ // Isso é um bloco de escopo órfão, ou seja, não pertence a qualquer estrutura da linguagem, 
  // como uma classe, uma função ou um método
  var a = "1";
}

escreva(a); // sinaliza erro, porque `a` foi declarada dentro de um bloco de escopo que já finalizou sua execução.

se a = "1" { // Este bloco de escopo pertence à instrução `se`, e é executado quando a é igual ao literal "1", um texto.
  escreva("A variável `a` tem o valor '1'.")
}

Se a variável não for um objeto de classe, ou se não tiver um método finalizar() declarado, a variável é simplesmente descartada com o restante do escopo.

Blocos de escopo são declarados entre chaves, { e }.

Toda execução de Delégua, seja pelo modo LAIR, seja pela execução de um programa, possui um escopo-padrão, também chamado de escopo global, implicitamente declarado. É nele que ficam variáveis e funções globais.

Variáveis declaradas no escopo global podem ser acessadas por um escopo mais interno, mas o contrário não é possível (como no exemplo anterior do escopo órfão). O exemplo a seguir demonstra como é possível acessar uma variável definida no escopo global por um bloco de escopo órfão.

var a = "1";
{
  escreva(a); // escreve 1, pois um escopo mais restritivo tem acesso ao escopo ao qual foi declarado.
}

O escopo interno pode alterar variáveis de escopos ancestrais sem necessidade de nova declaração.

var a = "1";
{
  a = "2";
}

escreva(a); // escreve 2

No entanto, se uma nova variável é declarada dentro de um escopo filho com o mesmo nome de outra variável num escopo pai, a variável declarada no escopo pai não pode mais ser acessada pelo nome no escopo filho.

var a = "1";
{
  var a = "2";
  escreva(a); // escreve 2
}

escreva(a); // escreve 1

Variáveis controladas por escopos e a declaração tendo ... como

A partir da versão 0.33.0, Delégua possui a declaração tendo ... como, que cuida do ciclo de vida da variável até o final do seu bloco de escopo. Ao finalizá-lo, se a variável é um objeto e possui um método chamado finalizar(), o método é chamado para executar lógicas adicionais necessárias ao descarte da variável. Por exemplo, se a variável é uma classe que manipula arquivos, pode ser interessante descartar buffers, fechar ponteiros de fluxo e descartar porções de memória que não serão mais utilizadas.

O exemplo a seguir ocorre ao utilizarmos funções da biblioteca delegua-arquivos:

const arquivos = importar('arquivos')
tendo arquivos.abrir('meu-arquivo.txt') como a {
    a.escrever('123')
} // Ao executar o fechamento de escopo, o arquivo é fechado para escrita e a variável `a` descartada.

Se a variável não é um objeto de classe, ou se não possui um método finalizar() implementado, a variável é simplesmente descartada juntamente com o escopo.