Arcane.Meta
Ler os decoradores em tempo de execução.
Arcane.Meta lê os metadados que os decoradores deixaram. É a metade que torna um decorador útil: @Rota("/itens") grava o caminho, e Meta.ler o devolve.
adopt Arcane.Meta as Meta
@Rota("GET", "/itens")
action listar():
yield itens
Meta.tem(listar, "Rota") // yes
Meta.arg(listar, "Rota", 0) // GETLeitura#
| Função | Devolve |
|---|---|
Meta.tem(alvo, nome) | o alvo foi decorado com @nome? |
Meta.nomes(alvo) | os nomes dos decoradores, na ordem em que aparecem |
Meta.todos(alvo) | todos os metadados: [{nome, args, kwargs}] |
Meta.ler(alvo, nome) | o primeiro @nome, ou void |
Meta.todos_de(alvo, nome) | todas as ocorrências de @nome (decorador repetível) |
Meta.arg(alvo, nome, i, padrao) | um argumento posicional, com padrão |
Meta.opcao(alvo, nome, chave, padrao) | um argumento nomeado, com padrão |
Todas devolvem o padrão (ou void) quando o decorador não existe — nunca levantam. Perguntar por um decorador ausente é o caso normal, não erro.
Varredura#
// os métodos de um controlador anotados com @Rota
cycle r in Meta.metodos_com(UsuariosController, "Rota"):
out r["nome"], r["meta"]["args"]
// de uma lista de blueprints, os @Injetavel
servicos := Meta.filtrar([Repo, Cache, Config], "Injetavel")| Função | Devolve |
|---|---|
Meta.metodos_com(blueprint, nome) | [{nome, metodo, meta}] — os métodos anotados |
Meta.filtrar(valores, nome) | de uma lista ou vault, os que têm @nome |
Meta.descrever(alvo) | tipo, nome, decoradores, métodos e campos |
metodos_com é o que um roteador usa para descobrir rotas a partir de uma classe; filtrar é o que um contêiner usa para achar o que registrar.
Escrita#
// anotar algo que já existe, sem a sintaxe de decorador
Meta.marcar(minha_acao, "Cache", 60)
out Meta.arg(minha_acao, "Cache", 0) // 60
Meta.limpar(minha_acao) // remove tudo — útil em testemarcar serve para anotar um valor vindo de outro módulo, e para escrever decoradores que anotam além do que receberam.
O que sobrevive ao embrulho#
@logar // embrulha
@Rota("/x") // só anota
action f(n):
yield n
Meta.tem(f, "Rota") // yes — o embrulho herdou a anotaçãoQuando um decorador embrulha o alvo, o embrulho herda os metadados de quem embrulhou. Sem isso, @logar @Rota(...) perderia a anotação assim que o primeiro decorador devolvesse um embrulho — e a ordem dos decoradores viraria uma armadilha.
Onde ver funcionando#
| Onde | O quê |
|---|---|
| Decoradores | um roteador e um contêiner de injeção completos |
| Playground | o exemplo "Decoradores", rodando no navegador |
tests/test_decoradores.py | 20 testes |