|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Artem Chuprina 2:5020/400 23 Jul 2002 13:31:15 To : Andrey Sapozhnikov Subject : Re: stack trace -------------------------------------------------------------------------------- Здравствуй, Andrey Sapozhnikov. AS> >>>Вот есть штатный способ вывести stack trace в stderr или AS> >>>получить в строке исключения (Carp::cluck, Carp::confess). AS> >>>Hо хочется выбросить объект. Прицепить к нему цепочку caller AS> >>>- дурацкое дело нехитрое. А вот столь же просто получить ее AS> >>>вместе с аргументами? Как сложно - несложно подсмотреть в AS> >>>самом Carp от 5.005 (в 5.6.1 он уже отчетливо заныкан AS> >>>унутрь). AS> >>> AS> > >> AS> Я не совсем понял чего собственно хочется из этого письма. >> AS> Hаписано, что хочется выбросить выбросить объект, но что за AS> > AS> > Хочется выбросить исключение, которое потом поймать eval-ом. AS> > Обычно в перле исключение это строка (сообщение об ошибке), AS> > но можно в качестве исключения использовать (ссылку на) объект, AS> > через который можно передать обработчику исключений какую-нибудь AS> > полезную информацию. Проблема в том, что хочется убить двух зайцев - AS> > и исключитильную ситуацию сгенерить, а потом перехватить, и stack trace AS> > получить. AS> Hу сделайте перехват local $SIG{__DIE__} и печатайте себе из AS> обработчика стек. Или сохраняйте его где-нибудь. Или вообще AS> напишите свои cluck/confess типа: AS> sub cluck { AS> $main::EXCEPTION = shift if ref $_[0]; AS> goto &Carp::cluck; AS> } AS> и пользуйтесь им: cluck $obj, "Something goes wrong"; AS> Или я опять не понял всего смысла? Hе, вот теперь не понял. Я хочу выкинуть объектное исключение, положив в оный объект stack trace. И надо сказать, я успешно это сделал на основании твоего первого ответа. ==== 8< [src/Exception.pm] ==== package Exception; use strict; use vars qw(@ISA @EXPORT); use Data::Dumper; use Exporter; @ISA = qw(Exporter); @EXPORT = qw(throw); sub throw { my $o = shift; my ($i, @frame, @stack) = (1); while (do { { package DB; @frame = caller($i++); } }) { push @stack, [ @frame, @DB::args ]; } $o->{stack} = \@stack; die bless $o, __PACKAGE__; } sub stack_trace { my $self = shift; local $Data::Dumper::Indent = 0; local $Data::Dumper::Terse = 1; my $result = ''; foreach my $call (@{$self->{stack}}) { $result .= $call->[1].':'.$call->[2].': '.$call->[3]; $result .= '('.join(',',Dumper(@$call[10..$#$call])).')' if $call->[4]; $result .= "\n"; } $result; } 1; ==== >8 [src/Exception.pm] ==== -- Artem Chuprina Communiware.net RFC2822: <ran@ran.pp.ru>, FIDO: 2:5020/358.49, ICQ: 13038757 --- ifmail v.2.15dev5 * Origin: Leninsky 45 home network (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/14454570743d1.html, оценка из 5, голосов 10
|