Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]7054[/thread]

fehler abfangen mit eval

Leser: 4


<< |< 1 2 >| >> 14 Einträge, 2 Seiten
supersucker
 2005-06-17 19:58
#55522 #55522
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
hi zusammen,

ich hab mir einen parser geschrieben, der alle datensätze aus gegebenen dateien einliest.
manche dieser datensätze sind nun fehlerhaft, und genau die möchte ich überspringen, dabei verhält sich aber "eval" nicht so wie ich das erwartet habe.

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
24
25
26
27
28
#!/usr/bin/perl

use warnings;
use strict;

# ein paar hundert zeilen code dazwischen.....

SKIPFRAG: while(.....)
eval {

# extract Primary Structure 1 Letter-Code

$primaryStructureSubStr = substr($primaryStructure1L, $k, $fragmentLength);

# extract quartary structure chain

$quartaryStructureSubStr = substr($quartaryStructureChainS, $k, $fragmentLength);

# create secondary structure substring

$secondaryStructureSubStr = substr($secondaryStructureS, $k, $fragmentLength);

};
if($@) {
print "skipping fragment \n";
$k++;
next SKIPFRAG;
}


wenn ein datensatz fehlerhaft krieg ich bei den "substr"-aufrufen im eval-block haufenweise fehlermeldungen (substr out of range usw, was ja auch ok ist, denn ich weiss das manche datensätze fehlerhaft sind), was ich aber möchte ist, das zum einen keine fehlermeldungen kommen (ich dachte ein eval würde die unterdrücken), zum anderen soll der datensatz übersprungen werden und der nächste datensatz eingelesen werden.
seltsammerweise aber scheint es so, als würde der if-block niemals betreten werden, die print-anweisung

Code: (dl )
print "skipping fragment \n";


im if-block wird nicht auf stdout geschrieben, aber es werden haufenweise exceptions im eval-block geworfen.
ich dachte alle fehler die im eval-block auftauchen werden unterdrückt, bzw. deren ausgabe wird unterdrückt, die variable $@ wird gesetzt und ich kann mich dann zur laufzeit um die fehlerbehandlung kümmern...
ja, aber wie schon gesagt, der if-block scheint nie betreten zu werden....

hab ich bei der fehlerbehandlung mit eval was falsch verstanden?
wenn ja, wie schaffe ich es zum einen die ausgabe der fehler im eval-block zu unterdrücken bzw. zum nächsten datensatz zu springen?

danke im voraus
murphy
 2005-06-17 21:03
#55523 #55523
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Kann es sein, dass in deinem eval-Block nur Warnungen ausgelöst werden, keine Fehler? Jene werden nämlich nicht von eval abgefangen.

Probier doch mal, ein
Code (perl): (dl )
local $SIG{_ _WARN_ _} = sub { die $_[0] };
an den Anfang deines eval-Blockes zu schreiben.
When C++ is your hammer, every problem looks like your thumb.
supersucker
 2005-06-18 01:24
#55524 #55524
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
hey,

vielen dank für den tip! jetzt läuft das genau so wie ich das erwartet hatte, es waren wirklich nur warnungen und keine fehler.

Code: (dl )
local $SIG{_ _WARN_ _} = sub { die $_[0] };


so ganz verstehe ich aber die zeile nicht (also eigentlich versteh ich die zeile überhaupt nicht).
ich sage doch perl in der zeile eigentlich nur das perl bei warnungen sterben soll, aber mir sind die komponenten der zeile im zusammenhang nicht klar.
%SIG {} ist der von perl genutzte hash für interprozesskommunikation oder? und das local sorgt dafür das es nur im eval-block gilt?
betterworld
 2005-06-18 02:57
#55525 #55525
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Du hast murphys Zeile schon genau richtig interpretiert. _ _ WARN _ _ ist kein richtiges Signal wie z. B. INT, sondern einfach nur ein Handler fuer Warnungen, der bei Perl auf dieselbe Weise angegeben wird wie Handler fuer Signale. Siehe vielleicht perldoc perlvar oder perldoc warnings, da muesste das irgendwo drinstehen.

Aber ich muss sagen, dass ich diese Vorgehensweise nicht nur unleserlich finde, sondern auch fehlerträchtig. Denn Warnungen sind nun einmal Warnungen und keine Fehler. Wenn Du Dich nun irgendwo in dem eval-Block vertippst und einen Code erzeugst, der eine andere Warnung hervorruft, wird der eval-Block abgebrochen. Das ist nicht gut.

Ich wuerde eher versuchen, vor dem substr-Aufruf explizit auf die Laenge des Strings zu pruefen. Wenn man es moeglichst kurz schreiben moechte, geht das vielleicht auch mit regulaeren Ausdruecken:
Code: (dl )
my ($teilstring) = m/^.{$k}(.{$teilstringlaenge})/ or die;
(ungetestet)\n\n

<!--EDIT|betterworld|1119049347-->
supersucker
 2005-06-18 21:02
#55526 #55526
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
ich hab schon wieder ein ähnliches problem, nur umgedreht diesmal:


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
24
    undef($@);

eval {

local $SIG{_ _WARN_ _} = sub { die $_[0] };

# extract Primary Structure 1 Letter-Code

$primaryStructureSubStr = substr($primaryStructure1L, $k, $fragmentLength);

# extract quartary structure chain

$quartaryStructureSubStr = substr($quartaryStructureChainS, $k, $fragmentLength);

# create secondary structure substring

$secondaryStructureSubStr = substr($secondaryStructureS, $k, $fragmentLength);

};
if($@) {
print "skipping fragment \n";
$k++;
next SKIPFRAG;
}


das problem ist jetzt, das die if-abfrage IMMER true ergibt, auch wenn im eval-block weder warnungen noch fehler auftauchen.
wollte $@ deshalb mit

Code: (dl )
undef($@);


reseten, aber das scheint auch nichts zu bringen.
ich hab diesen thread gestartet, weil niemals in die if-abfrage gesprungen wurde, jetzt hab ich das problem das immer in die if-abfrage gesprungen wird.........-(

muss ich $@ anders reseten? ich dachte wenn der eval-block keine fehler und warnungen ausgibt wird $@ automatisch auf undefiniert gesetzt.....
pq
 2005-06-19 02:54
#55527 #55527
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
      $@      The Perl syntax error message from the last eval()
              operator.  If $@ is the null string, the last
              eval() parsed and executed correctly (although the
              operations you invoked may have failed in the nor-
              mal fashion).  (Mnemonic: Where was the syntax
              error "at"?)

also einfach nur
if ($@) {
schreiben.
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
supersucker
 2005-06-20 04:38
#55528 #55528
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
danke für die tips, aber das klappt alles nicht, und ich versteh nicht warum......:-((((

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
24
25
26
27
28
#!/usr/bin/perl

use warnings;
use strict;

# ----------- viel code--------------

while(bla) {

eval {

no strict 'subs';

local $SIG{_ _WARN_ _} = sub { die $_[0] };

$primaryStructureSubStr = substr($primaryStructure1L, $k, $fragmentLength);

$quartaryStructureSubStr = substr($quartaryStructureChainS, $k, $fragmentLength);

$secondaryStructureSubStr = substr($secondaryStructureS, $k, $fragmentLength);

};
if($@) {
print "skipping fragment \n";
$k++;
next SKIPFRAG;
}
}


$@ wird einfach immer gesetzt, auch wenn im eval-block weder eine warnung noch ein fehler erzeugt wird.
ich verstehs einfach nicht, ich hab eval schon oft verwendet und so ein problem hatte ich noch nie...

hat jemand ne idee?
bin gerade absolut ratlos woran das liegen kann...
pq
 2005-06-20 15:06
#55529 #55529
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
was steht denn in $@? warum läßt du es dir nicht einfach mal ausgeben?
wenn if ($@) { ausgeführt wird, wird schon was drinstehen.
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
 2005-06-20 15:08
#55530 #55530
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
die leerzeichen zwischen den _ bei _ _WARN_ _ läßt du aber schon weg, oder?
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
supersucker
 2005-06-20 15:34
#55531 #55531
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
ok, jetzt läuft es, das mit den leerzeichen war das problem...
ich hatte das code-segment von murphy einfach reingepastet, da waren die leerzeichen drin...

danke soweit!
<< |< 1 2 >| >> 14 Einträge, 2 Seiten



View all threads created 2005-06-17 19:58.