Dúvida Simples - Parâmetros em Lua

934 views
Skip to first unread message

Adrian Laubisch

unread,
May 5, 2012, 10:52:32 AM5/5/12
to lua...@googlegroups.com
Pessoal, uma dúvida simples e provavelmente bem n00b, mas pesquisei na web e não encontrei resposta adequada.

É possível a passagem de parâmetros por referência em funções Lua?

Por exemplo, uma função assim:

function inc (param)
return param + 1
end

eu uso assim, e funciona:

variable = inc(variable)

Mas eu gostaria de ter a função assim:

function inc (param)
param = param + 1
end

e poder usá-la simplesmente assim:

inc(variable)


É possivel fazer algo semelhante?

Desde já obrigado!


|| Adrian Laubisch

Andrws Vieira

unread,
May 5, 2012, 11:44:12 AM5/5/12
to lua...@googlegroups.com
Declara a variável que tu quer incrementar na tua função como global, ai não precisa nem passar ela, não sei se isso te ajuda.




--
Andrws Aires Vieira         
Ciência da Computação 8° Semestre
Grupo PET Computação
Grupo de Arquitetura e Circuitos Integrados - GACI
Universidade Federal de Pelotas - UFPel

Lourival Vieira Neto

unread,
May 5, 2012, 11:59:11 AM5/5/12
to lua...@googlegroups.com
Olá Adrian,

Tabelas em Lua são passadas por referência. Segue um exemplo:

function inc(param)
param.value = param.value + 1
end

p = { value = 0 }
inc(p)
print(p.value) ~> 1

--
Lourival Vieira Neto

2012/5/5 Adrian Laubisch <adrian....@gmail.com>:

Eric Chiesse

unread,
May 5, 2012, 12:38:29 PM5/5/12
to lua...@googlegroups.com
O único jeito de simular a passagem por referência é encapsular a variável em uma tabela. Veja o exemplo:

function inc(i)
    i.i = i.i + 1
end

i = {i=0}
print(i.i) -- > 0
inc(i)
print(i.i) -- > 1

Você pode usar metatables para fazer um uso sem o i.i:

i_mt=
{
    __tostring = function(t)
        return tostring(t.i)
    end

    inc = function(t)
        t.i = t.i + 1
    end
}

i_mt.__index = i_mt

i = setmetatable({i=0}, i_mt)
print(i) -- > 0
inc(i)
print(i) -- > 1

Eu particularmente prefiro fazer diretamente: i = i + 1

Abraço.
---
Eric
www.twitter.com/echiesse
br.linkedin.com/in/echiesse



Em 5 de maio de 2012 11:52, Adrian Laubisch <adrian....@gmail.com> escreveu:

Eric Chiesse

unread,
May 5, 2012, 12:41:58 PM5/5/12
to lua...@googlegroups.com
Na verdade tabelas são passadas por valor, mas as referências dos parâmetros internos são mantidas.

Em particular a função:

function erase(t)
    t = nil
end

não vai anular a tabela no escopo externo à função erase (o que ocorreria se ela fosse passada por referência).
---
Eric
www.twitter.com/echiesse
br.linkedin.com/in/echiesse

Eric Chiesse

unread,
May 5, 2012, 1:32:45 PM5/5/12
to lua...@googlegroups.com
O último trecho de código que mandei continha um erro.
Substituir por:


i_mt=
{
    __tostring = function(t)
        return tostring(t.i)
    end

    inc = function(t)
        t.i = t.i + 1
    end
}

i_mt.__index = i_mt


i = setmetatable({i=0}, i_mt)
print(i)
i:inc()  -- <<<< Esta linha está corrigida aqui.
print(i)


---
Eric
www.twitter.com/echiesse
br.linkedin.com/in/echiesse

Elias Barrionovo

unread,
May 5, 2012, 1:51:52 PM5/5/12
to lua...@googlegroups.com
2012/5/5 Adrian Laubisch <adrian....@gmail.com>:
> É possível a passagem de parâmetros por referência em funções Lua?

Como já responderam, você vai ter que encapsular sua variável em uma
tabela, mas não consigo pensar em um motivo para isso ser necessário,
já que em Lua as funções podem retornar mais de um valor.

Ou seja, em vez disso (não vai funcionar):

function altera_val_e_retorna_random (val) -- como se estivesse
passando por referencia
val = val + 1
return math.random(val)
end

Pode-se fazer algo dessa forma:

function altera_val_e_retorna_random (val) -- como se estivesse
passando por referencia
val = val + 1
return math.random (val), val
end

E usar assim:

> v = 3
> rand, v = altera_val_e_retorna_random(v)
> print(rand, v)
2 4
> rand, v = altera_val_e_retorna_random(v)
> print(rand, v)
4 5


--
NI!

Breno Ramalho Lemes

unread,
May 5, 2012, 7:07:06 PM5/5/12
to Lua BR
On 5 maio, 10:52, Adrian Laubisch <adrian.laubi...@gmail.com> wrote:
> É possível a passagem de parâmetros por referência em funções Lua?

Não. (Todo mundo enfeito, mas ninguém disse a resposta)

Em Lua parâmetros são passados por valor.

Agora porque você quer passar parâmetros por referência? Em outras
linguagens fazemos isso quando precisamos que uma função retorne mais
que um valor, e no caso de Lua isso não é necessário já que podemos
retornar mais de um valor.

Se for só por uma questão estética, preferindo usar "inc(valor)" no
lugar de "valor = inc(valor)", então não há solução. O negócio é usar
o jeito Lua de programar mesmo. Na verdade até dá para simular isso
usando tabelas e metatables (como já citado), mas não recomendo. Além
de complicar seu código, vai mudar o comportamento padrão da linguagem
que pode lhe resultar em dor de cabeça para dar manutenção no código
futuramente. Especialmente se outra pessoa for fazer isso, pois vai
demorar a entender que você modificou o comportamento padrão da
linguagem. Claro que código bem comentado ameniza isso, mas mesmo
assim não acho uma boa ideia.

O lance da tabela ali é o seguinte:

"Valores do tipo table, function, thread e userdata (completo) são
objetos: variáveis não contêm realmente estes valores, somente
referências para eles. Atribuição, passagem de parâmetro, e retorno de
funções sempre lidam com referências para tais valores; estas
operações não implicam em qualquer espécie de cópia."

a = { value = 0 }

O valor de a é um objeto (tabela). Se você passar a como parâmetro de
uma função o *valor* de a será passado, e o valor de a é uma
referência. Por isso:

function inc(param)
param.value = param.value + 1
end

O valor de param é um referência a uma tabela, então você está
modificando a tabela. Mas se fizer:

function inc(param)
param = nil
end

Você está modificando apenas o valor de param, que vai deixar de ser
uma referência a uma tabela para conter o valor nil. Enquanto a tabela
em si vai permanecer lá inalterada.

De qualquer forma, a = nil também não vai eliminar a tabela, seja
dentro ou fora de alguma função, vai só anular a referência. O que vai
eliminar a tabela é o coletor de lixo quando verificar que não existe
mais nenhuma outra referência àquela tabela.

--
http://www.br-lemes.net/

Adrian Laubisch

unread,
May 5, 2012, 7:10:36 PM5/5/12
to lua...@googlegroups.com
Muito obrigado a todos pelas respostas!

Não apenas consegui soluções para o problema, como também tive várias reflexões que me fizeram entender melhor porque Lua não funciona desta forma e a adotar o jeito Lua de programar.

Um abraço e obrigado a todos novamente!

|| Adrian Laubisch



2012/5/5 Breno Ramalho Lemes <br_l...@yahoo.com.br>

Lourival Vieira Neto

unread,
May 5, 2012, 10:37:32 PM5/5/12
to lua...@googlegroups.com
2012/5/5 Breno Ramalho Lemes <br_l...@yahoo.com.br>:
> On 5 maio, 10:52, Adrian Laubisch <adrian.laubi...@gmail.com> wrote:
>> É possível a passagem de parâmetros por referência em funções Lua?
>
> Não. (Todo mundo enfeito, mas ninguém disse a resposta)
>
> Em Lua parâmetros são passados por valor.

"*Tables*, functions, threads, and (full) userdata values are objects:
variables do not actually contain these values, only *references* to
them. Assignment, *parameter passing*, and function returns always
manipulate *references* to such values; these operations do not imply
any kind of copy. " [1]

[1] Lua 5.1 Reference Manual. Roberto Ierusalimschy, Luiz Henrique de
Figueiredo, Waldemar Celes. http://www.lua.org/manual/5.1/manual.html

--
Lourival Vieira Neto

Lourival Vieira Neto

unread,
May 5, 2012, 10:58:31 PM5/5/12
to lua...@googlegroups.com
2012/5/5 Eric Chiesse <echi...@gmail.com>:
> Na verdade tabelas são passadas por valor, mas as referências dos parâmetros
> internos são mantidas.

Na verdade não; tabelas são passadas por referência (assim como
funções e userdata). [1]

[1] Lua 5.1 Reference Manual. Seção 2.2 §9. Roberto Ierusalimschy,
Luiz Henrique de
Figueiredo, Waldemar Celes. http://www.lua.org/manual/5.1/manual.html

> Em particular a função:
>
> function erase(t)
>     t = nil
> end
>
> não vai anular a tabela no escopo externo à função erase (o que ocorreria se
> ela fosse passada por referência).

Não, isso não ocorreria se a tabela fosse passada como referência.

--
Lourival Vieira Neto

Breno Ramalho Lemes

unread,
May 6, 2012, 12:40:35 AM5/6/12
to Lua BR
Lourival,
Eu citei exatamente o mesmo trecho do manual que você, porém em
português. Mas você interpretou de outra forma. Eu entendi o seguinte:

var = { value = 0 }

O valor de var é uma referencia a uma tabela recém criada. Ao passar
var para uma função, o valor dela (a referência) será passada. O que
não é a mesma coisa que passar parâmetro por referencia. Veja,
passamos uma referencia, mas a passagem em si não é por referencia.

Na passagem por referencia, o local na memória onde a variável está
armazenada é passado e você poderia alterar ela fora do escopo da
função, atribuindo nil ou qualquer outro tipo ou valor a ela. Mas não
é isso o que acontece. Veja a diferença:

Em C, passagem de parâmetro por referência:
#include <stdio.h>

void nulo(int *param) {
*param = NULL;
}

int main(int argc, char *argv[]) {
int a = 1;
printf("Antes %d\n", a);
nulo(&a);
printf("Depois %d\n", a);
return 0;
}

Resultado:
Antes 1
Depois 0

Em Lua, passagem de parâmetro por valor:
function nulo(param)
param = nil
end

a = { }
print("Antes", a)
nulo(a)
print("Depois", a)

Resultado:
Antes table: 0x83f9010
Depois table: 0x83f9010

--
http://www.br-lemes.net/

On 5 maio, 22:37, Lourival Vieira Neto <lourival.n...@gmail.com>
wrote:
> 2012/5/5 Breno Ramalho Lemes <br_le...@yahoo.com.br>:
>
> > On 5 maio, 10:52, Adrian Laubisch <adrian.laubi...@gmail.com> wrote:
> >> É possível a passagem de parâmetros por referência em funções Lua?
>
> > Não. (Todo mundo enfeito, mas ninguém disse a resposta)
>
> > Em Lua parâmetros são passados por valor.
>
> "*Tables*, functions, threads, and (full) userdata values are objects:
> variables do not actually contain these values, only *references* to
> them. Assignment, *parameter passing*, and function returns always
> manipulate *references* to such values; these operations do not imply
> any kind of copy. " [1]
>
> [1] Lua 5.1 Reference Manual. Roberto Ierusalimschy, Luiz Henrique de
> Figueiredo, Waldemar Celes.http://www.lua.org/manual/5.1/manual.html
>
> --
> Lourival Vieira Neto

Eric Chiesse

unread,
May 6, 2012, 1:19:02 AM5/6/12
to lua...@googlegroups.com
Breno, teu exemplo só pecou em usar C como comparação pois todas as passagens em C são por valor. :)

No exemplo que você colocou, você passa um ponteiro (endereço de a) por valor.

O melhor seria um exemplo em C++ ou vbscript que suportam passagem por referência de fato. Teu código em C++ usando passagem por referência ficaria:

void nulo(int &param) {

       param = NULL;
}

int main(int argc, char *argv[]) {
       int a = 1;
       printf("Antes %d\n", a);
       nulo(a);

       printf("Depois %d\n", a);
       return 0;
}

Resultado:
Antes 1
Depois 0

De resto é isso que eu ía falar também. Em Lua é passada uma referência, mas por valor.

Acho que a documentação é um pouco forte ao afirmar "these operations do not imply any kind of copy" pois como as variáveis são independentes, no mínimo a cópia dos endereços deve ocorrer. Entendo que no caso de tabelas, funções, etc. há mais um nível de indireção e o que não deve ocorrer é uma "deep copy".

---
Eric


>
> --
> Lourival Vieira Neto

Eric Chiesse

unread,
May 6, 2012, 1:35:09 AM5/6/12
to lua...@googlegroups.com
Em 5 de maio de 2012 23:58, Lourival Vieira Neto <louriv...@gmail.com> escreveu:
2012/5/5 Eric Chiesse <echi...@gmail.com>:
> Na verdade tabelas são passadas por valor, mas as referências dos parâmetros
> internos são mantidas.

Na verdade não; tabelas são passadas por referência (assim como
funções e userdata). [1]

[1] Lua 5.1 Reference Manual. Seção 2.2 §9. Roberto Ierusalimschy,
Luiz Henrique de
Figueiredo, Waldemar Celes. http://www.lua.org/manual/5.1/manual.html

Independente da questão da interpretação da documentação, o comportamento do interpretador é de passagem por cópia de valor. Ele copia uma referência para o escopo interno da função.
Nesse ponto eu respeitosamente opino que a documentação deve ser reavaliada na frase "these operations do not imply any kind of copy", que me parece um pouco forte.
 

> Em particular a função:
>
> function erase(t)
>     t = nil
> end
>
> não vai anular a tabela no escopo externo à função erase (o que ocorreria se
> ela fosse passada por referência).

Não, isso não ocorreria se a tabela fosse passada como referência.

Não entendi bem o que você quis dizer aqui (acho que você se confundiu com o texto). Mas a essência da passagem por referência é o efeito colateral no chamador devido a qualquer modificação na variável dentro do escopo da função mesmo por uma atribuição direta, como ocorre nas passagens por referência em C++ por exemplo.
 

--
Lourival Vieira Neto

Alex Queiroz

unread,
May 6, 2012, 8:20:45 AM5/6/12
to lua...@googlegroups.com
2012/5/6 Lourival Vieira Neto <louriv...@gmail.com>:
> 2012/5/5 Eric Chiesse <echi...@gmail.com>:
>> Na verdade tabelas são passadas por valor, mas as referências dos parâmetros
>> internos são mantidas.
>
> Na verdade não; tabelas são passadas por referência (assim como
> funções e userdata). [1]
>

Todas as variáveis em Lua são passadas por valor, mas variáveis não
contém tabelas, apenas referências a elas.

--
-alex
http://www.artisancoder.com/

Lourival Vieira Neto

unread,
May 6, 2012, 7:15:06 PM5/6/12
to lua...@googlegroups.com
2012/5/6 Alex Queiroz <asan...@gmail.com>:
Concordo. Variáveis são passadas por valor. Tabelas são passadas e
atribuídas por referência.

--
Lourival Vieira Neto

Lourival Vieira Neto

unread,
May 6, 2012, 7:27:10 PM5/6/12
to lua...@googlegroups.com
2012/5/6 Eric Chiesse <echi...@gmail.com>:
> (...)
>> > Em particular a função:
>> >
>> > function erase(t)
>> >     t = nil
>> > end
>> >
>> > não vai anular a tabela no escopo externo à função erase (o que
>> > ocorreria se
>> > ela fosse passada por referência).
>>
>> Não, isso não ocorreria se a tabela fosse passada como referência.
>
>
> Não entendi bem o que você quis dizer aqui (acho que você se confundiu com o
> texto). (...)

O que eu quis dizer foi: caso a tabela fosse passada por referência (o
que de fato ocorre), ela não seria anulada caso a variável que a
referencia dentro do escopo da função fosse anulada. "t = nil" não é
semanticamente equivalente a "free(t)". Acho que você é que está se
confundindo.

--
Lourival Vieira Neto

Lourival Vieira Neto

unread,
May 6, 2012, 7:44:22 PM5/6/12
to lua...@googlegroups.com
2012/5/6 Breno Ramalho Lemes <br_l...@yahoo.com.br>:
> Lourival,
> Eu citei exatamente o mesmo trecho do manual que você, porém em
> português. Mas você interpretou de outra forma. (...)

Desculpe, Breno. Não vi que você tinha citado o mesmo trecho do
manual. Realmente, acho que o interpretamos de forma diferente.
--
Lourival Vieira Neto

Eric Chiesse

unread,
May 6, 2012, 10:28:48 PM5/6/12
to lua...@googlegroups.com
Lourival, coloquei meus comentários em linha.

Em 6 de maio de 2012 20:27, Lourival Vieira Neto <louriv...@gmail.com> escreveu:
2012/5/6 Eric Chiesse <echi...@gmail.com>:
> (...)
>> > Em particular a função:
>> >
>> > function erase(t)
>> >     t = nil
>> > end
>> >
>> > não vai anular a tabela no escopo externo à função erase (o que
>> > ocorreria se
>> > ela fosse passada por referência).
>>
>> Não, isso não ocorreria se a tabela fosse passada como referência.
>
>
> Não entendi bem o que você quis dizer aqui (acho que você se confundiu com o
> texto). (...)

O que eu quis dizer foi: caso a tabela fosse passada por referência (o
que de fato ocorre),

agora entendi o que vc disse.
 
ela não seria anulada caso a variável que a
referencia dentro do escopo da função fosse anulada. "t = nil"

Lourival, antes de prosseguirmos quero dizer que te respeito como profissional e usuário da linguagem e lembrar que estou apenas discutindo tecnicamente a questão no intuito de agregarmos conhecimento de parte a parte. Se estivéssemos discutindo na mesma empresa numa pausa do café, ou tomando um chopp (eu um suco ;) ) tenho certeza que seria muito amigável a discussão chegaríamos a conclusões mais rápido. Mas infelizmente a internet tem suas limitações :(.

Isso dito, respiremos fundo e com todo carinho te digo:

O que você colocou acima não faz sentido. (Lembra que estamos na pausa do café ;)  )
Quando a passagem é por referência sempre há efeitos colaterais no chamador no caso de uma atribuição, o que não ocorre em Lua.
O que ocorre é a passagem de uma referência (sinônimo de um ponteiro para uma tabela) por cópia de valor (a referência(=ponteiro ou endereço da tabela) tem seu valor copiado para o escopo interno da função chamada).
Sem um quadro-negro para mostrar a alocação da variáveis em memória fica difícil mostrar o que estou falando.

Mas enfim, não quero brigar nem entrar numa flame por conta disso.
Acho que o artigo abaixo explica bem a dúvida que está ocorrendo. No artigo você pode assumir que ocorre com Lua a mesma confusão que ocorre com Java no caso da passagem de parâmetros. No caso de Java quem disser que existe passagem por referência na prova de certificação, perde uma questão pois todas as chamadas são por cópia valor mesmo no caso de objetos, onde as referências aos mesmos são passadas por cópia de valor (mesmo caso de Lua)
http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value

No artigo eles propoem o "call by sharing" para se referir a esse caso de passagem. Mas eu não gosto pois acho que não descreve com clareza o que ocorre de fato (passagem de uma referência (=ponteiro ou endereço da tabela, função, ...) por cópia de valor)
 
não é
semanticamente equivalente a "free(t)".

free para mim é usado para desalocar memória mas não altera o valor armazenado em um ponteiro (falando de C onde existe free). Nem pensei nisso pois Lua usa garbage collector.
 
Acho que você é que está se
confundindo.

O assunto é polêmico mesmo. Mas se tudo der certo todos saem com uma compreenção melhor.
 
 
--
Lourival Vieira Neto

--
Lua BR - http://groups.google.com/group/lua-br

Abraço.

Eric.

Lourival Vieira Neto

unread,
May 7, 2012, 12:48:18 AM5/7/12
to lua...@googlegroups.com
2012/5/6 Eric Chiesse <echi...@gmail.com>:
> Lourival, coloquei meus comentários em linha.
>
> Em 6 de maio de 2012 20:27, Lourival Vieira Neto <louriv...@gmail.com>
> escreveu:
>
>> 2012/5/6 Eric Chiesse <echi...@gmail.com>:
>> > (...)
>> >> > Em particular a função:
>> >> >
>> >> > function erase(t)
>> >> >     t = nil
>> >> > end
>> >> >
>> >> > não vai anular a tabela no escopo externo à função erase (o que
>> >> > ocorreria se
>> >> > ela fosse passada por referência).
>> >>
>> >> Não, isso não ocorreria se a tabela fosse passada como referência.
>> >
>> >
>> > Não entendi bem o que você quis dizer aqui (acho que você se confundiu
>> > com o
>> > texto). (...)
>>
>> O que eu quis dizer foi: caso a tabela fosse passada por referência (o
>> que de fato ocorre),
>
>
> agora entendi o que vc disse.
>
>>
>> ela não seria anulada caso a variável que a
>> referencia dentro do escopo da função fosse anulada. "t = nil"
> (...)
>
> O que você colocou acima não faz sentido. (...)

Voce pode explicitar o que exatamente nao faz sentido? Acho que voce
esta' confundindo a passagem da tabela com a passagem da variavel. O
meu ponto e': tabelas em Lua sao passadas (e tambem atribuidas) por
referencia. Nao existe copia de tabelas na passagem de parametros (ou
na atribuicao de variaveis). Em nenhum momento argumentei quanto a
passagem de variaveis serem por referencia. Nao e' este o meu ponto. O
meu ponto e' quanto ao objeto ou tipo de dado em si, e nao a respeito
da variavel que armazena uma referencia para esse tipo. Caso seja
complicado dissociar o objeto da variavel que o referencia, pense no
seguinte exemplo (sem a necessidade de um quadro negro =p): "function
f(t) end f{}".

> Quando a passagem é por referência sempre há efeitos colaterais no chamador no caso de uma atribuição, o que
> não ocorre em Lua. (...)

Em nenhum momento questionei a sua definicao (ou qualquer outra) de
"call-by-reference". Nao estou discutindo isto nem pretendo.

> Mas enfim, não quero brigar nem entrar numa flame por conta disso. (...)

Tambem nao quero provocar nenhum flame; caso isto tenha parecido, nao
foi a minha intencao.

--
Lourival Vieira Neto

Breno Ramalho Lemes

unread,
May 7, 2012, 1:43:04 AM5/7/12
to Lua BR
On 7 maio, 00:48, Lourival Vieira Neto <lourival.n...@gmail.com>
wrote:
> Voce pode explicitar o que exatamente nao faz sentido? Acho que voce
> esta' confundindo a passagem da tabela com a passagem da variavel.

Agora entendi o que você está dizendo. Está certo. Mas nós estávamos
falando de passagem da variável, porque foi isso que o Adrian
perguntou.

O que eu tentei explicar é que a tabela é passada por referência
através de uma variável, e a passagem da variável em si é por valor.

--
http://www.br-lemes.net/

Tomas Guisasola Gorham

unread,
May 7, 2012, 5:20:53 AM5/7/12
to lua...@googlegroups.com
Oi pessoal

Acho que a confus�o � mais de terminologia: parece que alguns
termos est�o sendo usados de formas diferentes. Espero n�o aumentar o
problema com esta mensagem :-)
Pelo que eu entendo, em Lua s� h� passagem por valor, ou seja,
os par�metros em uma chamada de fun��o s�o copiados na pilha antes do
desvio ser feito. Portanto, a fun��o chamada n�o tem acesso �s vari�veis
do chamador, eliminando a chance de efeito colateral sobre estas vari�veis.
Por outro lado, em Lua, alguns tipos n�o s�o manipulados como
valores, como � o caso das tabelas. A cria��o de uma tabela produz uma
refer�ncia para este valor, que � o que se atribui a uma vari�vel.
Juntando-se essas duas caracter�sticas, podemos ter um efeito
semelhante ao de passagem por refer�ncia. Quando uma tabela � par�metro
de uma chamada de fun��o, o valor da vari�vel que se refere a esta
tabela � copiado antes da chamada (passagem por valor), portanto a fun��o
chamada recebe uma c�pia da refer�ncia, ent�o tem acesso � mesma tabela.
A tabela em si n�o � copiada. Entretanto, a fun��o n�o pode alterar a
vari�vel (do chamador) que aponta para esta tabela.

t = {} -- t � uma refer�ncia para uma nova tabela
u = t -- u � uma c�pia de t; ambas referenciam a mesma tabela
u[1] = 2 -- t[1] == 2 !!!

f(t) -- f pode alterar o conte�do da tabela referenciada por t
assert(t==u) -- mas f n�o pode alterar o valor de t

Abra�os,
Tom�s

On Mon, 7 May 2012, Lourival Vieira Neto wrote:

> 2012/5/6 Eric Chiesse <echi...@gmail.com>:
>> Lourival, coloquei meus coment�rios em linha.
>>
>> Em 6 de maio de 2012 20:27, Lourival Vieira Neto <louriv...@gmail.com>
>> escreveu:
>>
>>> 2012/5/6 Eric Chiesse <echi...@gmail.com>:
>>>> (...)
>>>>>> Em particular a fun��o:
>>>>>>
>>>>>> function erase(t)
>>>>>> ��� t = nil
>>>>>> end
>>>>>>
>>>>>> n�o vai anular a tabela no escopo externo � fun��o erase (o que
>>>>>> ocorreria se
>>>>>> ela fosse passada por refer�ncia).
>>>>>
>>>>> N�o, isso n�o ocorreria se a tabela fosse passada como refer�ncia.
>>>>
>>>>
>>>> N�o entendi bem o que voc� quis dizer aqui (acho que voc� se confundiu
>>>> com o
>>>> texto). (...)
>>>
>>> O que eu quis dizer foi: caso a tabela fosse passada por refer�ncia (o
>>> que de fato ocorre),
>>
>>
>> agora entendi o que vc disse.
>>
>>>
>>> ela n�o seria anulada caso a vari�vel que a
>>> referencia dentro do escopo da fun��o fosse anulada. "t = nil"
>> (...)
>>
>> O que voc� colocou acima n�o faz sentido. (...)
>
> Voce pode explicitar o que exatamente nao faz sentido? Acho que voce
> esta' confundindo a passagem da tabela com a passagem da variavel. O
> meu ponto e': tabelas em Lua sao passadas (e tambem atribuidas) por
> referencia. Nao existe copia de tabelas na passagem de parametros (ou
> na atribuicao de variaveis). Em nenhum momento argumentei quanto a
> passagem de variaveis serem por referencia. Nao e' este o meu ponto. O
> meu ponto e' quanto ao objeto ou tipo de dado em si, e nao a respeito
> da variavel que armazena uma referencia para esse tipo. Caso seja
> complicado dissociar o objeto da variavel que o referencia, pense no
> seguinte exemplo (sem a necessidade de um quadro negro =p): "function
> f(t) end f{}".
>
>> Quando a passagem � por refer�ncia sempre h� efeitos colaterais no chamador no caso de uma atribui��o, o que
>> n�o ocorre em Lua. (...)
>
> Em nenhum momento questionei a sua definicao (ou qualquer outra) de
> "call-by-reference". Nao estou discutindo isto nem pretendo.
>
>> Mas enfim, n�o quero brigar nem entrar numa flame por conta disso. (...)

Hallison Batista

unread,
May 7, 2012, 12:47:30 PM5/7/12
to lua...@googlegroups.com
Muito importante a mensagem que o Tomas escreveu. Por favor, para
resolver o problema, leiam Programming in Lua, Chapter 5 - Functions,
p35. Experimentem o seguinte código:

pessoa = { nome = "Fulano Beltrano", idade = 34 }
email = "fb...@algum.com"

function mostre(t, e)
print(t, e)
for k, v in pairs(t) do
print(("%10s: %s"):format(k,v))
end
end

function atualize(t, e)
-- t é uma tabela global
t.nascimento = "1978-10-08"
t.nome = "Hallison Batista"
e = "ti...@var.org"
print(t, e)
end

function apague(t, e)
-- altera o conteúdo da variável local t, mas t global não é alterada, pois
-- todo escopo dentro de uma função é local.
t, e = nil, nil
end

print "pessoa"
mostre(pessoa, email)
print "----------"
-- pessoa
-- table: 0x1b0a210 fb...@algum.com
-- nome: Fulano Beltrano
-- idade: 34
-- ----------
print "atualizando pessoa"
atualize(pessoa, email)
mostre(pessoa, email)
print "----------"
-- atualizando pessoa
-- table: 0x1b0a210 ti...@var.org
-- table: 0x1b0a210 fb...@algum.com
-- nome: Hallison Batista
-- idade: 34
-- nascimento: 1978-10-08
-- ----------
print "apagando pessoa"
apague(pessoa, email)
print "----------"
-- apagando pessoa
-- ----------
print "resultado"
mostre(pessoa, email)
print "----------"
-- resultado
-- table: 0x1b0a210 fb...@algum.com
-- nome: Hallison Batista
-- idade: 34
-- nascimento: 1978-10-08
-- ----------

Observem que a variável email não foi alterada devido ao escopo, mas a
tabela (que possui um escopo próprio) foi alterada.


2012/5/7 Tomas Guisasola Gorham <to...@tecgraf.puc-rio.br>:
>        Oi pessoal
>
>        Acho que a confusão é mais de terminologia: parece que alguns
> termos estão sendo usados de formas diferentes.  Espero não aumentar o
> problema com esta mensagem :-)
>        Pelo que eu entendo, em Lua só há passagem por valor, ou seja,
> os parâmetros em uma chamada de função são copiados na pilha antes do
> desvio ser feito.  Portanto, a função chamada não tem acesso às variáveis
> do chamador, eliminando a chance de efeito colateral sobre estas variáveis.
>        Por outro lado, em Lua, alguns tipos não são manipulados como
> valores, como é o caso das tabelas.  A criação de uma tabela produz uma
> referência para este valor, que é o que se atribui a uma variável.
>        Juntando-se essas duas características, podemos ter um efeito
> semelhante ao de passagem por referência.  Quando uma tabela é parâmetro
> de uma chamada de função, o valor da variável que se refere a esta
> tabela é copiado antes da chamada (passagem por valor), portanto a função
> chamada recebe uma cópia da referência, então tem acesso à mesma tabela.
> A tabela em si não é copiada.  Entretanto, a função não pode alterar a
> variável (do chamador) que aponta para esta tabela.
>
> t = {}       -- t é uma referência para uma nova tabela
> u = t        -- u é uma cópia de t; ambas referenciam a mesma tabela
> u[1] = 2     -- t[1] == 2 !!!
>
> f(t)         -- f pode alterar o conteúdo da tabela referenciada por t
> assert(t==u) -- mas f não pode alterar o valor de t
>
>        Abraços,
>                Tomás
>
>
> On Mon, 7 May 2012, Lourival Vieira Neto wrote:
>
>> 2012/5/6 Eric Chiesse <echi...@gmail.com>:
>>>
>>> Lourival, coloquei meus comentários em linha.
>>>
>>> Em 6 de maio de 2012 20:27, Lourival Vieira Neto
>>> <louriv...@gmail.com>
>>> escreveu:
>>>
>>>> 2012/5/6 Eric Chiesse <echi...@gmail.com>:
>>>>>
>>>>> (...)
>>>>>>>
>>>>>>> Em particular a função:
>>>>>>>
>>>>>>> function erase(t)
>>>>>>>     t = nil
>>>>>>> end
>>>>>>>
>>>>>>> não vai anular a tabela no escopo externo à função erase (o que
>>>>>>> ocorreria se
>>>>>>> ela fosse passada por referência).
>>>>>>
>>>>>>
>>>>>> Não, isso não ocorreria se a tabela fosse passada como referência.
>>>>>
>>>>>
>>>>>
>>>>> Não entendi bem o que você quis dizer aqui (acho que você se confundiu
>>>>> com o
>>>>> texto). (...)
>>>>
>>>>
>>>> O que eu quis dizer foi: caso a tabela fosse passada por referência (o
>>>> que de fato ocorre),
>>>
>>>
>>>
>>> agora entendi o que vc disse.
>>>
>>>>
>>>> ela não seria anulada caso a variável que a
>>>> referencia dentro do escopo da função fosse anulada. "t = nil"
>>>
>>> (...)
>>>
>>> O que você colocou acima não faz sentido. (...)
>>
>>
>> Voce pode explicitar o que exatamente nao faz sentido? Acho que voce
>> esta' confundindo a passagem da tabela com a passagem da variavel. O
>> meu ponto e': tabelas em Lua sao passadas (e tambem atribuidas) por
>> referencia.  Nao existe copia de tabelas na passagem de parametros (ou
>> na atribuicao de variaveis). Em nenhum momento argumentei quanto a
>> passagem de variaveis serem por referencia. Nao e' este o meu ponto. O
>> meu ponto e' quanto ao objeto ou tipo de dado em si, e nao a respeito
>> da variavel que armazena uma referencia para esse tipo. Caso seja
>> complicado dissociar o objeto da variavel que o referencia, pense no
>> seguinte exemplo (sem a necessidade de um quadro negro =p): "function
>> f(t) end f{}".
>>
>>> Quando a passagem é por referência sempre há efeitos colaterais no
>>> chamador no caso de uma atribuição, o que
>>> não ocorre em Lua. (...)
>>
>>
>> Em nenhum momento questionei a sua definicao (ou qualquer outra) de
>> "call-by-reference". Nao estou discutindo isto nem pretendo.
>>
>>> Mas enfim, não quero brigar nem entrar numa flame por conta disso. (...)
>>
>>
>> Tambem nao quero provocar nenhum flame; caso isto tenha parecido, nao
>> foi a minha intencao.
>>
>>
>
> --
>
--
Hallison Batista
hallison...@gmail.com

Eric Chiesse

unread,
May 7, 2012, 10:02:00 PM5/7/12
to lua...@googlegroups.com
Eu não explicaria melhor.

Valeu !!
---
Eric


Em 7 de maio de 2012 06:20, Tomas Guisasola Gorham <to...@tecgraf.puc-rio.br> escreveu:
       Oi pessoal

       Acho que a confusão é mais de terminologia: parece que alguns
termos estão sendo usados de formas diferentes.  Espero não aumentar o

problema com esta mensagem :-)
       Pelo que eu entendo, em Lua só há passagem por valor, ou seja,
os parâmetros em uma chamada de função são copiados na pilha antes do

desvio ser feito.  Portanto, a função chamada não tem acesso às variáveis
do chamador, eliminando a chance de efeito colateral sobre estas variáveis.

       Por outro lado, em Lua, alguns tipos não são manipulados como
valores, como é o caso das tabelas.  A criação de uma tabela produz uma

referência para este valor, que é o que se atribui a uma variável.
       Juntando-se essas duas características, podemos ter um efeito

semelhante ao de passagem por referência.  Quando uma tabela é parâmetro
de uma chamada de função, o valor da variável que se refere a esta

tabela é copiado antes da chamada (passagem por valor), portanto a função
chamada recebe uma cópia da referência, então tem acesso à mesma tabela.

A tabela em si não é copiada.  Entretanto, a função não pode alterar a
variável (do chamador) que aponta para esta tabela.

t = {}       -- t é uma referência para uma nova tabela
u = t        -- u é uma cópia de t; ambas referenciam a mesma tabela

u[1] = 2     -- t[1] == 2 !!!

f(t)         -- f pode alterar o conteúdo da tabela referenciada por t
assert(t==u) -- mas f não pode alterar o valor de t

       Abraços,
               Tomás


On Mon, 7 May 2012, Lourival Vieira Neto wrote:

2012/5/6 Eric Chiesse <echi...@gmail.com>:
Lourival, coloquei meus comentários em linha.


Em 6 de maio de 2012 20:27, Lourival Vieira Neto <louriv...@gmail.com>
escreveu:

2012/5/6 Eric Chiesse <echi...@gmail.com>:
(...)
Em particular a função:


function erase(t)
    t = nil
end

não vai anular a tabela no escopo externo à função erase (o que
ocorreria se
ela fosse passada por referência).

Não, isso não ocorreria se a tabela fosse passada como referência.


Não entendi bem o que você quis dizer aqui (acho que você se confundiu
com o
texto). (...)

O que eu quis dizer foi: caso a tabela fosse passada por referência (o
que de fato ocorre),


agora entendi o que vc disse.


ela não seria anulada caso a variável que a
referencia dentro do escopo da função fosse anulada. "t = nil"
(...)

O que você colocou acima não faz sentido. (...)

Voce pode explicitar o que exatamente nao faz sentido? Acho que voce
esta' confundindo a passagem da tabela com a passagem da variavel. O
meu ponto e': tabelas em Lua sao passadas (e tambem atribuidas) por
referencia.  Nao existe copia de tabelas na passagem de parametros (ou
na atribuicao de variaveis). Em nenhum momento argumentei quanto a
passagem de variaveis serem por referencia. Nao e' este o meu ponto. O
meu ponto e' quanto ao objeto ou tipo de dado em si, e nao a respeito
da variavel que armazena uma referencia para esse tipo. Caso seja
complicado dissociar o objeto da variavel que o referencia, pense no
seguinte exemplo (sem a necessidade de um quadro negro =p): "function
f(t) end f{}".

Quando a passagem é por referência sempre há efeitos colaterais no chamador no caso de uma atribuição, o que
não ocorre em Lua. (...)

Em nenhum momento questionei a sua definicao (ou qualquer outra) de
"call-by-reference". Nao estou discutindo isto nem pretendo.

Mas enfim, não quero brigar nem entrar numa flame por conta disso. (...)

Tambem nao quero provocar nenhum flame; caso isto tenha parecido, nao
foi a minha intencao.



--

Eric Chiesse

unread,
May 7, 2012, 10:09:07 PM5/7/12
to lua...@googlegroups.com
Relax !

Como o Breno falou o tópico levantado foi focado em passagem de variáveis. E em Lua tem as referências às tabelas que acabam causando confusão quando se fala em passagem por referência.

Mas pelo que vc falou abaixo parece que entendemos da mesma forma só tivemos um problema de expressão talvez.

Tudo de bom pra vc!
---
Eric



--
Lourival Vieira Neto

Eric Chiesse

unread,
Dec 21, 2012, 3:33:56 PM12/21/12
to lua...@googlegroups.com
Acho que só com variáveis globais mesmo.

O que exatamente você quer fazer? Talvez haja soluções específicas
para o teu caso.

Abraço
---
Eric


Em 18 de dezembro de 2012 09:49, <tarsi...@gmail.com> escreveu:
> Olá pessoal,
>
> Sou iniciante da linguagem LUA e estou com uma dúvida: de que maneira eu
> faço a passagem de parâmetros entre documentos .lua?
>
> Obrigado.

Elias Barrionovo

unread,
Dec 21, 2012, 3:45:23 PM12/21/12
to lua...@googlegroups.com
2012/12/18 <tarsi...@gmail.com>:
> Olá pessoal,
>
> Sou iniciante da linguagem LUA e estou com uma dúvida: de que maneira eu
> faço a passagem de parâmetros entre documentos .lua?
>
> Obrigado.

Não sei se entendi o que você quer, mas acho que a função
loadfile[1][2] pode ajudar.

[1] 5.1: http://www.lua.org/manual/5.1/manual.html#pdf-loadfile
[2] 5.2: http://www.lua.org/manual/5.2/manual.html#pdf-loadfile

--
NI!

Eric Chiesse

unread,
Dec 21, 2012, 3:52:01 PM12/21/12
to lua...@googlegroups.com
Mas dá para passar parâmetros usando loadfile ?

---
Eric


Em 21 de dezembro de 2012 18:45, Elias Barrionovo
<elias....@gmail.com> escreveu:

Tomas Guisasola Gorham

unread,
Dec 22, 2012, 8:29:43 AM12/22/12
to lua...@googlegroups.com
Ol� Eric

Como voc� deve ter lido no manual, a fun��o loadfile (assim
como a fun��o load) retorna uma fun��o. Quando voc� chamar essa fun��o
estar� executando o conte�do do arquivo, como se tivesse passado-o para
o interpretador de comandos Lua. Ent�o, basta passar os par�metros como
em uma chamada normal! O c�digo do arquivo deve receber esses par�metros
como "varargs":

-- N�o testei esse c�digo !!!!!!!!

-- a.lua -----------
local params = { ... }
-- faz qualquer coisa com os par�metros
return resultado, mensagem_de_erro -- fique � vontade :-)
-- a.lua -----------


-- b.lua -----------
local f = loadfile"a.lua"
f(1, 2) -- executando o arquivo com (1,2) como par�metros
f("abc", "def") -- executando o arquivo com ("abc", "def") como par�metros
-- b.lua -----------

-- N�o testei esse c�digo !!!!!!!!

Espero que tenha ajudado.

Abra�os e Feliz Natal,
Tom�s

On Fri, 21 Dec 2012, Eric Chiesse wrote:

> Mas d� para passar par�metros usando loadfile ?
>
> ---
> Eric
>
>
> Em 21 de dezembro de 2012 18:45, Elias Barrionovo
> <elias....@gmail.com> escreveu:
>> 2012/12/18 <tarsi...@gmail.com>:
>>> Ol� pessoal,
>>>
>>> Sou iniciante da linguagem LUA e estou com uma d�vida: de que maneira eu
>>> fa�o a passagem de par�metros entre documentos .lua?
>>>
>>> Obrigado.
>>
>> N�o sei se entendi o que voc� quer, mas acho que a fun��o
>> loadfile[1][2] pode ajudar.
>>
>> [1] 5.1: http://www.lua.org/manual/5.1/manual.html#pdf-loadfile
>> [2] 5.2: http://www.lua.org/manual/5.2/manual.html#pdf-loadfile
>>
>> --
>> NI!
>>
>> --
>> Lua BR - http://groups.google.com/group/lua-br
>
>

--

Eric Chiesse

unread,
Dec 22, 2012, 5:37:03 PM12/22/12
to lua...@googlegroups.com
Não é que funciona :)

Legal, o Natal vai ser mais feliz. rsrs.

Valeu!
---
Eric Chiesse


Em 22 de dezembro de 2012 10:29, Tomas Guisasola Gorham
<to...@tecgraf.puc-rio.br> escreveu:
> Olá Eric
>
> Como você deve ter lido no manual, a função loadfile (assim
> como a função load) retorna uma função. Quando você chamar essa função
> estará executando o conteúdo do arquivo, como se tivesse passado-o para
> o interpretador de comandos Lua. Então, basta passar os parâmetros como
> em uma chamada normal! O código do arquivo deve receber esses parâmetros
> como "varargs":
>
> -- Não testei esse código !!!!!!!!
>
> -- a.lua -----------
> local params = { ... }
> -- faz qualquer coisa com os parâmetros
> return resultado, mensagem_de_erro -- fique à vontade :-)
> -- a.lua -----------
>
>
> -- b.lua -----------
> local f = loadfile"a.lua"
> f(1, 2) -- executando o arquivo com (1,2) como parâmetros
> f("abc", "def") -- executando o arquivo com ("abc", "def") como parâmetros
> -- b.lua -----------
>
> -- Não testei esse código !!!!!!!!
>
> Espero que tenha ajudado.
>
> Abraços e Feliz Natal,
> Tomás
>
>
> On Fri, 21 Dec 2012, Eric Chiesse wrote:
>
>> Mas dá para passar parâmetros usando loadfile ?
>>
>> ---
>> Eric
>>
>>
>> Em 21 de dezembro de 2012 18:45, Elias Barrionovo
>> <elias....@gmail.com> escreveu:
>>>
>>> 2012/12/18 <tarsi...@gmail.com>:
>>>>
>>>> Olá pessoal,
>>>>
>>>> Sou iniciante da linguagem LUA e estou com uma dúvida: de que maneira eu
>>>> faço a passagem de parâmetros entre documentos .lua?
>>>>
>>>> Obrigado.
>>>
>>>
>>> Não sei se entendi o que você quer, mas acho que a função

tarsi...@gmail.com

unread,
Dec 22, 2012, 8:38:41 PM12/22/12
to lua...@googlegroups.com
Tomas Guisasola Gorham,

Esse trecho de código que você colocou, no arquivo b.lua, tem como acessar os valores das variáveis locais do arquivo a.lua usando a variável local f que está em b.lua? Tentei fazer esse seu exemplo e não funcionou.

Obrigado e Feliz Natal a todos!

Abraço.

Társio.

d4n1

unread,
Dec 22, 2012, 8:53:03 PM12/22/12
to lua...@googlegroups.com
Não entendi bem o que você queria fazer, se for só passar parametros em uma função, faz assim:

dani@beastie:/home/dani % lua
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> function lua_param(param1, param2)
>>   print(param1, param2)
>> end
> lua_param("Parametro 1", "Parametro 2")
Parametro 1    Parametro 2

P.S.: Usando Lua 5.1.5 como mostra na saída no FreeBSD 3:)
Daniel Melo (d4n1)

tarsi...@gmail.com

unread,
Dec 22, 2012, 9:06:49 PM12/22/12
to lua...@googlegroups.com
O que eu quero é acessar os valores das variáveis que são locais em outro arquivo .lua

Obrigado.

Abs,

Társio.

d4n1

unread,
Dec 22, 2012, 9:32:32 PM12/22/12
to lua...@googlegroups.com
Descupe-me ter entendido errado, o que o Tomas passou deve funcionar.
Daniel Melo (d4n1 3:)

tarsi...@gmail.com

unread,
Dec 22, 2012, 10:00:15 PM12/22/12
to lua...@googlegroups.com
Não funcionou. Eu não consegui ter acesso à variável local do outro arquivo. Independente do seu escopo, global ou local, os dados armazenados em uma variável de um arquivo a.lua não são visíveis no arquivo b.lua e vice-versa. O que eu preciso é justamente ter essa flexibilidade.


Obrigado.

Abs,

Társio.

Eric Chiesse

unread,
Dec 22, 2012, 11:21:02 PM12/22/12
to lua...@googlegroups.com
Você não vai ter acesso às variáveis locais do outro arquivo. Do
contrário não seriam locais.

O que o Tomas mostrou foi como passar variáveis via loadfile e
varargs. Mas o código dele é só um exemplo do conceito, não deve rodar
mesmo.

Tenta fazer isso aqui:

A.lua:
local args = {...}
return args[1] + args[2]

Ai chama o interpretador na linha de comando e faz:
soma = loadfile"A.lua"
print(soma(2,3))

Isso deve imprimir 5 na tela. Rodei aqui e funcionou.

Se não for esse tipo de comportamento o que você quer aí você precisa
dar mais detalhes.

Talvez uma alternativa seja você usar a biblioteca de debug do lua
(debug.getlocal). Mas normalmente o código começa a cheirar a
gambiarra.

Abraço.
---
Eric
Reply all
Reply to author
Forward
0 new messages