Escopo de váriáveis/funções ao utilizar loadfile

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Escopo de váriáveis/funções ao utilizar loadfile

Valmir Manfrim
Olá Srs,

Estou tentando realizar o seguinte processo, carregar outras funções através do meu modulo utilizando loadfile. Implementei o seguinte código:

local handle, err = loadfile( <arquivo> )
if (err) then
  return false, err
else
  setfenv( handle, _M )
  local status, err = pcall( handle )
    if (status) then
      return true, true
    else
      return false, err
    end
end


Tudo que esta declarado como local em <arquivo>, o modúlo não consigo acessar, e da mesma forma tudo que esta declarado como local no modulo, o funções carregadas por loadfile não conseguem acessar. Abaixo segue um exemplo:

_______________________________________________
module( 'Scope', package.seeall )
local text = "Teste..."
local handle, err = loadfile( '.../teste2.lua' )
if (err) then
  --return false, err
else
  setfenv( handle, _M )
  local status, err = pcall( handle )
    if (status) then
      --return true, true
    else
      --return false, err
    end
end
 

generate( ) -->> retorna erro (attempt to call global 'generate' (a nil value)). Se eu declarar generate( ) no arquivo teste2.lua sem ser local, funciona...


_____________________________
<teste2.lua>
local function generate( )
 print( 'Function generate...' )
 print( text )    -->> imprime nil. Se eu declarar text como global em Scope, funciona...
end


Gostaria de entender perfeitamente como funciona o escopo destas variáveis locais em lua. No manual de referência, ítem 2.6 (Regras de Visibilidade) diz o seguinte: "O escopo das variáveis começa no primeiro comando depois da sua declaração e vai até o fim do bloco mais interno que inclui a declaração". Neste caso text foi declarado no inicio do Scope, ou seja, fora de qualquer bloco interno a este módulo. Qual seria o escopo desta variávável e porquê as funções carregadas por loadfile não a enxergam ?  Eu poderia dizer que uma varíavel declarada como local em um módulo (como é o caso de text no exemplo acima), seria global ao mesmo ?
Obrigado pela compreensão!

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Elias Barrionovo

On Jul 14, 2012 10:04 AM, "Valmir Manfrim" <[hidden email]> wrote:
> Gostaria de entender perfeitamente como funciona o escopo destas variáveis locais em lua. No manual de referência, ítem 2.6 (Regras de Visibilidade) diz o seguinte: "O escopo das variáveis começa no primeiro comando depois da sua declaração e vai até o fim do bloco mais interno que inclui a declaração". Neste caso text foi declarado no inicio do Scope, ou seja, fora de qualquer bloco interno a este módulo. Qual seria o escopo desta variávável e porquê as funções carregadas por loadfile não a enxergam ?  Eu poderia dizer que uma varíavel declarada como local em um módulo (como é o caso de text no exemplo acima), seria global ao mesmo ?

Um arquivo .lua possui um escopo dele mesmo; pense num .lua como uma função implícita, tanto é que ele pode retornar valores.

Aliás, cuidado com a função module, porque ela faz algumas magias com o ambiente (já tive dores de cabeça por causa disso). Na verdade, ela foi bem criticada e deprecada (existe essa palavra em português?) na versão 5.2.

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Valmir Manfrim

Um arquivo .lua possui um escopo dele mesmo; pense num .lua como uma função implícita, tanto é que ele pode retornar valores.

Aliás, cuidado com a função module, porque ela faz algumas magias com o ambiente (já tive dores de cabeça por causa disso). Na verdade, ela foi bem criticada e deprecada (existe essa palavra em português?) na versão 5.2.

 
 
Elias,
 
 
Ha alguma forma de contornar isto ? 

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Valmir Manfrim
Ha alguma forma de um arquivo carregado por loadfile enxergar as variáveis locais do arquivo que o carregou ?

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Elias Barrionovo
2012/7/16 Valmir Manfrim <[hidden email]>:
> Ha alguma forma de um arquivo carregado por loadfile enxergar as variáveis
> locais do arquivo que o carregou ?

Se você quer tanto acessar as variáveis locais de outro arquivo, por
que não declará-las como globais, então? Afinal, é para isso que o
escopo global serve.
--
NI!

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Valmir Manfrim
Porquê isto "suja" o código, não fica bacana, bem organizado. Se eu declarar como global vai funcionar, como mencionei no primeiro post!

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Elias Barrionovo
On Mon, Jul 16, 2012 at 3:06 PM, Valmir Manfrim <[hidden email]> wrote:
> Porquê isto "suja" o código, não fica bacana, bem organizado. Se eu declarar
> como global vai funcionar, como mencionei no primeiro post!
O que suja o código é tentar fazer uma gambiarra para acessar
variáveis locais de outro módulo (quando o escopo global foi feito
para isso). De qualquer forma, como disseram, você pode fazer um monte
de getters e setters para essas variáveis (o que seria muito feio
também...).

--
NI!

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Eric Chiesse
In reply to this post by Valmir Manfrim
Mas no caso que você citou as locais terão o mesmo efeito de globais (com área de efeito menor é verdade).
Mas dentro da função definida por loadfile vc teria os mesmos problemas de efeitos colaterais e legibilidade que o uso de globais acarreta. A função definida na chamada ao loadfile seria "suja" pois conta com uma variável não definida em seu escopo. Seria muito fácil alguém esquecer de definir a tal variável no chamador e crashar tudo em consequencia.

---
Eric


2012/7/16 Valmir Manfrim <[hidden email]>
Porquê isto "suja" o código, não fica bacana, bem organizado. Se eu declarar como global vai funcionar, como mencionei no primeiro post!

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

RE: Escopo de váriáveis/funções ao utilizar loadfile

Francisco Ari Josino Júnior
In reply to this post by Elias Barrionovo
...Ou talvez um getter que retorne todas as variaveis de uma vez... mas isso consegue ser mais feio ainda, concordo com o Elias quando tornar uma variável global em Lua é muito menos "sujo" que usar getters e setters. Minha única sugestão quanto a isso seria que você criasse uma tabela ou algo do tipo para melhorar no encapsulamento das variáveis, so pra manter a referencia de onde cada uma vem ou algo do tipo.

> Date: Mon, 16 Jul 2012 15:13:09 -0300

> Subject: Re: [lua-br] Escopo de váriáveis/funções ao utilizar loadfile
> From: [hidden email]
> To: [hidden email]
>
> On Mon, Jul 16, 2012 at 3:06 PM, Valmir Manfrim <[hidden email]> wrote:
> > Porquê isto "suja" o código, não fica bacana, bem organizado. Se eu declarar
> > como global vai funcionar, como mencionei no primeiro post!
> O que suja o código é tentar fazer uma gambiarra para acessar
> variáveis locais de outro módulo (quando o escopo global foi feito
> para isso). De qualquer forma, como disseram, você pode fazer um monte
> de getters e setters para essas variáveis (o que seria muito feio
> também...).
>
> --
> NI!
>
> --
> Lua BR - http://groups.google.com/group/lua-br

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Valmir Manfrim
Pessoal, obrigado pelas respostas até o momento. Deixa eu explicar a arquitetura onde trabalho para entenderem melhor o porquê da minha dúvida. Eu trabalho com desenvolvimento embarcado, onde tenhu serviços (módulos) responsáveis por determinadas tarefas. Em desenvolvimento embarcado, memória é um ponto crítico. Pensando nisto a minha idéia é dividir estes módulos em arquivos .lua onde eu sempre subo o .lua principal (que inicia o módulo) e, de acordo com uma configuração do equipamento, eu irei subir os outros .lua, com o intuito de enocomizar RAM. Neste ponto entra o loadfile. Estes arquivos .lua não são módulos, e sim partes de um módulo, de acordo com a configuração eu carrego determinado .lua. No arquivo principal que é sempre carregado estão algumas variáveis que são locais a este módulo e quando eu carrego um outro arquivo .lua (uma parte extra deste módulo) gostaria que tivessem acesso a estas variáveis sem eu ter que declarar como global.

Vocês sabem qual o impacto de memória de se declarar uma variável como local ou global ?

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Roberto Ierusalimschy
> Vocês sabem qual o impacto de memória de se declarar uma variável como
> local ou global ?

Quantas variáveis você pretende declarar?

-- Roberto

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Valmir Manfrim


Em segunda-feira, 16 de julho de 2012 18h01min55s UTC-3, Roberto Ierusalimschy escreveu:

Quantas vari�veis voc� pretende declarar?

-- Roberto

Roberto, primeiramente é uma honra hehe

Não tenho um número certo, pois as variáveis crescem como o aplicativo cresce, mas hoje tenhu 8 variáveis nesta condição, onde preciso declará-las como global. Estou meio confuso quanto ao escopo das variáveis em lua, quando declaro como global dentro de um módulo, percebo que ela  fica alocada na tabela do módulo (_M), e não vai para o ambiente global (_G). Quando declaro como local, simplismente não sei para onde ela vai rsrs... Acho que ninguém melhor do que você para esclarecer isto.

Aproveitando a oportunidade, quantos bits são usados para alocar uma variável em lua ?

Sobre o dofile, você tem alguma posição ?

Acompanhei seus três episódios no grokpodcast.com onde você cita sobre projetos que você so descobre sobre lua quando ja estão com proporções enormes, acho que faço parte de um destes hehe. Trabalho com desenvolvimento embarcado em lua para um equipamento de comunicação satelital (fornecedor: www.skywave.com), não sei se ja conheçe este projeto, trabalho nele a quase 1 ano, já temos outros projetos maiores envolvendo o lua.

Obrigado!

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Roberto Ierusalimschy
> Não tenho um número certo, pois as variáveis crescem como o aplicativo
> cresce, mas hoje tenhu 8 variáveis nesta condição, onde preciso declará-las
> como global. Estou meio confuso quanto ao escopo das variáveis em lua,
> quando declaro como global dentro de um módulo, percebo que ela  fica
> alocada na tabela do módulo (_M), e não vai para o ambiente global (_G).
> Quando declaro como local, simplismente não sei para onde ela vai rsrs...
> Acho que ninguém melhor do que você para esclarecer isto.

Variáveis "globais" vão para o ambiente do módulo, variáveis locais moram
na pilha.


> Aproveitando a oportunidade, quantos bits são usados para alocar uma
> variável em lua ?

Depende de um monte de coisas. Mas se você realmente está preocupado
com quantos bits uma dúzia de variáveis vão usar, talvez Lua não
seja a solução adequada para seu problema. Você deveria usar C,
assembler ou algo parecido.

(Em uma aproximação grosseira, uma variável global usa ~256 bits. Uma
tabela vazia usa a mesma coisa.)


> Sobre o dofile, você tem alguma posição ?

Acho que a melhor opção já foi sugerida por outros. Crie um ambiente
próprio para suas variáveis, e carregue os arquivos compartilhando
este ambiente.

-- Roberto

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Augusto Rodrigues
In reply to this post by Valmir Manfrim
Em 16 de julho de 2012 11:14, Valmir Manfrim <[hidden email]> escreveu:
> Ha alguma forma de um arquivo carregado por loadfile enxergar as variáveis
> locais do arquivo que o carregou ?
>
> --
> Lua BR - http://groups.google.com/group/lua-br

Olha, eu trabalho com Lua embarcado em terminais POS. E nos nossos
projetos usamos os arquivos .lua como módulos também. Entretanto não
utilizamos a função loadfile.

Um exemplo do que estou falando baseado  no que vc esta postando:

___________________
<teste2.lua>
module( package.seeall )

function generate( arg_1, arg_2 )
  print( 'Function generate...' )
  print( arg_1 )
  print( arg_2 )

  return arg_1 .. arg_2
end

_________________
<main chunck ou outro módulo>

var_global = "variavel global"
local var_local = "var local"

modulo_teste = require ('.../teste2.lua')

resultado = modulo_teste.text(var_global, var_local)

modulo_teste = nil
collect_garbage()

print(resultado)


Porem identificamos alguns comportamentos do comando 'module'. Quando
um arquivo lua é carregado pelo comando modulo e este por sua vez
carrega outros arquivos lua, pode ser que esses outros módulos não
sejam descarregados da memoria pelo collect_garbage (acho que não
são).

O que foi feito foi uma função no arquivo lua que procura as
dependências do modulo especificado e vai descarregando os mesmos da
memória.

--
Lua BR - http://groups.google.com/group/lua-br
Reply | Threaded
Open this post in threaded view
|

Re: Escopo de váriáveis/funções ao utilizar loadfile

Augusto Rodrigues
> Porem identificamos alguns comportamentos do comando 'module'. Quando
> um arquivo lua é carregado pelo comando modulo e este por sua vez
> carrega outros arquivos lua, pode ser que esses outros módulos não
> sejam descarregados da memoria pelo collect_garbage (acho que não
> são).

Galera, agora que notei o erro: o comando que é utilizado é o
"require" e não o comando "modulo" (que não existe, pois o comando
correto é o "module").

E o arquivo carregado pelo comando "require" pode ser carregar outros
arquivos pelo mesmo comando 'require".

Entretanto existe a possibilidade de que somente o arquivo teste2.lua
seja descarregado da memória. Principalmente quando algum arquivo
carregado pelo arquivo teste2.lua esteja sendo utilizado por um outro
arquivo lua da aplicação.

Bom .. é isso.

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