Tabela (table)
Em aardio, exceto pelos tipos de dados básicos, todos os objetos compostos são tabelas (por exemplo, classes e namespaces). Uma tabela pode armazenar qualquer objeto em aardio, incluindo outra tabela. Em outras linguagens, estruturas como dicionários, listas, arrays, conjuntos e mapas são implementadas usando tabelas em aardio.
Criando um Dicionário
import console;
var dicionario = {
chave1 = 123;
chave2 = "texto";
[456] = "chaves numéricas devem estar entre colchetes.";
["chave com espaço"] = "chaves com caracteres especiais usam colchetes.";
subObjeto = {
teste = "tabelas podem conter outras tabelas"
}
}
// Sintaxe alternativa similar a JSON
var dicionario = {
"chave1": 123,
"chave2": "texto",
"chave com espaço": "valor"
}
dicionario.chave1 = 789;
dicionario["chave2"] = "novo valor";
// Atribuir null remove a chave
dicionario.subObjeto = null;
// Iterando sobre as chaves e valores
for chave, valor in dicionario {
console.dump(chave, valor);
}
console.pause();
Criando um Array
var arranjo = {10; 20; 30; "elemento"};
// Iterando usando índice
for i = 1, #arranjo, 1 {
console.dump(i, arranjo[i]);
}
Misturando Arrays e Dicionários
var misto = {
100;
200;
nome = "exemplo";
}
// O operador # retorna apenas o tamanho da parte array
console.log(#misto) // Saída: 2
// Usando table.count para obter o total de elementos
console.log(table.count(misto)) // Saída: 3
Classes
A palavra-chave class define uma classe, que pode criar objetos tabela com estrutura idêntica dinamicamente.
Definindo uma Classe
// Definição da classe
class MinhaClasse {
// Construtor opcional usando ctor
ctor(parametros) {
// Código do construtor
}
atributo = "valor padrão";
metodo = function(parametro) {
// Implementação
}
}
A sintaxe é semelhante à definição de uma tabela, mas classes permitem a instanciação de objetos.
var instancia = MinhaClasse();
io.print(instancia.atributo);
instancia.metodo();
Espaço de Nomes da Classe
Ao definir uma classe, um namespace com o mesmo nome é criado por padrão. Variáveis atribuídas a esse namespace são membros estáticos públicos da classe.
io.open(); // Abre a janela do console
// Definição da classe
class Exemplo {
valor = 100;
}
// Membros estáticos no namespace
Exemplo.Estatico = "membro estático";
var obj = Exemplo();
io.print("obj.valor", obj.valor) // Exibe 100
io.print("Exemplo.Estatico", Exemplo.Estatico) // Exibe "membro estático"
Em código de bibliotecas, é comum definir um namespace junto com a classe para funções ou variáveis estáticas.
class Base {
x = 1;
y = 2;
z = 3;
}
namespace Base {
compartilhado = 123; // Membro estático
}
Objeto this
Refere-se ao objeto atual, semelhante ao self em Python.
Objeto owner
Este conceito é sutil, mas uma vez compreendido, torna-se simples. O exemplo a seguir ilustra:
class Demo {
funcao = function() {
..io.print("owner", owner)
..io.print("this", this)
..io.print("owner == this", owner == this)
}
}
var instanciaDemo = Demo();
io.open();
instanciaDemo.funcao(); // owner e this apontam para o mesmo objeto
var funcRef = instanciaDemo.funcao;
funcRef(); // owner é nulo, mas this permanece inalterado
Quando um objeto tabela chuma um método membro, um objeto owner é passado por padrão. Em métodos de objetos criados por classes, owner e this referem-se ao mesmo objeto. A diferença é que this é fixo para o objeto criado pela classe, enquanto owner muda com base no prefixo tabela na chamada da função.
Construtor
A função ctor atua como o construtor da classe, equivalente ao __init__ em Python, mas sem o parâmetro self.
class Pessoa {
ctor(nome, idade) {
this.nome = nome;
this.idade = idade;
}
profissao = "desconhecida";
}
var individuo = Pessoa("Ana", 30);
import console;
console.log(individuo.nome, individuo.idade);
console.pause();
Herança de Classes
Herança Direta
// Classe base
class Animal {
nome = "generico";
som = "silencioso";
}
namespace Animal {
tipo = "ser vivo";
}
class Cachorro {
ctor(...) {
this = ..Animal(...); // Chama o construtor da classe base
}
som = "latido"; // Sobrescreve membro da classe base
habilidade = "buscar";
}
import console;
var rex = Cachorro();
for chave, valor in rex {
console.log(chave, valor);
}
console.pause();
Herança Indireta
class Veiculo {
rodas = 4;
marca = "indefinida";
}
class Carro {
marca = "sedan";
cor = "prata";
@_prototype;
}
// Define a herança via tabela protótipo
Carro._prototype = { _get = ..Veiculo() };
import console;
var meuCarro = Carro();
// Itera apenas sobre membros diretos do objeto
for chave, valor in meuCarro {
console.log(chave, valor);
}
// Acesso a membros herdados via meta-métodos
console.log("Membro herdado", meuCarro.rodas);
console.pause();
Membros Privados
Variáveis definidas com var dentro da classe têm escopo limitado, sendo inacessíveis externamente.
Membros Somente Leitura
Variáveis iniciadas com sublinhado (por exemplo, _id) são somente leitura. Alternativamente, meta-tabelas podem ser usadas para definir propriedades somente leitura.