Lua 5.1 para Programadores
Renato Maia
maia@inf.puc-rio.br
Pontifícia Universidade Católica do Rio de JaneiroDepartamento de Informática
O Que é Lua?
I
Mais uma linguagem dinâmica.
I
Interpretação de código
code = l o a d s t r i n g (" p r i n t ( ’ H e l l o , World ! ’ ) ") code ( ) −−> H e l l o , World ! ITipagem dinâmica
a = 1 p r i n t ( a+a ) −−> 2 a = " a " p r i n t ( a+a ) −−> a t t e m p t t o perform a r i t h m e t i c on g l o b a l ’ a ’ ( a s t r i n g v a l u e )I
Coleta automática de lixo
f i l e = a s s e r t ( i o . open (" f i l e . t x t ", "w") ) f i l e : w r i t e ( a ) f i l e : c l o s e ( ) f i l e = n i l −− conteudo de ‘ f i l e ’ v i r a l i x o a s e r c o l e t a d o I
Reflexão computacional
f u n c t i o n s t r i n g : t r i m ( ) r e t u r n s e l f : match ("^%s ∗(. −)% s∗$ ") end username = " admin " p r i n t ( username : t r i m ( ) ) −−> adminO Que é Lua?
I
Linguagem de extensão estensível.
I
Ênfase em comunicação inter-linguagens.
I
Enfatiza desenvolvimento em múltiplas linguagens.
I
Uma biblioteca ANSI C:
# include < l u a . h> # include < l u a l i b . h> # include < l a u x l i b . h>
i n t main (i n t argc , char∗ argv [ ] ) { l u a _ S t a t e ∗L = lua_open ( ) ; l u a L _ o p e n l i b s ( L ) ; l u a L _ d o s t r i n g ( L , " p r i n t ( ’ H e l l o , World ! ’ ) ") ; l u a _ c l o s e ( L ) ; r e t u r n 0 ; }
I
Única linguagem fora do eixo EUA/Europa/Japão a ser
adotada mundialmente (Ruby é a única do Japão).
Onde Lua é Usada?
“It is easy to see why Lua is rapidly becoming the de facto standard for game scripting”.
Artificial Intelligence for Games Morgan Kaufmann 2006
“It’s quite possible that game developers will look back at the 2000s as the decade of Lua”.
Game Programming Charles River Media 2005
Onde Lua é Usada?
I
Adobe Photoshop Lightroom
“Over 40% of Adobe Lightroom is written in Lua.” “So what we do with Lua is essentially all of the
application logic from running the UI to managing what we actually do in the database.”
Mark Hamburg Fundador do projeto Adobe Photoshop Lightroom
Onde Lua é Usada?
I
Firmware de impressoras (Olivetty)
I
Analisador de protocolos (Wireshark)
I
Monitoramento remoto (Omnitronix)
I
Pós-produção de filmes (Digital Fusion, eyeon)
Por Que o Sucesso de Lua?
Livre
A licença de Lua é muito liberal (MIT license).
Portável
Escrita em ANSI C ∩ ANSI C++, sem ifdef’s.
Embarcável
Se integra facilmente com outras linguagens.
Pequena
Fontes em torno de 17 mil linhas de código C.
Interpretador+bibliotecas == 153KB (Linux).
Rápida
“Lua code tends to be executed much faster than
other interpreted languages, so fast that ‘as fast as
Lua’ has become a proverbial expression.”
www.h3rald.com
Poderosa, mas simples
“Lua gives you the power; you build
the mechanisms.”
Programming in Lua
Roberto Ierusalimschy, 2003.
Como é Lua?
Tipos de Dados
nil
function
boolean
table
number
thread
string
userdata
Operadores
Aritméticos
+ - * / ^
Relacionais
== ~= < > <= >=
Lógicos
not and or
Concaten.
..
Comprim.
#
Estruturas de Controle
l o c a l e , b , c = 0 , 0 , 0 l o c a l l n = i o . read ( ) while l n ~= n i l do i f l n == " " then e = e + 1e l s e i f l n : match ("^%s&") then b = b + 1 else c = c + 1 end repeat p r i n t ( l n : sub ( 1 , 8 0 ) ) l n = l n : sub ( 8 1 ) u n t i l l n == " " l n = i o . read ( ) end l o c a l t = e+b+c f o r i =1 , 80 do i o . w r i t e ( ( i /80 < c / t ) and " . " or " ") end
Strings
I
São imutáveis.
v e r s i o n = " Lua ". ." ". ." 5 . 1 "
i n v e r t ( v e r s i o n )
p r i n t ( v e r s i o n ) −−> Lua 5 . 1
I
Cada valor string é único.
i f v e r s i o n == " Lua 5 . 1 " then p r i n t (" i g u a i s ") end −−> i g u a i s
I
Porém há um custo em criar novas strings, mesmo uma
substring. Em particular, o custo de concatenação é “alto”.
−− ruim l o c a l t e x t = " " f o r l i n e i n i o . l i n e s ( ) do t e x t = t e x t . . l i n e . ." \ n " end −− melhor l o c a l t e x t = i o . read (" ∗a ")
Funções
I
São valores de primeira-classe e anônimas.
p r i n t ( s t r i n g . gsub (" Lua $MAJOR . $MINOR", " $(%u + ) ", f u n c t i o n( name ) i f name == "MAJOR" then r e t u r n 5 end
i f name == "MINOR" then r e t u r n 1 end end) ) −−> Lua 5 . 1 2
I
Não define os parâmetros que deve receber.
twoArgs = f u n c t i o n( a , b ) p r i n t ( a , b ) end
twoArgs ( 1 , 2 , 3 ) −−> 1 2
twoArgs ( 1 ) −−> 1 n i l
I
Pode retornar um número arbitrário de parâmetros.
(1)f u n c t i o n getNums ( n ) i f n == 1 then r e t u r n 1 end i f n == 2 then r e t u r n 1 , 2 end i f n == 3 then r e t u r n 1 , 2 , 3 end end l o c a l a , b = getNums ( 3 ) p r i n t ( a , b ) −−> 1 2 l o c a l a , b = getNums ( 1 ) p r i n t ( a , b ) −−> 1 n i l p r i n t ( getNums ( 3 ) ) −−> 1 2 3
Manipulando Argumentos Variados
IDando diferentes nomes aos argumentos.
f u n c t i o n process ( message , . . . ) i f message == " Request " then
l o c a l o b j e c t , o p e r a t i o n , args = . . . r e t u r n d i s p a t c h ( o b j e c t , o p e r a t i o n , args ) e l s e i f message == " Reply " then
l o c a l success , r e s u l t = . . . i f success then r e t u r n r e s u l t end e r r o r ( r e s u l t )
end end
I
A função select.
f u n c t i o n maximum ( . . . ) l o c a l max = −math . huge f o r i =1 , s e l e c t (" # ", . . . ) do
l o c a l v a l u e = s e l e c t ( i , . . . ) max = v a l u e > max and v a l u e or max end
r e t u r n max end
p r i n t ( maximum ( 1 , 2 , 3 ) ) −−> 3
Funções
I
Podem ser recursivas e realizam chamadas finais próprias
(proper tail call).
f u n c t i o n pickOS ( )
i o . w r i t e (" P i c k an OS: MacOS, Linux , Windows \ n > ") l o c a l c h o i c e = i o . read ( )
i f c h o i c e == "MacOS" then r e t u r n pickMacOS ( ) end i f c h o i c e == " L i n u x " then r e t u r n p i c k L i n u x ( ) end i f c h o i c e == " Windows " then r e t u r n pickWindows ( ) end r e t u r n pickOS ( )
end
f u n c t i o n pickMacOS ( )
i o . w r i t e (" P i c k an MacOS v e r s i o n : 1−−10 o r t y p e ’ Back ’ \ n > ") l o c a l c h o i c e = i o . read ( )
i f c h o i c e == " Back " then r e t u r n pickOS ( ) end l o c a l v e r s i o n = tonumber ( i o . read ( ) )
i f v e r s i o n and v e r s i o n > 0 and v e r s i o n <= 10 then r e t u r n setOS ("MacOS", v e r s i o n )
end
r e t u r n pickMacOS ( ) end
for
Genérico
I
Pode-se usar uma função para iterar num conjunto de
elementos.
l o c a l f u n c t i o n i t e r a t o r ( s t r i n g , pos ) pos = pos + 1
i f pos <= # s t r i n g then
r e t u r n pos , s t r i n g : sub ( pos , pos ) end end f u n c t i o n a l l c h a r s ( s t r i n g ) r e t u r n i t e r a t o r , s t r i n g , 0 end f o r pos , char i n a l l c h a r s ( v e r s i o n ) do −−> 1 L p r i n t ( pos , char ) −−> 2 u end −−> 3 a −−> 4 −−> 5 5 −−> 6 . −−> 7 1
Fechos de Função
I
Funções são na realidade fechos que capturam variáveis
do escopo em que são criadas
f u n c t i o n compose ( f , g ) r e t u r n f u n c t i o n( . . . ) r e t u r n f ( g ( . . . ) ) end end f u n c t i o n normal ( x , y , z ) l o c a l l e n = ( x ^2+ y ^2+ z ^ 2 ) ^ . 5 r e t u r n x / l e n , y / l e n , z / l e n end l o c a l f = compose ( maximum , normal ) p r i n t ( f ( 1 , 2 , 3 ) ) −−> 0 . 8 0 1 7 . . . f u n c t i o n c o u n t e r ( ) l o c a l c u r r e n t = 0 r e t u r n f u n c t i o n( ) c u r r e n t = c u r r e n t + 1 r e t u r n c u r r e n t end, f u n c t i o n( ) c u r r e n t = c u r r e n t − 1 r e t u r n c u r r e n t end end l o c a l i n c , dec = c o u n t e r ( ) p r i n t ( i n c ( ) ) −−> 1 p r i n t ( i n c ( ) ) −−> 2 p r i n t ( i n c ( ) ) −−> 3 p r i n t ( dec ( ) ) −−> 2 p r i n t ( dec ( ) ) −−> 1 p r i n t ( dec ( ) ) −−> 0
Interpretação
I
A função loadstring permite criar uma função cujo
corpo é o código Lua dado pela string passada por
parâmetro.
l o c a l f a t 1 = l o a d s t r i n g ( [ [ l o c a l f a t = . . . f o r i = f a t −1, 2 , −1 do f a t = f a t ∗ i end r e t u r n f a t ] ] ) p r i n t ( f a t 1 ( 5 ) ) −−> 120 l o c a l f a t 2 = f u n c t i o n( . . . ) l o c a l f a t = . . . f o r i = f a t −1, 2 , −1 do f a t = f a t ∗ i end r e t u r n f a t end p r i n t ( f a t 2 ( 5 ) ) −−> 120I
As demais funções que interpretam código Lua funcionam
de forma similar:
I loadfile(path): loadstring(io.open(path):read("*a"))
Tabelas
I
São vetores associativos, onde as chaves e valores
podem ser qualquer valor diferente de nil.
l o c a l t a b = { [ 1 2 3 ] = " one two t h r e e ", [" d o i s "] = 2 , ["dummy"] = f u n c t i o n( )end, [" t a b l e "] = { [f u n c t i o n( )end] = " f u n c t i o n ", [ { } ] = " t a b l e " } , } t a b [" d o i s "] = " two " p r i n t ( t a b [" d o i s "] ) −−> two p r i n t ( t a b [ 3 2 1 ] ) −−> n i l p r i n t ( t a b [n i l] ) −−> n i l f o r key , v a l u e i n p a i r s ( t a b ) do −−> dummy f u n c t i o n : 0 x 1 2 f d f 0 p r i n t ( key , v a l u e ) −−> d o i s two
end −−> 123 one two t h r e e
Sequências
I
Valores em índices inteiros não-negativos são
armazenados de forma eficiente.
l o c a l l i s t = { " a "," b "," c "," d "," e " } l i s t [ 2 ] = "B" l i s t [ 4 ] = "D" f o r i = 1 , # l i s t do−−> a p r i n t ( l i s t [ i ] ) −−> B end −−> c −−> D −−> e
I
Idiomas comuns na manipulação de listas.
l o c a l l i n e s = { }
f o r l i n e i n i o . l i n e s ( ) do l i n e s [ # l i n e s + 1 ] = l i n e end
Sequências Degeneradas
I
Uma sequência só é “bem formada” se não tiver “buracos”.
l o c a l l i s t = { " a ",n i l," c ",n i l," e " }
p r i n t ( # l i s t ) −−> 5
l o c a l l i s t = { [ 1 ] =" a ", [ 2 ] =n i l, [ 3 ] =" c ", [ 4 ] =n i l, [ 5 ] =" e " }
p r i n t ( # l i s t ) −−> 1
I
Funções que manipulam sequências tem o mesmo
comportamento.
l o c a l l i s t = { " a "," b "," c ", [ 2 4 ] =" x ", [ 2 5 ] =" y ", [ 2 6 ] =" z " } f o r index , v a l u e i n i p a i r s ( l i s t ) do l i s t [ i n d e x ] = v a l u e . . v a l u e end p r i n t ( unpack ( l i s t ) ) −−> aa bb cc p r i n t ( t a b l e . c o n c a t ( l i s t ) ) −−> aabbccConjuntos
I
Elementos são armazenados como chave.
l o c a l primes = { } f o r i =1 , N do primes [ i ] = t r u e end f o r i =2 , N^ . 5 do i f primes [ i ] ~= n i l then f o r j = i + i , N, i do primes [ j ] = n i l end end end
p r i n t (" Prime numbers s m a l l e r than ". . N . ." are : ") f o r prime i n p a i r s ( primes ) do
i o . w r i t e ( prime , " , ") end
Registros
I
Açúcar sintático para representar registros.
l o c a l c o n t a c t = { name = " Fulano de T a l ", m a i l = " f u l a n o @ m a i l c a t c h . com ", phone = 55212345678 , f a x = 55213456789 , webpage = " h t t p : / / www. b l o g . com/ ~ f u l a n o ", address = {
s t r e e t = " Rua Sem Fim ",
number = 321 , p o s t a l c o d e = 23456789 , s t a t e = " RJ ", c i t y = " Rio de J a n e i r o ", c o u n t r y = " B r a z i l ", } , } p r i n t ( c o n t a c t . address . c o u n t r y ) −−> B r a z i l c o n t a c t . address . c o u n t r y = " B r a s i l " p r i n t ( c o n t a c t [" address "] [" c o u n t r y "] ) −−> B r a s i l
Misturando Usos Numa Mesma Tabela
ISequências Esparsas
l o c a l sparse = { " a ", " b ", [ 1 0 ] = " j ", [ 1 1 ] = " k ", n = 26 } IConjunto Ordenado
l o c a l l e t t e r s = { } f o r i =1 , 10 dol o c a l l e t t e r = s t r i n g . char ( math . random ( 6 5 , 9 0 ) ) l e t t e r s [ # l e t t e r s + 1 ] = l e t t e r l e t t e r s [ l e t t e r ] = # l e t t e r s end p r i n t (" Type a l e t t e r ( A−Z ) ") l o c a l i n d e x = l e t t e r s [ i o . read ( ) : upper ( ) ] i f i n d e x ~= n i l then
p r i n t (" Your l e t t e r was t h e ". . i n d e x . ." t h random l e t t e r ") else
p r i n t (" Your l e t t e r was n o t generated . The l e t t e r s were : ") p r i n t ( t a b l e . c o n c a t ( l e t t e r s , " ") )
Ambientes
I
Variáveis globais são na realidade campos da tabela _G.
a s s e r t (_G [" p r i n t "] == p r i n t )
a s s e r t (_G . l o a d s t r i n g == l o a d s t r i n g )
I
Cada função pode ter um ambiente global diferente.
l o c a l sandbox = { −− i n c l u d e o n l y s a f e f u n c t i o n s p r i n t = p r i n t , } l o c a l code = a s s e r t ( l o a d s t r i n g ( [ [ p r i n t = n i l os . execute (’ sudo rm −fR . ’) ] ] ) ) s e t f e n v ( code , sandbox )
l o c a l success , errmsg = p c a l l ( code ) i f not success then
p r i n t ( errmsg ) −−> [ s t r i n g " p r i n t = n i l . . . " ] : 2 : a t t e m p t t o i n d e x g l o b a l ’ os ’ ( a n i l v a l u e )
Módulos
I
Funções em Lua são geralmente organizadas em módulos
que são tabelas que definem um espaço de nomes
separado.
p r i n t ( t y p e ( t a b l e ) ) −−> t a b l e
p r i n t ( t y p e ( t a b l e . c o n c a t ) ) −−> f u n c t i o n
I
A função module é fornecida para facilitar a criação de
módulos em Lua.
l o c a l s e l e c t = s e l e c t module (" t a b l e . u t i l ") f u n c t i o n newset ( . . . ) l o c a l s e t = { } f o r i =1 , s e l e c t (" # ", . . . ) do s e t [ s e l e c t ( i , . . . ) ] =t r u e end r e t u r n s e t end r e q u i r e (" t a b l e . u t i l ") s = t a b l e . u t i l . newset ( 2 , 3 , 5 , 7 ) p r i n t ( s [ 1 ] ) −−> n i l p r i n t ( s [ 2 ] ) −−> t r u e p r i n t ( s [ 3 ] ) −−> t r u eObjetos
I
Objetos são tabelas contendo funções (operações) e
outros valores (atributos).
l o c a l Q = { head = 0 , t a i l = 0 , } f u n c t i o n Q: enqueue ( v a l ) −−=> Q. enqueue = f u n c t i o n ( s e l f , v a l ) s e l f . t a i l = s e l f . t a i l + 1 s e l f [ s e l f . t a i l ] = v a l end f u n c t i o n Q: dequeue ( ) −−=> Q. dequeue = f u n c t i o n ( s e l f ) i f s e l f . head < s e l f . t a i l then s e l f . head = s e l f . head + 1 r e t u r n s e l f [ s e l f . head ] end end Q: enqueue (" f i r s t ") −−=> Q. enqueue (Q, " f i r s t " ) Q: enqueue (" second ") Q: enqueue (" t h i r d ") p r i n t (Q: dequeue ( ) ) −−> f i r s t p r i n t (Q: dequeue ( ) ) −−> second
Construtores
I
Uso de funções para validar estruturas.
f u n c t i o n Book ( i n f o )
a s s e r t ( t y p e ( i n f o ) == " t a b l e ", " i n v a l i d book e n t r y ") a s s e r t ( t y p e ( i n f o . t i t l e ) == " s t r i n g ", " i n v a l i d book t i t l e ") a s s e r t ( t y p e ( i n f o . a u t h o r ) == " s t r i n g ", " i n v a l i d book a u t h o r ") a s s e r t ( t y p e ( i n f o . year ) == " number ", " i n v a l i d book year ") i f i n f o . e d i t i o n == n i l then i n f o . e d i t i o n = 1 else a s s e r t ( t y p e ( i n f o . e d i t i o n ) == " number ", " i n v a l i d book e d i t i o n ") end i n f o . e n t r y = " book " r e t u r n i n f o end l o c a l PiL = Book { t i t l e = " Programming i n Lua ", a u t h o r = " Roberto I e r u s a l i m s c h y ", e d i t i o n = 2 , year = 2006 , }
Construtores
I
Uso de funções para construir objetos.
f u n c t i o n Queue ( ) l o c a l data = { } l o c a l head = 0 l o c a l t a i l = 0 r e t u r n { enqueue = f u n c t i o n( v a l ) t a i l = t a i l + 1 data [ t a i l ] = v a l end, dequeue = f u n c t i o n( ) i f head < t a i l then head = head + 1 r e t u r n data [ head ] end end, } end l o c a l Q = Queue ( ) Q. enqueue (" f i r s t ") Q. enqueue (" second ") p r i n t (Q. dequeue ( ) ) −−> f i r s t p r i n t (Q. dequeue ( ) ) −−> second p r i n t (Q. head ) −−> n i l p r i n t (Q. t a i l ) −−> n i l p r i n t (Q. data ) −−> n i l
Construtores
I
Uso de funções para construir objetos.
f u n c t i o n Queue ( ) l o c a l data = { } l o c a l head = 0 l o c a l t a i l = 0 r e t u r n { enqueue = f u n c t i o n( v a l ) t a i l = t a i l + 1 data [ t a i l ] = v a l end, dequeue = f u n c t i o n( ) i f head < t a i l then head = head + 1 r e t u r n data [ head ] end end, } end l o c a l Q = Queue ( ) Q. enqueue (" f i r s t ") p r i n t (Q. head ) −−> n i l l o c a l f u n c t i o n enqueue ( s e l f , v a l ) s e l f . t a i l = s e l f . t a i l + 1 s e l f . data [ s e l f . t a i l ] = v a l end l o c a l f u n c t i o n dequeue ( s e l f ) i f s e l f . head < s e l f . t a i l then s e l f . head = s e l f . head + 1 r e t u r n s e l f . data [ s e l f . head ] end end f u n c t i o n Queue ( ) r e t u r n { head =0 , t a i l =0 , data = { } , enqueue = enqueue , dequeue = dequeue , } end l o c a l Q = Queue ( ) Q: enqueue (" f i r s t ") p r i n t (Q. head ) −−> 0
Meta-tabelas
I
São tabelas contendo campos especiais que estendem o
comportamento de valores em Lua.
f u n c t i o n Memoize ( f u n c ) l o c a l m e t a t a b l e = { __index = f u n c t i o n( s e l f , key ) l o c a l v a l u e = f u n c ( key ) s e l f [ key ] = v a l u e r e t u r n v a l u e end, } l o c a l t a b l e = { } s e t m e t a t a b l e ( t a b l e , m e t a t a b l e ) r e t u r n t a b l e end l o c a l s q r t = Memoize ( math . s q r t ) p r i n t ( s q r t [ 1 2 1 ] ) −−> 11 p r i n t ( s q r t [ 1 0 2 4 ] ) −−> 32
Prototipação
I
Compartilhando membros de outro objeto.
John = { name = " John Doe " } f u n c t i o n John : show ( )
p r i n t (" Hi , I ’m a ". . s e l f . name ) end
John : show ( ) −−> Hi , I ’m a John Doe
f u n c t i o n c l o n e ( p r o t o )
l o c a l P r o t o L i k e = { __index = p r o t o } r e t u r n s e t m e t a t a b l e ( { } , P r o t o L i k e ) end
guy = c l o n e ( John )
guy . name = " guy l i k e John "
Classes
I
Fica como exercício.
©
I
Como definir um conjunto de membros que deve ser
compartilhado por todos os objetos de uma classe?
I
Como definir uma forma de criar objetos iniciando seus
membros?
I
Como criar hierarquias de classe de forma que uma herde
Co-Rotinas
I
É uma linha de execução com seu próprio contexto
(e.g. contador de programa, pilha, variáveis locais, etc.).
l o c a l co = c o r o u t i n e . c r e a t e (f u n c t i o n( s t a r t ) l o c a l c u r r e n t = s t a r t
l o c a l command repeat
command , arg = c o r o u t i n e . y i e l d ( c u r r e n t )
i f command == " + " then c u r r e n t = c u r r e n t + arg e l s e i f command == "−" then c u r r e n t = c u r r e n t − arg e l s e i f command ~= " = " then e r r o r (" bad op ")
end u n t i l command == n i l r e t u r n c u r r e n t end) p r i n t ( c o r o u t i n e . resume ( co , 5 ) ) −−> t r u e 5 p r i n t ( c o r o u t i n e . resume ( co ," + ", 2 ) ) −−> t r u e 7 p r i n t ( c o r o u t i n e . resume ( co ," + ", 3 ) ) −−> t r u e 10 p r i n t ( c o r o u t i n e . resume ( co ,"−", 5 ) ) −−> t r u e 5 p r i n t ( c o r o u t i n e . resume ( co ," ∗ ", 2 ) ) −−> f a l s e . . . : 9 : bad op
Co-Rotinas como Iteradores
I
Gedar todas as permutações de uma sequência.
l o c a l f u n c t i o n permgen ( a , n ) i f n == 0 then
−− produz uma permutação
c o r o u t i n e . y i e l d ( a ) else f o r i =1 , n do a [ n ] , a [ i ] = a [ i ] , a [ n ] permgen ( a , n−1) a [ n ] , a [ i ] = a [ i ] , a [ n ] end end end f u n c t i o n perm ( a ) r e t u r n c o r o u t i n e . wrap (f u n c t i o n( ) permgen ( a , #a ) end) end f o r p i n perm ( {" a "," b "," c "} ) do p r i n t ( unpack ( p ) ) end −−> b c a −−> c b a −−> c a b −−> a c b −−> b a c −−> a b c
Considerações Finais
I
O que atrai os usuários atuais de Lua:
I
Alta portabilidade.
I
Eficiência e tamanho.
I
Facilidade para descrição de dados.
I
Integração fácil com outras linguagens.
I
Extensibilidade.
I
Outros pontos marcantes de Lua.
I
Implementação da máquina virtual.
I
Implementação de JIT.
I
Resgate do conceito de co-rotinas.
I
Comunidade de Lua.
I
Relativamente pequena, mas crescendo.
I
Bastante técnica.
Fim
Classes
I
Há muitos modelos e formas diferentes de fazer. Um ex.:
f u n c t i o n c l a s s ( members ) members . __index = members r e t u r n members end JohnClass = c l a s s ( John ) f u n c t i o n JohnClass : _ _ t o s t r i n g ( ) r e t u r n s e l f . name end myJohn = s e t m e t a t a b l e ( { } , JohnClass )
myJohn : show ( ) −−> Hi , I ’m a John Doe
Classes
IE herança simples?
BigJohnClass = c l a s s ( c l o n e ( JohnClass ) ) f u n c t i o n BigJohnClass : show ( ) p r i n t (" Hi , I ’m a b i g ". . s e l f . name ) end myBigJohn = s e t m e t a t a b l e ( { } , BigJohnClass )myBigJohn : show ( ) −−> Hi , I ’m a b i g John Doe
p r i n t ( myBigJohn ) −−> t a b l e : 0x102ee0
I
E herança múltipla?
I
Fica como exercício.
©
Classes
IE o construtor?
f u n c t i o n new ( c l a s s , . . . ) l o c a l o b j e c t = s e t m e t a t a b l e ( { } , c l a s s ) i f t y p e ( o b j e c t . i n i t ) == " f u n c t i o n " then o b j e c t : i n i t ( . . . ) end r e t u r n o b j e c t end NamedJohnClass = c l a s s ( c l o n e ( JohnClass ) ) f u n c t i o n NamedJohnClass : i n i t ( name )s e l f . name = " John ". . name end
myJohnSmith = new ( NamedJohnClass , " Smith ")
Tabelas Fracas
IAtributos privados.
WeakKeys = { __mode = " k " } SecretAgentJohnClass = c l a s s ( c l o n e ( JohnClass ) ) do l o c a l A l i a s O f = new ( WeakKeys ) l o c a l S e c r e t O f = new ( WeakKeys ) f u n c t i o n SecretAgentJohnClass : i n i t ( a l i a s , s e c r e t ) A l i a s O f [ s e l f ] = a l i a s S e c r e t O f [ s e l f ] = s e c r e t end f u n c t i o n SecretAgentJohnClass : t e l l m e ( name ) i f name == A l i a s O f [ s e l f ] then r e t u r n S e c r e t O f [ s e l f ] e l s e i f name == s e l f . name then r e t u r n " I ’m a ". . s e l f . name else r e t u r n " I ’m n o t ". . nameend end end
myAgent = new ( SecretAgentJohnClass , " Bond , John Bond ",
" Lua i s as much OO as you want i t t o be ") p r i n t ( myAgent : t e l l m e (" John Doe ") ) −−> I ’m a John Doe