×

Langue

Fermer
Atelier 801
  • Forums
  • Dev Tracker
  • Connexion
    • English Français
      Português do Brasil Español
      Türkçe Polski
      Magyar Română
      العربية Skandinavisk
      Nederlands Deutsch
      Bahasa Indonesia Русский
      中文 Filipino
      Lietuvių kalba 日本語
      Suomi עברית
      Italiano Česky
      Hrvatski Slovensky
      Български Latviešu
      Estonian
  • Langue
  • Forums
  • /
  • Transformice
  • /
  • Archives
  • /
  • Seção Editor de Mapas e Modules
  • /
  • [Tutorial] Metatables e Metamétodos
[Tutorial] Metatables e Metamétodos
Yuir
« Héliaste »
1471480860000
    • Yuir#2211
    • Profil
    • Derniers messages
    • Tribu
#1
  0

Metatables & Metamethods


 Em lua, há diferentes tipos de meta métodos. Eles realizam funções dentro de uma tabela, e essa tabela que contém um metamethod é chamada de metatable.

 "Essa meta tabela é uma tabela Lua comum que define o comportamento do valor original sob certas operações especiais. Você pode mudar vários aspectos do comportamento de operações sobre um valor especificando campos específicos em sua meta tabela.", (manual lua)

 Cada meta método é precedido por dois underscores ( _ ) e o nome do event, como em __event.

Sumário de funções:
» getmetatable(tabela)
    - Caso a tabela de argumento seja uma metatable, esta função retornará todos os metamethods dessa tabela, exceto no instante que existir um meta método chamado __metatable, que apenas ela será retornada.
» setmetatable(tabela, metatabela)
    - Estabelece o(s) (novo(s)) meta método(s) da/na tabela inserida, mas caso o argumento metatabela seja nil, o(s) meta método(s) da tabela inserida será(ão) removido(s), caso exista o meta método __metatable na tabela original inserida (caso não seja o primeiro meta método ou a tabela já seja metatable), um erro será retornado.
Sumário de metamethods:
__index(list,index)
    - É executado quando uma tabela é chamada. Seus argumentos são list (tabela) e index (nome da variável)
    Exemplo
    garbage = setmetatable({},{
      __index = function(list,index)
        return "Not Nil! Biiiirl! The monster!!!!!"
      end
    }
    )


    garbage.Tig = 1
    garbage.Noob = 2

    print(garbage["Tig Noob"])
    print(garbage.Tig)
    print(garbage["Noob"])
     
__newindex(list,index,value)
    - É executado quando uma variável dentro da tabela é criada. Seus argumentos são list (tabela), index (nome da variável) e value (valor da nova variável)
    Exemplo
    calc = setmetatable({},{
      __newindex = function(list,index,value)
        if type(value[1]) == "number" and type(value[2]) == "number" then
          local math = {
            [1] = value[1],
            [2] = value[2],
            add = value[1] + value[2],
            sub = value[1] - value[2],
            mul = value[1] * value[2],
            div = value[1] / value[2],
          }
          rawset(list,index,math)
        else
          rawset(list,index,value)
        end
      end
    })


    calc.cake = {10,20}

    print(calc.cake[1])
    print(calc.cake[2])
    print(calc.cake.add)
    print(calc.cake.sub)
    print(calc.cake.mul)
    print(calc.cake.div)
     
__call(list,arg)
    - É executado quando uma tabela é chamada como função. Seus argumentos são list (tabela) e arg (argumento(s) passados pela suposta "função") (também pode ser representado por ...)
    Exemplo
    local call = {
      __call = function(list,arg)
        print(("[%s [%dy]] %s!"):format(arg.name,arg.age,arg.quote))
      end
    }


    humanProfile = setmetatable({},{
      __newindex = function(list,index,value)
        rawset(list,index,setmetatable(value,call))
      end
    }
    )


    humanProfile[1] = {
      name = "Homer Simpson",
      age = 40,
      quote = "I am sorry, God, but I do not trust you!",
    }


    humanProfile[1](humanProfile[1])
     
__concat(...)
    - É executado quando ocorre uma concatenação de valores diferentes (ex: a tabela com uma string). Seu argumento é ..., onde é passado todos os valores que foram concatenados. (Também representado como o1, o2)
    Exemplo
    local concat = {
      __concat = function(...)
        local values = {}
        local args = {...}
        for i = 1,#args do
          if type(args[i]) == "table" then
            for k,v in next,args[i] do
              values[#values + 1] = v
            end
          else
            values[#values + 1] = args[i]
          end
        end
        return table.concat(values,", ")
      end
    }

    list = setmetatable({},{
      concat,
      __newindex = function(list,index,value)
        if type(value) == "table" then
          rawset(list,index,setmetatable(value,concat))
        else
          rawset(list,index,value)
        end
      end
    }
    )


    list.food = "pasta"
    list.soda = {"coke","grape"}
    list.trolls = {"Tigrounette","Pikashu"}

    print(list.soda .. list.trolls .. list.food)
     
__add(n1,n2)
    - É executado quando ocorre uma adição entre valores não numéricos (ou um numérico e outro não). Seus argumentos são n1 e n2, os dois "números" ou "valores" que estão sendo somados.
    Exemplo
    sMath = setmetatable({},{
      __add = function(n1,n2)
        n1,n2 = (type(n1) == "table" and #n1 or n1),(type(n2) == "table" and #n2 or n2)
        return n1 + n2
      end
    }
    )


    sMath[1] = 0
    sMath[2] = 0
    sMath[3] = 0
    sMath[4] = 0

    print(sMath + sMath + 2)
     
__sub(n1,n2)
    - É executado quando ocorre uma subtração entre valores não numéricos (ou um numérico e outro não). Seus argumentos são n1 e n2, os dois "números" ou "valores" que estão sendo subtraídos.
    Exemplo
    sMath = setmetatable({},{
      __sub = function(n1,n2)
        n1,n2 = (type(n1) == "table" and #n1 or n1),(type(n2) == "table" and #n2 or n2)
        return n1 - n2
      end
    }
    )


    sMath[1] = 0
    sMath[2] = 0
    sMath[3] = 0
    sMath[4] = 0

    print(sMath - 3)
     
__mul(n1,n2)
    - É executado quando ocorre uma multiplicação entre valores não numéricos (ou um numérico e outro não). Seus argumentos são n1 e n2, os dois "números" ou "valores" que estão sendo multiplicados.
    Exemplo
    sMath = setmetatable({},{
      __mul = function(n1,n2)
        n1,n2 = (type(n1) == "table" and #n1 or n1),(type(n2) == "table" and #n2 or n2)
        return n1 * n2
      end
    }
    )


    sMath[1] = 0
    sMath[2] = 0
    sMath[3] = 0
    sMath[4] = 0

    print(sMath * 4)
     
__div(n1,n2)
    - É executado quando ocorre uma divisão entre valores não numéricos (ou um numérico e outro não). Seus argumentos são n1 e n2, os dois "números" ou "valores" que estão sendo divididos.
    Exemplo
    sMath = setmetatable({},{
      __div = function(n1,n2)
        n1,n2 = (type(n1) == "table" and #n1 or n1),(type(n2) == "table" and #n2 or n2)
        return n1 / n2
      end
    }
    )


    sMath[1] = 0
    sMath[2] = 0
    sMath[3] = 0
    sMath[4] = 0

    print(sMath / 4)
     
__pow(n1,n2)
    - É executado quando ocorre uma exponenciação (1²) entre valores não numéricos (ou um numérico e outro não). Seus argumentos são n1 e n2, os dois "números" ou "valores" que estão sendo exponenciados.
    Exemplo
    sMath = setmetatable({},{
      __pow = function(n1,n2)
        n1,n2 = (type(n1) == "table" and #n1 or n1),(type(n2) == "table" and #n2 or n2)
        return n1 ^ n2
      end
    }
    )


    sMath[1] = 0
    sMath[2] = 0
    sMath[3] = 0
    sMath[4] = 0

    print(sMath ^ 2)
     
__mod(n1,n2)
    - É executado quando ocorre um mod (1%2 (Coletar o resto da divisão entre 2 números)) entre valores não numéricos (ou um numérico e outro não). Seus argumentos são n1 e n2, os dois "números" ou "valores" que estão sendo "modularizados".
    Exemplo
    sMath = setmetatable({},{
      __mod = function(n1,n2)
        n1,n2 = (type(n1) == "table" and #n1 or n1),(type(n2) == "table" and #n2 or n2)
        return n1 % n2
      end
    }
    )


    sMath[1] = 0
    sMath[2] = 0
    sMath[3] = 0
    sMath[4] = 0

    print(sMath % 3)
     
__unm(n1)
    - É executado quando ocorre um valor não numérico é chamado com unário (no caso, seria o mesmo que chamar "-var" para que o número de var seja negativo). Seu argumento é o n1, o "número" ou "valor" que está sendo transformado num número negativo.
    Exemplo
    sMath = setmetatable({},{
      __unm = function(n1)
        n1 = (type(n1) == "table" and #n1 or n1)
        return -n1
      end
    }
    )


    sMath[1] = 0
    sMath[2] = 0
    sMath[3] = 0
    sMath[4] = 0

    print(-sMath)
     
__metatable()
    - Bloqueia a função getmetatable de coletar o meta método real da tabela inserida, e, ao invés dela, acaba mandando o metamethod __metatable como forma de proteção.
    Exemplo
    str = setmetatable({},{
      __metatable = "Nothing here, noob!",
      __newindex = function(list,key,value)
        print(key .. " Biirl!")
        rawset(list,key,value)
      end
    }
    )


    print(getmetatable(str))
    print(getmetatable(str).__newindex)

    str.test = '?'

    tbl = setmetatable({},{
      __newindex = function(list,key,value)
        print(key .. " Huuuu!")
        rawset(list,key,value)
      end
    }
    )


    print(getmetatable(tbl))
    print(getmetatable(tbl).__newindex)

    tbl.test = '?'
     
Tremines
« Citoyen »
1471480980000
    • Tremines#0000
    • Profil
    • Derniers messages
    • Tribu
#2
  0
Inteligente hein!
Lerei com atenção.
Squalleze
« Citoyen »
1471550640000
    • Squalleze#0000
    • Profil
    • Derniers messages
    • Tribu
#3
  0
Muito bom o tutorial, e adorei as cores, mas também existe o metamethod __len, que ta bugado nessa versão do LuaJ e os do Lua 5.3 também são bem interessantes
Yuir
« Héliaste »
1471562700000
    • Yuir#2211
    • Profil
    • Derniers messages
    • Tribu
#4
  0
Squalleze a dit :
Muito bom o tutorial, e adorei as cores, mas também existe o metamethod __len, que ta bugado nessa versão do LuaJ e os do Lua 5.3 também são bem interessantes

Sim, há o metamethod __len, mas, como você disse, ele está bugado, tornando-o inviável no tópico. Sobre os 5.3, não serão colocados uma vez que o Lua do jogo é 5.2
Hydroper
« Citoyen »
1476014340000
    • Hydroper#0528
    • Profil
    • Derniers messages
    • Tribu
#5
  0
Removido (o lua do TFM não suporta debug)

Dernière modification le 1479336120000
  • Forums
  • /
  • Transformice
  • /
  • Archives
  • /
  • Seção Editor de Mapas e Modules
  • /
  • [Tutorial] Metatables e Metamétodos
© Atelier801 2018

Equipe Conditions Générales d'Utilisation Politique de Confidentialité Contact

Version 1.27