Ir para conteúdo

Featured Replies

Postado
  • Este é um post popular.

lua.gif

Metamétodos

Bem, talvez não seja útil a todos (ou apenas não vejam a utilidade disso no começo), mas como já tinha feito um tutorial de POO em lua decidi me aprofundar mais e entrar em um assunto que não tem muita gente que sabe, ter um conhecimento intermediário sobre POO ajuda a aprender isso (saber usar a função setmetatable também), mas apenas um complementa o outro como veremos logo a seguir.

Porque aprender ?

Se eu dissesse que isso é necessário para programar eu estaria mentindo, mas pode acabar sendo útil, quem sabe para complementar o conhecimento de POO, mas é como eu já disse no outro tópico, aprende quem quiser.

Metamétodos

Metamétodos são (obviamente) associados a metatabelas, esses "métodos" são basicamente os eventos que ocorrem quando Lua (a linguagem) executa algumas operações: subtração, divisão, comparações, concatenações etc. É o que chamam em algumas linguagens de sobrecarregar operador (basicamente é a mesma coisa), cada evento tem um nome, adição é "add", exponenciação é "pow", concatenação é "concat", mais a frente eu cito todos e suas funções.

Um exemplo, que caso você já saiba POO já deve ter visto é esse:


Classe = {}

function Classe:new()

return setmetatable({}, { __index = self })

end

Esse __index, já se perguntou o que ele faz ali ?
Ele é um metamétodo também, ele simplesmente mostra que é para procurar indices(seja métodos, atributos, oque for) na tabela
self
(ou seja, nela mesma), e é por isso que quando você cria uma classe você consegue usar os métodos (não confunda com metamétodos), atributos dela.
O 2º parametro da função setmetatable é uma tabela de metamétodos. Exemplo:

metatable = {}

function String(s)

return setmetatable({ value = s or '' }, metatable)

end

function metatable.__add(a, b)

return String(a.value .. b.value)

end

Veja que eu adicionei o metamétodo __add que se refere ao operador matemático de adição, com esse método você pode fazer isso (a seguir), tente executar e veja o resultado:

s = String('Hello')

print("Valor de 's' é: " .. s.value)

m = s + String(' World')

print("Soma de duas Strings: " .. m.value)

Agora apague tudo e tente dessa maneira sem o metamétodo:

metatable = {}

function String(s)

return setmetatable({ value = s or '' }, metatable)

end

s = String('Hello')

print("Valor de 's' é: " .. s.value)

m = s + String(' World')

print("Soma de duas Strings: " .. m.value)

Vai resultar em um erro. A partir disso você pode criar muitas coisas ! o exemplo acima (o que funciona) também pode ser escrito dessa maneira:

function String(s)

return setmetatable({

   value = s or ''

  }, {

   __add = function(a,b)

	 return String(a.value .. b.value)

    end

  })

end

s = String('Hello')

print("Valor de 's' é: " .. s.value)

m = s + String(' World')

print("Soma de duas Strings: " .. m.value)

Eu pulei linha ali no setmetatable apenas pra ficar mais organizado e de fácil entendimento, não que seja necessário. Basicamente, metamétodos são os métodos que fazem operações em metatabelas lua, agora veja o mesmo exemplo acima mas sem o metamétodo:

String = {}

function String:new(s)

return setmetatable({ value = s or '' }, { __index = self })

end

function String:add(s)

self.value = self.value .. s.value

return self.value

end

s = String:new('Hello')

print("Valor de 's' é: " .. s.value)

m = s:add(String:new(' World'))

print("Soma de duas Strings: " .. m)

O uso ficaria um pouco mais complicado e não daria a liberdade de você fazer isso (em negrito):

s = String('Hello')

print("Valor de 's' é: " .. s.value)

m = s + String(' World') + String(' and ') + String('Universe')

print("Soma de quatro Strings: " .. m.value)

Soma de quatro objetos String ao mesmo tempo (em negrito) --- A tabela com os metamétodos, toma-se class1 como um objeto de uma classe qualquer e class2 como um outro objeto da mesma classe de class1, ou numero, ou string, ou tabela, ou userdata, ou thread ou qualquer outro tipo de dado lua: matamethods.pngAs cores não estão ali a toa, Função/Nome = o nome e função do metamétodo; Uso = Como se deve usar; Parâmetros = Quais parâmetros o metamétodo possui; Exemplo = Exemplo de quando o metamétodo irá acontecer. Você pode encontrar todas os metamétodos junto a um exemplo nesse link http://www.lua.org/manual/5.1/pt/manual.html#2.8, mas vou citar alguns exemplos:

TV = {}

function TV:new(marca, polegadas)

return setmetatable({

   marca = marca or '',

   polegadas = polegadas or ''

  }, {

   __add = function (tv, n)  -- Metamétodo de adição

	 if (type(n) == 'number') then

	  return TV:new(tv.marca, tv.polegadas + n)

	 else

	  return TV:new(tv.marca, tv.polegadas + n.polegadas)

	 end

    end,

   __mul = function (tv, n)  -- Metamétodo de multiplicação

	 return TV:new(tv.marca, tv.polegadas * n)

    end,

   __eq = function (tv1, tv2)  -- Metamétodo de igualdade

	 if (tv1.marca == tv2.marca and tv1.polegadas == tv2.polegadas) then

	  return true

	 end

	 return false

    end

  })

end

tv1 = TV:new("LG", 21)

tv2 = TV:new("Philips", 19)

tv1 = tv1 + 4 -- Adiciono 3 a tv1

print(tv1.polegadas) -- tv1 fica com 25 polegadas

tv2 = tv1 + tv2 -- Adiciono as polegadas da tv1 na tv2

print(tv2.polegadas)

tv1 = tv1 * 2 -- Multiplico as polegadas da tv1 por 2

print(tv1.polegadas)

if (tv1 == tv2) then

print('tv1 é igual a tv2 !')

else

print('tv1 não é igual a tv2')

end

tv1 = tv2 -- Agora tv1 é igual a tv2

if (tv1 == tv2) then

print('tv1 é igual a tv2 !')

else

print('tv1 não é igual a tv2')

end

O exemplo é ruim eu sei, mas to sem criatividade D: Explicação detalhada: Agora uma explicação passo a passo de um metamétodo, vou aproveitar o da TV:

__add = function (tv, n)  -- Metamétodo de adição

  if (type(n) == 'number') then

   return TV:new(tv.marca, tv.polegadas + n)

  else

   return TV:new(tv.marca, tv.polegadas + n.polegadas)

  end

end

e uma soma qualquer:

tv1 = tv1 + 4

O
metamétodo
tem 2 parametros,
tv
e
n
(você pode escolher o nome que quiser),
tv
e
n
referem-se a
tv1
e
4
na soma respectivamente, ou seja, o
__add
(linha 1) vai verificar se o
n
é um numero
(linha 2)
e caso for ele vai retornar outro objeto da classe TV , com a mesma marca da
tv
mas com as polegadas somadas ao numero
n
(linha 3)
, mas caso não for um numero
(linha 4)
vai manter a marca da
tv
e somar as polegadas da
tv
e da TV
n
(linha 5)
.

Novamente, as cores (e o negrito) não estão ali a toa.

Bem é um pouco complicadinho, mas todos (a maioria) dos metamétodos seguem esse mesmo padrão de 2 parametros, ai facilita um pouco

---

Espero que alguém tenha compreendido, tentei ser o mais claro possível, caso contrario eu refaço as partes que estão complicadas,

Qualquer dúvida, sugestão, critica, só postar !

Quem
quiser
pode me enviar sugestões de temas para tutoriais sobre scripting e programação, algum assunto que não entendeu, que não viu no forum ou que faltou algo mais detalhado.

Creditos

Lwkass

Contato;

6yonKDJ.png god.marinii

TaxNfhb.png

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.7k

Informação Importante

Confirmação de Termo