1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
#!/usr/bin/env perl use strict; use warnings; my $fmt1 = "%09d %09d %5d %5d"; my $fmt2 = "#%-3d #%-3d %09d"; # User Choice my $fmt = $fmt2; my $f = 2; my $d = { 'a' => 123, 'b' => 456, 'c' => 54321, 'd' => 98765 }; my $e = { 'a' => 789, 'b' => 987 }; sub get_line_1 { my ($dat1) = @_; return sprintf( $fmt, $dat1->{'a'}, $dat1->{'b'}, $dat1->{'c'}, $dat1->{'d'} ); } sub get_line_2 { my ($dat1, $dat2) = @_; return sprintf( $fmt, $dat2->{'a'}, $dat2->{'b'}, $dat1->{'a'} ); } # Fake Code: Ich habe folgendes schon ausprobiert und weiß, dass es nicht # funktioniert, aber ich hatte gehofft, dass eine Lösung in dieser Richtung # existiert: Idealerweise ist es möglich die Argumente für die Formatstrings # vorzuberechnen, das kriege ich aber leider nicht hin: Unten stehender Code # liefert nur: # Useless use of a constant ("$dat1->{'a'}") in void context # Argument "$dat1->{'a'}" isn't numeric in sprintf # # my $arg1 = qw( $dat1->{'a'} $dat1->{'b'} $dat1->{'c'} $dat1->{'d'} ); # my $arg2 = qw( $dat2->{'a'} $dat2->{'b'} $dat1->{'a'} ); # # my $arg = $arg2; # # sub get_line_wunsch { # my ($dat1, $dat2) = @_; # # return sprintf( # $fmt, # $arg # ); # } # # print get_line_wunsch($d, $e), "\n"; if($f == 1) { print get_line_1($d), "\n"; } else { print get_line_2($d, $e), "\n"; }
1 2 3 4 5 6 7 8 9 10 11
my %formats = ( "format name 1" => { "format" => "%02d %02d", "fields" => [ "a", "b" ], }, "format name 2" => { "format" => "%03s %02d", "fields" => [ "c", "d" ], }, );
2020-01-05T10:26:49 rosti
2020-01-05T10:56:04 hlubenow2020-01-05T10:26:49 rosti
Interessantes Modul. Aber wenn man die Resultate der Verarbeitung von Dateien mit >5 Mio. Zeilen speichert ("trading space for time"), könnten erhebliche Datenmengen entstehen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
#!/usr/bin/env perl use strict; use warnings; use 5.016; my $fmt1 = "%09d %09d %5d %5d"; my $fmt2 = "#%-3d #%-3d %09d"; # User Choice my $f = $ARGV[0] // 1; my $d = { 'a' => 123, 'b' => 456, 'c' => 54321, 'd' => 98765 }; my $e = { 'a' => 789, 'b' => 987 }; sub get_line_wunsch_factory { my ($f) = @_; my ($fmt,$arg_extractor); if ($f == 1) { $fmt = $fmt1; $arg_extractor = sub { my ($dat1) = @_; return (@$dat1{qw(a b c d)}); } } elsif ($f == 2) { $fmt = $fmt2; $arg_extractor = sub { my ($dat1, $dat2) = @_; return ($dat2->{'a'},$dat2->{'b'},$dat1->{'a'}); } } else { die "Fuer f = $f habe ich kein Format\n"; } return sub { return sprintf($fmt,&$arg_extractor(@_)); } } my $get_line_wunsch = get_line_wunsch_factory($f); print &$get_line_wunsch($d,$e),"\n";
QuoteAn der Zeile sind zwei Dinge falsch:Code (perl): (dl )my $arg1 = qw( $dat1->{'a'} $dat1->{'b'} $dat1->{'c'} $dat1->{'d'} );
2020-01-05T10:53:02 hlubenowWenn man große Datenmengen zu verarbeiten hat, und es dabei wirklich auf die Zeit ankommt, wird man sich letztlich wohl die Mühe machen müssen, das Programm in C zu schreiben.
2020-01-05T20:32:04 hajNeben XS gibt es auch die Möglichkeit Inline::C oder Inline::CPP (letzteres für C++). Da kannst Du direkt C-Code in die Perl-Module schreiben.
2020-01-05T19:34:33 pinwheelMöglicherweise finde ich ja indirekt den Weg zu Perl zurück, wenn die zukünftige Lib so designed wird, dass man sie über XS (ist nur geraten - ich habe mir gestern noch ein wenig was zum Einbinden von C Code in Perl angesehen und bin auf das Stichwort gestoßen) direkt aus Perl heraus verwenden kann.