Fronteira de capacidade
Rodar uma ação com os poderes que ela pode alcançar — e a lista honesta do que isto não é.
O `comptime` já recusava out, adopt, thread e parallel: é uma fronteira de capacidade escrita à mão, para um caso só. E o `--plugin=` roda um .df arbitrário do projeto com todos os poderes — uma regra de lint que pode abrir soquete.
dataforge
adopt Arcane.Capacidade as Cap
// a formula do usuario calcula, e so
action formula():
adopt Arcane.Math as M
yield M.sqrt(16) + len("abc")
assert Cap.executar(formula, []) is 7.0dataforge
adopt Arcane.Capacidade as Cap
action ler_disco():
adopt Arcane.IO as IO
yield IO.exists(".")
// sem permissao, o adopt e recusado pelo NOME da capacidade
monitor:
Cap.executar(ler_disco, [])
assert no
handle Error as e:
assert "arquivos" in e.message
assert "Arcane.IO" in e.message
// com ela, o mesmo codigo passa
assert Cap.executar(ler_disco, ["arquivos"])As capacidades#
| Capacidade | O que libera |
|---|---|
arquivos | Arcane.IO, Archive, Excel, ArquivoSeguro, Lago |
rede | Http, Rede, Web, Email, Malha, Kiln, Vitrine |
processo | OS e Process — o sistema e outros processos |
banco | Database, Forge, e o que persiste |
threads | Concurrent, Async, Laco, Stm |
nativo | Arcane.C — memória sem rede de proteção, a fronteira mais insegura que existe aqui |
python | a ponte, que alcança tudo o que o Python alcança |
ambiente | variáveis de ambiente e argumentos |
Um nome inventado é recusado com a lista: um erro de digitação concederia silenciosamente nada, e a fronteira pareceria mais aberta do que é.
dataforge
adopt Arcane.Capacidade as Cap
// descobrir de que uma acao precisa: rode sem nada e leia os negados
action tenta():
monitor:
adopt Arcane.OS as OS
yield OS.name()
handle Error:
yield "negado"
r := Cap.observar(tenta, [])
assert r["negados"][0]["capacidade"] is "processo"
assert Cap.exige("Arcane.OS") is "processo"
assert Cap.exige("Arcane.Math") is void // inofensivoO que isto NÃO é#
| Limite | Por quê |
|---|---|
| não tira o que foi ENTREGUE | passar o módulo é passar o poder junto. Isso é o modelo, não um defeito: numa linguagem de capacidade, poder é o que se passa, não o que está no ar — e é por isso que bloquear o adopt é a fronteira certa |
| a ponte para o Python é capacidade própria | ela alcança tudo o que o Python alcança; deixá-la junto de outra faria o resto da lista virar enfeite |
| a lista de módulos é escrita à mão | um erro nela é um furo. Contra código que você escreveu e revisou — plugin, fórmula de usuário, comptime — isto vale |
| contra código malicioso, não use isto | use processo separado, contêiner, ou o sistema operacional |
dataforge
adopt Arcane.Capacidade as Cap
adopt Arcane.IO as IO
// IO foi ENTREGUE por quem chamou: o cofre nao o retira
action com_o_que_recebeu(ferramenta):
yield ferramenta.exists(".")
assert Cap.executar(com_o_que_recebeu, [], [IO])E a fronteira se desfaz sempre — inclusive quando o corpo falha. Uma fronteira que não se desfizesse travaria o programa inteiro, e é o finally que garante isso.