2016-06-15 6 views
2

Ich habe eine config.file, um einige Tests zu machen, und ich möchte auch einige Werte von diesem bekommen.Wie man einige Werte mit einer Schleife von Hashes von Hashes in Perl bekommt

Hier mein config.file:

my $folder = 'E:\FOLDER\Test\WEB'; 
{ 
     license => [ 'kit-licence.zip', 
        'kit-work.zip' 
        ], 
     programs => [ 
      #template society =>\%program_work 
      'VIKTOR DESCRIPTION PRODUCT' => { 
        name => 'VIKTOR ', 
        parameters => [ 
          Count_id       => '06 (Viktor)', 
          Birth_date     => '1995-04-30', 
          Marriage_date    => '2014-05-26', 
          Divorce_date    => '2015-03-30', 
          Activities_folder    => $folder.'\VIKTOR\independent worker', 
          Activities_format    => 'Enterprise Format (V35)', 
          Description_File_from  => $folder.'\VIKTOR\FILE\description.xlm', 

        ] 
      }, 

      'OLIVER NEW OBJECT' => { 
        name => 'OLIVER ', 
        parameters => [ 
          Count_id       => '06 (oliver)', 
          Birth_date     => '1990-04-30', 
          Marriage_date    => '2011-03-26', 
          Divorce_date    => '2014-01-30', 
          Activities_folder    => $folder.'\OLIVER\independent worker', 
          Activities_format    => 'Enterprise Format (V35)', 
          Description_File_from  => $folder.'\OLIVER\FILE\description.xlm', 

        ] 
      }, 
     ] 
}; 

Meine Datei Test folgt:

#test.pl 
use Modern::Perl; 
my $config = do 'work.conf'; 
use Data::Dumper; 
say Dumper($config); 

Um Parameter in Programme für Viktor zum Beispiel, ich kann dies tun:

%programs = @{ $config->{programs} }; 
    for my $prog (values %programs) { 
     my %param = @{ $prog->{parameters} }; 
     for my $name (sort keys %param){ 
     print $name, ': ', $param{$name},"\n"; 
     } 
    } 

Aber in meinem Fall möchte ich Parameter für jeden Benutzer erhalten können. Hier ist es nur für Viktor. Ich möchte sie für Oliver oder für einen anderen Benutzer bekommen. Dafür und um alle Benutzer zu unterscheiden, muss ich die "template society" verwenden, mit der sich jeder Benutzer unterscheidet. Zum Beispiel für Viktor: "VIKTOR DESCRIPTION PRODUCT". Für Oliver: "OLIVER NEUES OBJEKT".

Wie kann ich das tun?

Das Gleiche gilt für „Lizenz“:

license => [ 'kit-licence.zip', 
       'kit-work.zip' 
        ], 
     programs => [.. 

würde Ich mag die Lizenz nach Name eines jeden bekommen. Zum Beispiel "kit-license.zip".

und nicht durch „harte Codierung“ wie folgt aus:

use File::Spec::Functions qw/catfile/; 
my $filename = catfile($::svn, ${$config->{license}}[0]); 
my $filename1 = catfile($::svn, ${$config->{license}}[1]); 

Vielleicht in einer Schleife, aber ich finde nicht.

PS: Frag mich nicht, warum sie alle geschieden sind. Ich weiß es wirklich nicht.

+1

Ich würde nicht über den geschiedenen Status fragt sich, sondern vielmehr darüber, warum diese Datenstruktur ist so seltsam. – simbabque

Antwort

2

Sie sind bereits dabei, diese Array-Refs in Hashes umzuwandeln. Aber die values macht dein Leben schwer. Sie benötigen den Schlüssel und den Wert gleichzeitig. Sie können dazu each verwenden.

my %programs = @{ $config->{programs} }; 
while (my ($template_society, $value) = each %programs) { 
    my %param = @{ $value->{parameters} }; 
    print "$template_society\n"; 
    for my $name (sort keys %param) { 
     print "\t", $name, ': ', $param{$name}, "\n"; 
    } 
} 

Dies wird die folgende Ausgabe:

VIKTOR DESCRIPTION PRODUCT 
    Activities_folder: \VIKTOR\independent worker 
    Activities_format: Enterprise Format (V35) 
    Birth_date: 1995-04-30 
    Count_id: 06 (Viktor) 
    Description_File_from: \VIKTOR\FILE\description.xlm 
    Divorce_date: 2015-03-30 
    Marriage_date: 2014-05-26 
OLIVER NEW OBJECT 
    Activities_folder: \OLIVER\independent worker 
    Activities_format: Enterprise Format (V35) 
    Birth_date: 1990-04-30 
    Count_id: 06 (oliver) 
    Description_File_from: \OLIVER\FILE\description.xlm 
    Divorce_date: 2014-01-30 
    Marriage_date: 2011-03-26 

Die each Einbau-Renditen sowohl den Schlüssel und den Wert einer Hash pro Iteration und undef sobald es fertig ist. Deshalb müssen Sie es in eine while Schleife legen.

Wenn Sie nicht wie die each Ansatz, können Sie auch keys statt values verwenden, um die Schlüssel ($template_society) und verwenden, die den entsprechenden Wert zu suchen.

my %programs = @{ $config->{programs} }; 
foreach my $template_society (keys %programs) { 
    my %param = @{ $programs{$template_society}->{parameters} }; 
    print "$template_society\n"; 
    for my $name (sort keys %param) { 
     print "\t", $name, ': ', $param{$name}, "\n"; 
    } 
} 

Dies gibt Ihnen die gleiche Ausgabe.


alle Pfade Ihre Lizenz bekommen Sie sie in einem Array speichern müssen und eine Schleife verwenden, um Ihre Array ref in diesem Array zu verarbeiten. Der einfachste und prägnanteste Weg ist die Verwendung von map.

my @licences = map { catfile($::svn, $_) } @{ $config->{license} }; 

Es ist wie eine foreach Schleife, nur kürzer. Der BLOCK ist im Grunde eine Funktion, die den aktuellen Iterationsgegenstand in $_ bekommt. Es ist im Wesentlichen das Gleiche wie das Folgende, nur mehr perlisch.

my @licences; 
foreach my $licence (@{ $config->{license} }) { 
    push @licences, catfile($::svn, $licence); 
} 

nicht Versuchen Sie nicht, Variablen wie $foo1, $foo2 und so weiter dynamisch zu erstellen. Das wird nicht funktionieren. See this für eine Erklärung warum.


Endlich ein Wort auf $::svn: Wenn Sie in einem Paket sind, sollten Sie Ihren Code in eine Funktion setzen und $svn als Argument akzeptieren. Das Arbeiten mit Globals oder Paketvariablen aus verschiedenen Paketen ist knifflig und chaotisch und Sie werden sich irgendwann in den Fuß schießen.

1: Das normale Dokument zur Zeit gebrochen ist, so habe ich archive.org es zu bekommen

+0

Danke @simbabque. Deine Herangehensweise ist ziemlich gut. Ich werde mir die Zeit nehmen, das zu sehen und zu verstehen. Hast du eine Idee für den zweiten Teil meiner Post, betreffend "Lizenz". Danke im Voraus ! – Chaoui05

+0

@ Chaoui05 Ich habe diesen Teil zuerst nicht verstanden. Aber ich denke, ich habe es jetzt verstanden. Sie müssen ein Array verwenden, um die Namen zu speichern. Ich werde aktualisieren. – simbabque

+0

Danke! Also ich warte deine Lösung mit Neugier – Chaoui05