Previamente no Tutorial Perl nós vimos como abrir arquivos para leitura e escrita. Infelizmente, quando você busca pela web, ou entçao olha códigos antigos você irá se deparar com uma sintaxe um tanto diferente.
Vamos ver o que é, qual é o problema e como evitá-la?.
Então, o que devo fazer?
Antes de explicar o que você não deve fazer, deixe-me fornecer a você links para artigos explicando o que você deve fazer:
Leia como abrir arquivos para leitura no estilo moderno ou o artigo sobre escrever em arquivos utilziando o Perl.
Agora vamos retornar ao antigo, e não tão bom assim, modo de programar.
A forma antiga e não recomendada
Até o lançamento do perl 5.6 - isto é, meados de 2000 - nos costumávamos escrever código como este para abrir um arquivo para escrita:
open OUT, ">$filename" or die ...;
e código como este para leitura:
open IN, $filename or die ...;
A parte "or die" é a mesma que utilizamos hoje em dia.
Como você pode ver a função open
recebe dois parâmetros. O primeiro é um conjunto de letras,
geralmente em caixa alta. Esta é a estrutura que receberá o filehandle. O segundo parâmetro
é um combinado do modo de abertura com o caminho do arquivo que deve ser aberto.
Ou seja, no primeiro caso você vê o sinal 'maior do que' significando que nós estamos abrindo o arquivo
para escrita, mas no segundo exemplo nós omitimos o modo de abertura. Isso funciona porquê a função
open()
funciona em modo de leitura por padrão.
Existem duas grandes diferenças:
Filehandle glob
A primeira diferença está no uso da estranha variável sem o sinal de $
na frente
para receber o filehandle.
(Isto na verdade é uma palavra solta (bareword), mas uma que não dispara o erro
Bareword not allowed while "strict subs" in use).
Funciona da mesma forma que antigamente nos primórdios do Perl, mas há vários problemas:
É global a todo o seu script, então se alguma outra pessoa utilizar o mesmo nome (IN, ENTRADA, OUT, SAIDA, por exemplo) irá ocorrer colisão com as suas variáveis.
É também um tanto difícil passar essas variáveis às suas funções.
Abertura com 2 parâmetros
A segunda diferença é o fato de que nesses exemplos a função open
apenas possui dois parâmetros.
E se a variável $filename
, que você está usando para abrir o arquivo para leitura, contém >/etc/passwd ?
Ops.
O open IN, $filename
irá na verdade abrir o arquivo para escrita.
Você acaba de deletar o arquivo de senhas do seu sistema Linux.
Nada Bom.
É necessário fechar o filehandle
Outra vantagem de usar variáveis definidas dentro de um escopo como filehandles é que elas irão fechar automaticamente quando saírem de escopo.
Como evitar estes problemas?
A melhor saída é evitar ambas práticas utilizando o comando "new", (disponível desde 2000 !) utilizando a função open com 3 parâmetros através de variável escalar definida dentro de um escopo para armazenar o filehandle.
Existem ainda políticas no Perl::Critic que irão ajudá-lo a analizar o seu código e localizar todos os locais onde foram utilizadas as formas descritas acima.
O Bom e o Ruim para leitura
Ruim:
open IN, $filename or die ...;
Bom:
open my $in, '<', $filename or die ...;
O Bom e o Ruim para escrita
Ruim:
open IN, ">$filename" or die ...;
Bom:
open my $in, '>', $filename or die ...;