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

Error for Standardlibrary?

Leser: 1


<< >> 3 Einträge, 1 Seite
defun
 2008-08-15 20:51
#113553 #113553
User since
2008-07-18
28 Artikel
BenutzerIn
[default_avatar]
Ich bin in meinen installierten Perl-Modulen zufällig über "Error" gestolpert und war hoch erfreut. Genau so ein Modul wünscht man sich, wenn man eine Zeit lang unter Java programmiert hat und das Exception-Handling als einzig nützliches Feature (von den Features, die Java von Perl übernommen hat, wie gelabelte Schleifen und foreach natürlich mal abgesehen) empfunden hat. Leider entpuppte sich meine Annahme, Error sei ein Standard-Modul, als Fehler. Ich wollte eigentlich ohne CPAN-Module auskommen, um die Installation und Distribution zu vereinfachen, aber so langsam wird mir klar, dass das eine ziemliche Schnapsidee ist, weil ich mich bzw. mein Programm auf lange Sicht damit nur einschränke. Einen Tod muss man halt sterben, und der CPAN-Tod ist für Perl-Programme wohl auf lange Sicht unumgänglich ;)

Wird so ein Error-Handling wirklich so selten benötigt? Ich brauche es zwar auch nicht ständig, aber wenn, dann ist sowas mit Perls Bordmitteln ja wirklich nur umständlich (bzw. nicht schön) zu realisieren. Ist es anzunehmen, dass das Error-Modul seinen Weg in die Standard-Module schafft? Gibt es gar etwas ähnliches bereits in der Standardbibliothek?

In einem großen Projekt, in dem das "Werfen" von Fehlern eine ganz natürliche Entscheidung ist, habe ich bisher folgende Lösung verwendet:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sub otto
{
   ...
   return new BlubbError(...) if $fehlerausloeser;
   ...
   return 0, $result;
}
...
sub uwe
{
   ...
   my($status, $result) = otto(...);
   return $status if $status; # Fehler weiterreichen
   ...
}
...
# Irgendwo, wo mich Fehler interessieren:
my $status = uwe(...);
tuWasDamit($status) if $status;

Aber jetzt, da ich das Error-Modul mal gesehen habe, schäme ich mich fast für diese primitive Lösung, weil sie eigentlich nur ein Workaround ist, um ein anderes Verhalten zu erreichen.

Vielleicht wäre es klüger, einen schlichten Mechanismus mit eval und die zu basteln, wie es ja auch in "Error" gemacht wird:
Code (perl): (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
29
30
31
32
33
34
35
36
37
package ErrorHandling;
our $RecordedError;
sub error
{
   $RecordedError = [@_];
   die;
}
sub catch(&)
{
   my $code = shift;
   eval {$code->()};
   return $RecordedError;
}
package Whatever;
sub otto
{
   ...
   error(...) if $fehlerausloeser;
   ...
   return $result;
}
...
sub uwe
{
   ...
   my $result = otto(...);
   ...
}
...
# Irgendwo, wo mich Fehler interessieren:
my $status = catch
{
   ...
   uwe(...);
   ...
};
tuWasDamit($status) if $status;

Natürlich würde das nur funktionieren, wenn die catches nicht geschachtelt werden. Um ehrlich zu sein bin ich gerade zu verwirrt, um eine einfache Lösung für geschachtelte catches aus dem Ärmel zu schütteln.

So, ich hoffe dieses kleine Brainstorming war jetzt nicht zu frustrierend zu lesen. ;)
renee
 2008-08-16 17:56
#113572 #113572
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Für Perl 5.12 ist ein besseres Exceptionhandling in Diskussion.

Was meinst Du mit "geschachtelten catches"?
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/
defun
 2008-08-17 01:31
#113594 #113594
User since
2008-07-18
28 Artikel
BenutzerIn
[default_avatar]
Ich meine sowas wie
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
my $status = catch
{
   my $result;
   my $ottoStatus = catch {$result = otto()};
   doSomethingWith($ottoStatus) if $ottoStatus;
   error("Wrong number of otto\n") unless $result == 4;
   doAnything();
};
doSomethingWith($status) if $status;


Inzwischen hat sich der Knoten in meinem Kopf gelöst und mir ist klar, dass man das gewünschte Verhalten mit einem Stack erreicht:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package ErrorHandling;
our @RecordedErrors;
sub error
{
   $RecordedErrors[-1] = [@_];
   die;
}
sub catch(&)
{
   my $code = shift;
   push @RecordedErrors, 0;
   eval {$code->()};
   return pop @RecordedErrors;
}
<< >> 3 Einträge, 1 Seite



View all threads created 2008-08-15 20:51.