[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