私は、ファイルを開いて読み込み、行を解析して新しいファイルに書き込む関数を持っています。私はこのファンクションを別のファイルで何回か呼びます。しかし、今私は気づいた、すべての新しい関数呼び出しでは、以前のファイルの行も読み込まれます。どうすればそれを防ぐことができますか? es.txtの古い内容のperlを残さずに別のファイルから読み取る
内容:dt.txtの El anarquismo es una filosofía política y social que llama
内容: der Regel mit Veränderungen der chemischen Bindungen in
プログラムの実行後に、それが唯一のDT」からのトークンが含まれている必要がありますが、作成されたファイルProfileDEは(次のようになります.txtファイルes.txt "」、いくつかのトークンからのものである"):
una
ilos
ism
lític
qui
lí
ti
polí
socia
- 実際のコード:
#! /usr/bin/perl
use utf8;
use warnings;
use strict;
use List::Util qw(min);
use open ':encoding(utf8)';
binmode(STDOUT, ":utf8");
binmode(STDIN, ":utf8");
generateProfile("es.txt", "ES"); #function call to read from file es.txt
generateProfile("dt.txt", "DE"); #second call to read only from file dt.txt
sub generateProfile {
my $file= $_[0]; #taking arguments
my $Lang = $_[1];
open(IN, "<:utf8",$file) || die "error"; #to read file
open(OUT, ">:utf8", "profile$Lang.txt"); # to create and write in file e.g profileDe
my (%ngramL); #any hash for later
my $line;
my (@words);
my (%ngramL);
my (@uni, @bi, @tri, @quad, @five); #array which keeps letterkombinations of different length
while($line =<IN>){
chomp $line;
# print $line; # just for testing: during the second function call, it would print here old content from "es.txt" instead of only reading from "dt.txt"
push(@words, $line);
}
close IN; #doesn't it closed?
foreach my $word (@words){
bigramm($word); #split word in different letter combinations
}
freqL(); #fill that hash with frequences, how many times occures one letter combination e.g. "ab" = 2, "tion"=5
print_hashL(); #print hash
sub bigramm{
my $wort= $_[0];
my $i; my $k;
my @letters= split(//, $wort);
for ($i=0; $i<length($wort)-0; $i++){ ####!!!!! -1?
my $bi= substr($wort, $i, 1);
push(@uni, $bi); }
for ($i=0; $i<length($wort)-1; $i++){
my $bi= substr($wort, $i, 2);
push(@bi, $bi); }
for ($i=0; $i<length($wort)-2; $i++){
my $bi= substr($wort, $i, 3);
push(@tri, $bi); }
for ($i=0; $i<length($wort)-3; $i++){
my $bi= substr($wort, $i, 4);
push(@quad, $bi); }
for ($i=0; $i<length($wort)-4; $i++){
my $bi= substr($wort, $i, 5);
push(@five, $bi); }
}
sub freqL{
for my $duo (@uni, @bi, @tri, @quad, @five){
if(defined $ngramL{$duo}) {$ngramL{$duo}++;}
else {$ngramL{$duo}=1;}
}
}
sub print_hashL{
foreach my $elem(sort{$ngramL{$b}<=>$ngramL{$a}} keys %ngramL) {
print OUT "$elem\n";}
}
}
この問題が発生するかどうかは、いくつかの警告がありますか? :
"my" variable %ngramL masks earlier declaration in same scope at stack.pl line 23.
Variable "@uni" will not stay shared at stack.pl line 46.
Variable "@bi" will not stay shared at stack.pl line 49.
Variable "@tri" will not stay shared at stack.pl line 52.
Variable "@quad" will not stay shared at stack.pl line 55.
Variable "@five" will not stay shared at stack.pl line 58.
Variable "@uni" will not stay shared at stack.pl line 63.
Variable "@bi" will not stay shared at stack.pl line 63.
Variable "@tri" will not stay shared at stack.pl line 63.
Variable "@quad" will not stay shared at stack.pl line 63.
Variable "@five" will not stay shared at stack.pl line 63.
Variable "%ngramL" will not stay shared at stack.pl line 64.
Variable "%ngramL" will not stay shared at stack.pl line 70.
この部分は大丈夫です。 'bigramm'サブはグローバル変数か状態変数を使用していますか?私は、bigrammキャッシュが(グローバルに、または状態変数で)その入力を受け取り、その後キャッシュをクリアしないと思います。 – dgw
私はサブシステム内のサブシステムの専門家ではありませんが、サブシステムの外側で 'my(@words、%ngramL、@uni、@bi、@tri、@quad、@five)を宣言し、' 'generateProfile'を呼び出すと、あなたの問題を解決します。それは迅速な修正のためのものですが、私はより多くの経験/知識を持つ人により正確な回答を投稿できるようにします。私の推測では、他のサブシステム内のサブシステムは一度だけコンパイルされ、それらの外部で宣言された配列/ハッシュは内部変数をグローバル変数に変換されているということです...しかし、それはちょっと推測しています – Dada
私はコード全体を改造しました。私はコードをそのままにしておくと、クイックフィックスも機能しましたが、generateProfile( "en.txt"のような他の関数呼び出しを1つ追加するだけです。 "、" EN "); –