Metatabela é uma tabela normal Prisma, porém ela fica oculta dentro do objeto (que pode ser uma string, uma tabela, userdata etc). Essa metatabela tem campos chamados metamétodos, responsáveis por mudar o comportamento do objeto em uma operação (que pode ser aritmética, concatenação, tamanho, tipo etc); *
Metamétodos são funções dentro de metatabelas, com nomes específicos de acordo com as operações e ações. É possível, por exemplo, definir um metamétodo em Prisma para somar duas tabelas, ou para mudar o nome do seu tipo.
Veja o exemplo abaixo:local mt = {}; //metatabela; mt.__tipo = funcao() //metamétodo acionado com a função tipo(); retorne 'retangulo'; fim mt.__convstring = funcao(t) local s = 'retangulo:{comprimento=' .. t.comprimento .. ', largura=' .. t.largura .. '}'; retorne s; fim local ret = {comprimento=10, largura=20}; defmetatabela(ret, mt); //definindo a tabela mt como metatabela de ret; //só testar: imprima(tipo(ret) ); //--> retangulo imprima(ret); // --> retangulo:{comprimento=10, largura=20}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
local mt = {}; //metatabela; mt.__tipo = funcao() //metamétodo acionado com a função tipo(); retorne 'retangulo'; fim mt.__convstring = funcao(t) local s = 'retangulo:{comprimento=' .. t.comprimento .. ', largura=' .. t.largura .. '}'; retorne s; fim local ret = {comprimento=10, largura=20}; defmetatabela(ret, mt); //definindo a tabela mt como metatabela de ret; //só testar: imprima(tipo(ret) ); //--> retangulo imprima(ret); // --> retangulo:{comprimento=10, largura=20}
local meta = inclua'meta'; local ret = {comprimento=10, largura=20}; meta.__('tipo', ret, funcao() retorne 'retangulo'; fim); meta.__('convstring', ret, funcao(t) local s = 'retangulo:{comprimento=' .. t.comprimento .. ', largura=' .. t.largura .. '}'; retorne s; fim); //agora só testar imprima(tipo(ret)); //--> retangulo imprima(ret);// --> retangulo:{comprimento=10, largura=20}
1 2 3 4 5 6 7 8 9 10 11 12 13
local meta = inclua'meta'; local ret = {comprimento=10, largura=20}; meta.__('tipo', ret, funcao() retorne 'retangulo'; fim); meta.__('convstring', ret, funcao(t) local s = 'retangulo:{comprimento=' .. t.comprimento .. ', largura=' .. t.largura .. '}'; retorne s; fim); //agora só testar imprima(tipo(ret)); //--> retangulo imprima(ret);// --> retangulo:{comprimento=10, largura=20}
Função para copiar uma metatabela de uma tabela para outra tabela.
Funcao para definir uma tabela 'mt' como metatabela da tabela 'tab'.
- funcao meta.def(tab, mt)local meta = inclua'meta'; local mt = { __add = funcao(a,b) a.val = a.val + b; retorne a.val; fim }; //meta tabela com metamétodo + definido local tab = {val = 0;}; tab = meta.def(tab, mt); imprima(tab+10); //--> 10 imprima(tab+1); //---> 11
1 2 3 4 5 6 7 8
local meta = inclua'meta'; local mt = { __add = funcao(a,b) a.val = a.val + b; retorne a.val; fim }; //meta tabela com metamétodo + definido local tab = {val = 0;}; tab = meta.def(tab, mt); imprima(tab+10); //--> 10 imprima(tab+1); //---> 11
Funcao para mesclar uma tabela'mt' como metatabela da tabela 'tab'.
Se houver uma metatabela em tab ela não será apagada, apenas os metamétodos presentes em mt substituirão os já existentes na tabela original, senão serão apenas acrescentados.local tab = {n=0}; local mt = {__add=funcao(a, n) a.n = a.n + n; retorne a.n; fim}; local mt2 = {__sub = funcao(a, n) a.n = a.n - n; retorne a.n; fim}; local mt3 = {__mul = funcao(a,n) a.n = a.n * n; retorne a.n; fim}; local mt4 = {__div = funcao(a,n) a.n = a.n / n; retorne a.n; fim}; tab = meta.def(tab, mt); meta.mescle(tab, mt2); meta.mescle(tab, mt3); meta.mescle(tab, mt4); imprima(tab + 10); imprima(tab - 1); imprima(tab * 3); imprima(tab / 9);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
local tab = {n=0}; local mt = {__add=funcao(a, n) a.n = a.n + n; retorne a.n; fim}; local mt2 = {__sub = funcao(a, n) a.n = a.n - n; retorne a.n; fim}; local mt3 = {__mul = funcao(a,n) a.n = a.n * n; retorne a.n; fim}; local mt4 = {__div = funcao(a,n) a.n = a.n / n; retorne a.n; fim}; tab = meta.def(tab, mt); meta.mescle(tab, mt2); meta.mescle(tab, mt3); meta.mescle(tab, mt4); imprima(tab + 10); imprima(tab - 1); imprima(tab * 3); imprima(tab / 9);
Função para facilitar a definição de metamétodos em Prisma, fazendo a sobrecarga de operadores.
funcao defmetametodo( meta, tab, func)Esta função meta.__() é um açúcar sintático, um atalho para a função meta.defmetametodo() ficando mais curta assim.
veja:meta.defmetametodo() == meta.__()
1
meta.defmetametodo() == meta.__()
local meta = inclua'meta'; local myint = Classe{val = 0}; funcao myint:construtor(val) //funcao construtora: meta.__('+', este, funcao (a,b) local c = {val=0}; meta.cp(c,a); c.val = a.val + b.val; retorne c; fim) meta.__('-', este, funcao (a,b) local c = {val=0}; meta.cp(c,a); c.val = a.val - b.val; retorne c; fim) meta.__('s', este, funcao(a) retorne convstring(a.val); fim) este.val = val; fim local a = myint(1); local b = myint(2); imprima(a + b); imprima(a - b); meta.__('tipo', b, funcao() retorne 'myint'; fim); imprima(tipo(b));
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
local meta = inclua'meta'; local myint = Classe{val = 0}; funcao myint:construtor(val) //funcao construtora: meta.__('+', este, funcao (a,b) local c = {val=0}; meta.cp(c,a); c.val = a.val + b.val; retorne c; fim) meta.__('-', este, funcao (a,b) local c = {val=0}; meta.cp(c,a); c.val = a.val - b.val; retorne c; fim) meta.__('s', este, funcao(a) retorne convstring(a.val); fim) este.val = val; fim local a = myint(1); local b = myint(2); imprima(a + b); imprima(a - b); meta.__('tipo', b, funcao() retorne 'myint'; fim); imprima(tipo(b));
meta é a tabela com os métodos para esta biblioteca prisma.
Obs.: ela é local portanto ao usar o inclua'' deve-se atribuir o valor de retorno: ex.: local meta = inclua'meta';