Schrift
[thread]11113[/thread]

pm-Modul: DATA-Teil und 1; inkompatibel?



<< |< 1 2 >| >> 16 Einträge, 2 Seiten
RalphFFM
 2008-01-09 11:08
#104521 #104521
User since
2006-11-16
258 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo, wie ichs gewohnt bin möchte eigentlich gerne jedes Modul (*.pm) mit einer 1; abschließen. Nun habe ich zum ersten Mal ein Modul mit einem DATA-Teil. Wenn ich aber hier vor dem DATA-Teil meine 1; hinschreibe, dann bekomme ich eine Fehlermeldung die über eine Uninitialized Value in Multiplication meckert.

Schematisch sieht das so aus:
Code: (dl )
1
2
3
4
5
6
7
8
9
sub ... {
while (<DATA>) { ... Multiplikationen mit den DATA-Daten, etc ... }
}

1;

__DATA__
1.234;2.345;3.456
4.567;5.678;7.890


Kann es sein, daß das while (<DATA>) wenn es am Dateiende angekommen ist "nach oben" zurückspringt und bei den Zeilen zwischen Sub und DATA-Teil weiter ausliest??? Dort steht dann die 1; Die erste meiner Sub-Variablen wird vielleicht mit dem Wert 1 gefüllt und die anderen bleiben uninitialized?

Ohne die 1; funktioniert alles wunderbar ohne jede Warnmeldung!!!
pq
 2008-01-09 11:42
#104527 #104527
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
RalphFFM+2008-01-09 10:08:52--
Kann es sein, daß das while (<DATA>) wenn es am Dateiende angekommen ist "nach oben" zurückspringt

du bist derjenige, der das am besten beantworten kann!
woher sollen wir das wissen, wenn du nicht mal den code postest, in dem die warnung
vorkommt?
perl kann man debuggen!
wenn du eine warnung bekommst, dann schreib in die zeile, in der du einen uninitialisierten
wert vermutest, ein print-statement rein, mit dem du die aktuelle zeile ausgibst.
dein code ist doch keine blackbox.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
pq
 2008-01-09 11:57
#104528 #104528
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ cat Foo.pm 
package Foo;

sub data {
while (<DATA>) {
warn __PACKAGE__." <$_>\n";
}
}

1;

__DATA__
23
42
99
$ perl -wle'use Foo;
Foo::data()'
Foo <23
>
Foo <42
>
Foo <99
>

also hier klappt das ausgezeichnet.
This is perl, v5.8.8 built for i486-linux-gnu-thread-multi
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
RalphFFM
 2008-01-09 20:37
#104554 #104554
User since
2006-11-16
258 Artikel
BenutzerIn
[Homepage] [default_avatar]
Habe den Fehler gefunden, es lag an etwas anderem. Hier der Kern des Problems:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/perl
while (<DATA>){
print "erster Durchlauf: $_";
}
seek (DATA,0,0);
while (<DATA>){
print "zweiter Durchlauf: $_";
}

__DATA__
1
2
3
4
5

Ich hatte angenommen, daß mein seek-Befehl an den Anfang des DATA-Blocks zurückspringt. Tja, den Gefallen tut er mir leider nicht, stattdessen springt er an den Dateianfang:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ralph@erde:/tmp$ ./test.pl
erster Durchlauf: 1
erster Durchlauf: 2
erster Durchlauf: 3
erster Durchlauf: 4
erster Durchlauf: 5
erster Durchlauf:
zweiter Durchlauf: #!/usr/bin/perl
zweiter Durchlauf: while (<DATA>){
zweiter Durchlauf: print "erster Durchlauf: $_";
zweiter Durchlauf: }
zweiter Durchlauf: seek (DATA,0,0);
zweiter Durchlauf: while (<DATA>){
zweiter Durchlauf: print "zweiter Durchlauf: $_";
zweiter Durchlauf: }
zweiter Durchlauf:
zweiter Durchlauf: __DATA__
zweiter Durchlauf: 1
zweiter Durchlauf: 2
zweiter Durchlauf: 3
zweiter Durchlauf: 4
zweiter Durchlauf: 5
zweiter Durchlauf:


Mist! Da die 5 DATA-Zeilen hier im Muster in Realität knapp 9000 Zeilen und 800 KB groß sind, wollte ich das nicht alles in ein Array oder Hash nehmen. Hat wer von Euch hierzu eine Idee?
pq
 2008-01-09 21:54
#104556 #104556
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
aha! das ist doch schon konkreter.
merk dir die position am anfang mit tell()
also
Code (perl): (dl )
1
2
3
4
5
use Fcntl qw/ :seek /;
my $pos = tell DATA;
# erster durchlauf
seek DATA, $pos, SEEK_SET; # immer die konstanten benutzen!
# zweiter durchlauf
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
RalphFFM
 2008-01-09 22:17
#104561 #104561
User since
2006-11-16
258 Artikel
BenutzerIn
[Homepage] [default_avatar]
Ja, das sieht recht elegant aus. Geschickter noch als Parsen. Gute Idee, Danke!

Werde noch etwas nachdenken, gefühlsmäßig kommt mir das Verhalten von while(<DATA>) einerseits und von seek andererseits betreffend ihrer Startpunkte immer noch inkonsistent vor.
pq
 2008-01-09 23:12
#104563 #104563
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
also DATA ist ein filehandle auf das script selbst, der am anfang an der stelle im script steht, wo
__DATA__ (oder auch __END__) steht. ansonsten ist alles konsistent =)
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
sid burn
 2008-01-11 01:04
#104600 #104600
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
bis auf das
Code: (dl )
while (<DATA>) { ... }

anstatt
Code: (dl )
while (my $line = <DATA>) { ... }

verwendet wird.


Ansonsten wenn du Statische Daten hast würde ich diese direkt in einer variable Packen und diese dann am anfang des Modules initialisieren. Anstatt womöglich jedesmal die Daten Zeile für Zeile durchzugehen und die Daten wahrscheinlich noch aufzusplitten etc.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
RalphFFM
 2008-01-11 10:27
#104609 #104609
User since
2006-11-16
258 Artikel
BenutzerIn
[Homepage] [default_avatar]
@sid burn: Ja. Nur mit der Variablenlösung müßten wieder alle Daten im
Arbeitsspeicher vorgehalten werden was ich eigentlich vermeiden wollte.

Andererseits zeigte mir ein erster Test, daß die Performance mit der DATA-Lösung
nicht so prickelnd ist, nach 8 Sekunden wirft das Modul endlich die Ergebnisse aus.

Ich werde noch herausfinden, ob die lange Zeit beim Durchnudeln der DATA-Daten
verbraten wird oder beim Rechnen mit den Daten. Falls ersteres der Fall ist, wäre
die Variablenlösung sicherlich am schnellsten.

Ich weiß aber auch, daß voreilige Performanceoptimierung m.W. i.A. ein Fehler ist
solange man die Perl-Compilierungs-Interna nicht so gut wie seine Hosentasche
kennt. (-> Frage: Seht ihr das eigentlich genauso?)
Daher werde ich wohl erstmal mit den anderen Programmteilen weitermachen.
(Kann also sein, daß ich das letztlich anders lösen muß.)
renee
 2008-01-11 11:30
#104610 #104610
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
RalphFFM+2008-01-11 09:27:27--
Ich weiß aber auch, daß voreilige Performanceoptimierung m.W. i.A. ein Fehler ist
solange man die Perl-Compilierungs-Interna nicht so gut wie seine Hosentasche
kennt. (-> Frage: Seht ihr das eigentlich genauso?)
Daher werde ich wohl erstmal mit den anderen Programmteilen weitermachen.
(Kann also sein, daß ich das letztlich anders lösen muß.)


Bevor man optimiert, sollte man erstmal schauen, wo überhaupt der Flaschenhals ist und nicht einfach "irgendwo" optimieren...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
<< |< 1 2 >| >> 16 Einträge, 2 Seiten



View all threads created 2008-01-09 11:08.