[Cascavel-pm] Re: Escopo: Dúvida

Ednardo Lobo ednardo em elobo.cjb.net
Domingo Janeiro 5 23:25:29 CST 2003


    Luciano,

    Acabei fazendo uma  pesquisa, além de contar com a  ajuda do Fabiano
que enviou-me um trecho de um  livro (O'REILLY, Pragramming Perl 3ª Ed.,
pag. 761) que fala sobre isso e elucidou algumas coisas:

    1. O `filehandler', de fato é global, porém não tanto. Em Perl, cada
    pacote possui uma  tabela de símbolos própria, ou seja,  o escopo do
    handler  é restringido  ao pacote  que o  declarou. Porém  há alguma
    excessões, veja o trecho abaixo.
    
           Only identifiers  starting with  letters (or  underscore) are
           stored in  a package's  symbol table.  All other  symbols are
           kept  in  package  "main", including  all  punctuation  vari­
           ables,  like $_.  In  addition, when  unqualified, the  iden­
           tifiers STDIN,  STDOUT, STDERR, ARGV, ARGVOUT,  ENV, INC, and
           SIG are  forced to be in  package "main", even when  used for
           other purposes than their built-in one. If you have a package
           called "m",  "s", or  "y", then you  can't use  the qualified
           form of an identifier because it would be instead interpreted
           as  a pattern  match, a  substitution, or  a transliteration.
           
           (man perlmod)
           

    2. Quando se  tenta abrir um `filehandler'  previamente aberto, ele
    será implicitamente fechado primeiro.

           The  "open" function  takes  two arguments:  the  first is  a
           filehandle, and the second is a single string comprising both
           what to open and how to  open it. "open" returns true when it
           works, and when it fails, returns  a false value and sets the
           special  variable $!  to  reflect the  system  error. If  the
           filehandle  was  previously  opened, it  will  be  implicitly
           closed first.
           
           (man perldata)

    3. É possível criar um escopo mais restritivo para um `file handler'
    usando um tipo interno especial da Perl, `typeglobs'.

           Typeglobs are also  a way to create a  local filehandle using
           the local() operator. These last until their block is exited,
           but may be passed back. For example:

               sub newopen {
                   my $path = shift;
                   local *FH;  # not my!
                   open(FH,$path) or return undef;
                   return *FH;
               }
               $fh = newopen('/etc/passwd');

           (man perldata)

    4.   Todas   as   funções   que  criam   `filehandlers',   o   fazem
    automaticamente anônimo se  em vez de um  símbolo identificador (ex:
    FH), for especificado  uma variável escalar não  inicializada. Com a
    vantagem,  ainda, do  `filehandler' ser  automaticamente fechado  ao
    final  do  escopo  dessa  variável, caso  não  exista  nenhum  outra
    referência a ela fora de seu escopo.

           All  functions  that  are  capable  of  creating  filehandles
           (open(),   opendir(),    pipe(),   socketpair(),   sysopen(),
           socket(),  and accept())  automatically  create an  anonymous
           filehandle if the  handle passed to them  is an uninitialized
           scalar variable. This allows  the constructs such as "open(my
           $fh, ...)"  and "open(local  $fh,...)" to  be used  to create
           filehandles  that will  conveniently be  closed automatically
           when the scope  ends, provided there are  no other references
           to them. This largely eliminates  the need for typeglobs when
           opening filehandles  that must  be passed  around, as  in the
           following example:

           sub myopen {
               open my $fh,"@_" or die "Can't open '@_': $!";
               return $fh;
           }

           {
               my $f = myopen("</etc/motd");
               print <$f>;
               # $f implicitly closed here
           }

           (man perldata)


    Bem pessoal, a Perl é um  grande Oráculo! Muitos segredos e truques,
ainda há, a serem explorados e desvendados. O que a faz facinante!! :-)

On Sun, Jan 05, 2003 at 10:34:32PM -0200, lup wrote:
> Olá Ednardo!
> 
>     Olha amigo, a melhor coisa que eu  teria pra te dizer é... Só Deus
> sabe, realmente não testei isso. Porém eu imagino voltando um pouco ao
> C que os HANDLERS são globais, portanto quando você faz o segundo open
> referenciando a stream a FH que  já estava aberta você mata a primeira
> STREAM, seria um reopen. Da minha  maneira de ver é isso que acontece.
> Tanto  são globais  que  você  pode referir-se  a  STDIN  e STDOUT  de
> qualquer lugar do programa e não  me lembro de existir nenhuma maneira
> de você explicitar o modo global para uma stream como:
>
> global open(FH , ARQUIVO); :-) isso é bem estranho.
> 
> Um abraço,
> 
>      Luciano Greiner
> 
> > Em perl o escopo de uma variável, é sempre o bloco em que a mesma
> > foi declarada, por exemplo:
> > 
> > ------------------------------------------------------------
> > use strict;
> > 
> > {
> > my $a = 10
> > my $f = 0;
> > 
> > while (not $f) {
> > my $a = 20;
> > 
> > $f = 1;
> > 
> > print $a # imprime 20
> > }
> > 
> > print $a # imprime 10
> > print $f # imprime 1
> > }
> > 
> > print $f; # com 'use strict', variável indefinida
> > ------------------------------------------------------------
> > 
> > 
> > Minha dúvida: File Handles, também possuem escopo?
> > 
> > Por exemplo:
> > 
> > ------------------------------------------------------------
> > use strict;
> > 
> > open FH,">>/etc/passwd";
> > 
> > my ($login,$password) = &get();
> > 
> > ...
> > 
> > print FH "$login:$password:$UID:$GID::$HOME:$SHELL\n"
> > 
> > close FH;
> > 
> > #
> > ## Obtem `login' e `password'
> > # 
> > sub get {
> > open FH,"/var/tmp/user.tmp";
> > 
> > my ($login,$passwd) = split / /,;
> > 
> > close FH;
> > 
> > return($login,$password);
> > }
> > ------------------------------------------------------------
> > 
> > O que acontecerá com `FH' após `&get' ter sido executada? 
> > 
> > 
> > -- 
> > Ednardo Lobo - www.elobo.cjb.net
> > 

-- 
    Ednardo Lobo - www.elobo.cjb.net

--
Well begun is half done.
		-- Aristotle



Mais detalhes sobre a lista de discussão Cascavel-pm