Pular para o conteúdo

Escopo

Como os nomes são resolvidos, e o que shadow faz.

A cadeia de escopos#

Cada bloco cria um escopo filho. Ao procurar um nome, o interpretador sobe a cadeia até encontrá-lo — ou dispara NameError_.

dataforge
global := "topo"

action externa():
    da_acao := "acao"

    action interna():
        do_bloco := "interna"
        out global, da_acao, do_bloco     # enxerga os três

    interna()

externa()

Atribuir atualiza onde existe#

dataforge
contador := 0

action incrementar():
    contador := contador + 1     # atualiza o de FORA
    yield contador

incrementar()
incrementar()
out contador                     # 2

:= procura o nome na cadeia. Se encontra, atualiza ali. Se não encontra, cria no escopo atual.

shadow — uma cópia local#

dataforge
x := 10

action sombreia():
    shadow x := 99     # cria uma cópia local, não toca no de fora
    yield x

out sombreia(), x      # 99 10

shadow diz explicitamente "este nome é meu, aqui dentro". Sem ele, a atribuição afetaria o x externo.

Escopos de bloco#

Laços, condicionais e blocos monitor criam escopos próprios. A variável do cycle existe só ali dentro:

dataforge
cycle i from 1 to 3:
    dentro := i * 2

# out i        # erro — 'i' não existe aqui fora

O mesmo vale para a variável de uma compreensão.

Closures#

Uma ação aninhada captura o escopo onde foi criada, e o mantém vivo mesmo depois que a ação externa terminou:

dataforge
action fabrica(n):
    action somador(x):
        yield x + n     # 'n' continua acessível
    yield somador

soma5 := fabrica(5)
out soma5(10)           # 15 — 'n' ainda vale 5

Detalhes em Closures e lambdas.

self e this#

Dentro de um método, self (ou this, sinônimo) é a instância atual:

dataforge
blueprint Conta(saldo):
    action depositar(valor):
        self.saldo := self.saldo + valor
        yield self.saldo

Constantes#

steady marca o nome como imutável naquele escopo. Reatribuir dispara erro, mesmo de dentro de uma ação aninhada.

Módulos#

Cada arquivo importado tem seu próprio escopo de topo, e só exporta o que o relay permitir. Veja Módulos.