/ Forside / Teknologi / Udvikling / Perl / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Perl
#NavnPoint
bjarneA 141
poul_from 50
soccer 30
Nicknack 14
Tmpj 0
rekursiv perl og putte ting i en hash
Fra : Henrik Farre


Dato : 18-12-03 15:22

Hej

Jeg indrømmer gerne at jeg er en perl noob, men alligevel kan jeg ikke
fatte hvorfor jeg ikke kan få det til at virke.

Jeg vil lave en "parser" der læser en conf fil og spytter noget andet ud.

Den fil som skal læses ser nogenlunde sådan her ud:

key1 {
   
   key2 = value1
   key3 = value2
   key4 { key5 = value3 }
}

Jeg vil gerne have den fil puttet i en hash, så jeg let kan tilgå den,
f.eks. ved: print($minhash{'key1'}{'key4'}{'key5'}) hvilket vil print
value3 så.

Først læser jeg filen ind i et array, og så køre jeg denne funktion på
den:

sub getSection {
   my $size = @{ $arrayLineRef }; # ref til arrayet m. filen
   my %tempHash;
   my @lineData;
   
   while ($linePos < $size) { # $linePos er 0 første gang
      my $line = @{ $arrayLineRef }[$linePos];
      
      if ($line =~ /\}/) {
         return %tempHash;
      }
            
      if ($line =~ /\{/ ) {
         $line =~ s/\{//;
         my $sectionKey = trim_whitespace($line);
         $linePos++;
         $tempHash{$sectionKey} = ( getSection($linePos) );
      }
      elsif ($line !~ /\}/) {
         @lineData = extract_data($line); # retuner et key/value array
         $tempHash{$lineData[0]} = ($lineData[1]);
      }
      $linePos++;
   }
}

Problemet ligger for det første i at min return %tempHash; ikke retunere
noget. Desuden har jeg fået en del fejl med "odd number of elements i
hash" men de skulle være væk nu.

--
Mvh. / Kind regards
Henrik Farre

http://www.cs.auc.dk/~enrique


 
 
Lars Balker Rasmusse~ (18-12-2003)
Kommentar
Fra : Lars Balker Rasmusse~


Dato : 18-12-03 16:19

Henrik Farre <look@my.signature.txt> writes:
> sub getSection {
>    my $size = @{ $arrayLineRef }; # ref til arrayet m. filen
>    my %tempHash;
>    my @lineData;
>    
>    while ($linePos < $size) { # $linePos er 0 første gang

Lad være med at være afhængig af den slags. En

my $linePos = 0;

før while'n eller uden for funktionen ville være bedre end kommentaren.

>       my $line = @{ $arrayLineRef }[$linePos];

Du bruger array-refen forkert - brug $arrayLineRef->[$linePos] i stedet.

>       if ($line =~ /\}/) {
>          return %tempHash;
>       }
>             
>       if ($line =~ /\{/ ) {
>          $line =~ s/\{//;
>          my $sectionKey = trim_whitespace($line);
>          $linePos++;
>          $tempHash{$sectionKey} = ( getSection($linePos) );

Du bruger ikke argumentet til getSection til noget - det vil sikkert
gå galt, at du bruger en global variabel til rekursionen.

>       }
>       elsif ($line !~ /\}/) {
>          @lineData = extract_data($line); # retuner et key/value array
>          $tempHash{$lineData[0]} = ($lineData[1]);
>       }
>       $linePos++;
>    }
> }
>
> Problemet ligger for det første i at min return %tempHash; ikke retunere
> noget.

Du har ikke nogen "return %tempHash" - der hvor du bruger denne
manglende returværdi, skal du bruge en ref, altså \%tempHash;
--
Lars Balker Rasmussen Consult::Perl

Henrik Farre (18-12-2003)
Kommentar
Fra : Henrik Farre


Dato : 18-12-03 17:01

Den Thu, 18 Dec 2003 16:18:45 +0100. skrev Lars Balker Rasmussen:

>>    while ($linePos < $size) { # $linePos er 0 første gang
>
> Lad være med at være afhængig af den slags. En
>
> my $linePos = 0;
>
> før while'n eller uden for funktionen ville være bedre end kommentaren.

Sry, det var bare for at fortælle at når jeg kalder funktionen første gang
er den nul :)

altså: getSection(0);

>>       my $line = @{ $arrayLineRef }[$linePos];
>
> Du bruger array-refen forkert - brug $arrayLineRef->[$linePos] i stedet.

Hvis jeg ændre det til: my $line = @{ $arrayLineRef->[$linePos] };
Får jeg følgende fejl:
Can't use string ("Window {") as an ARRAY ref while "strict refs" in use at /home/enrique/bin/cpttft.pl line 60.

'Window {' er den første linie i filen

> Du har ikke nogen "return %tempHash" - der hvor du bruger denne
> manglende returværdi, skal du bruge en ref, altså \%tempHash;

Hvis jeg ændre det til:

if ($line =~ /\}/) {
   return \%tempHash;
}

sker det stadig ikke noget. Heller ikke hvis jeg ændre det til: return 1;
ingenting bliver skrevet ud.

Hele scriptet kan ses her: http://www.cs.auc.dk/~enrique/cpttft.pl og et
eksempel på den fil jeg prøver at parse:
http://www.cs.auc.dk/~enrique/AluTheme

--
Mvh. / Kind regards
Henrik Farre

http://www.cs.auc.dk/~enrique


Henrik Farre (21-12-2003)
Kommentar
Fra : Henrik Farre


Dato : 21-12-03 01:41

Den Thu, 18 Dec 2003 17:01:17 +0100. skrev Henrik Farre:

>> Du bruger array-refen forkert - brug $arrayLineRef->[$linePos] i stedet.

Ja, det kan jeg se nu.

Jeg arbejder nu på at komme af med den globale var ($linePos) nogen ide
til hvordan jeg kan gøre det?

sub parsePekwmTheme {
   my $size = @{ $themeFileRef };
   my $returnHash = {};
   my @lineData;
   
   while ($linePos < $size) {
      my $line = $themeFileRef->[$linePos];
      
      if ($line =~ /\}/) {
         return $returnHash;
      }
            
      if ($line =~ /\{/ ) {
         $line =~ s/\{//;
         my $sectionKey = trim_whitespace($line);
         
         $linePos++;
         
         $returnHash->{$sectionKey} = parsePekwmTheme();
      }
      elsif ($line !~ /\}/) {
         @lineData = extract_data($line);
         $returnHash->{$lineData[0]} = $lineData[1];
      }
      $linePos++;
   }
   return $returnHash;
}

Hele scriptet kan ses her: http://www.cs.auc.dk/~enrique/cpttft.pl og et
eksempel på den fil jeg prøver at parse:
http://www.cs.auc.dk/~enrique/AluTheme

--
Mvh. / Kind regards
Henrik Farre

http://www.cs.auc.dk/~enrique


Søg
Reklame
Statistik
Spørgsmål : 177428
Tips : 31962
Nyheder : 719565
Indlæg : 6407936
Brugere : 218877

Månedens bedste
Årets bedste
Sidste års bedste