标签: carp

Carp/Croak,Cluck/Confess和详细选项之间有什么区别?

我没有那么多地使用鲤鱼,因为我一般都是自己动手.但是,本着与Core模块保持一致的精神,我现在正在使用它.然而,似乎它几乎不比警告/死亡好.

此外,咯咯/忏悔/冗长甚至做什么?我已经运行了这个简短的脚本来了解输出的样子(因为Carp文档没有这样做).它在任何运行中看起来都完全相同(除了随机字符串).

  #!/usr/bin/perl

  package Warning;

  sub warning {
    warn "warn";
  }

  package CWarn;
  use Carp qw(carp cluck);

  sub cwarn {
    int(rand(2)) ? carp "carp" : cluck "cluck";
  }

  package Fatal;
  use Carp qw(confess croak);

  sub fatal {
    int(rand(2)) ? confess "confess" : croak "croak";
  }

  package Loop;

  use v5.10;

  sub loop {
    say '=' x 80;
    Warning::warning();
    CWarn::cwarn();
    loop() unless ($c++ > 10);
    Fatal::fatal();
  }

  package main;

  Warning::warning();
  CWarn::cwarn();
  Loop::loop();
Run Code Online (Sandbox Code Playgroud)

更新:使用包名更新了脚本,它确实有所作为.但是,就记录信息而言,Carp似乎仍然非常基础,并且它不支持Web输出.我想我会看看其他像CGI :: Carp,Log :: Output和Log :: Log4Perl.

error-handling perl carp

52
推荐指数
2
解决办法
3万
查看次数

我为什么要在Perl中使用Carp而不是警告?

人们不断向我提供鲤鱼的例子,而不是警告.为什么?是什么让鲤鱼比警告更好?

perl module carp

26
推荐指数
4
解决办法
9527
查看次数

如何在Perl应用程序中用'confess'替换所有'die'?

我正在使用大型Perl应用程序,并且每次调用"die"时都希望获得堆栈跟踪.我知道Carp模块,但我不想用'confess'搜索/替换'die'的每个实例.另外,我想要Perl模块或Perl解释器本身的错误的完整堆栈跟踪,显然我不能改变使用Carp的那些.

那么,有没有办法在运行时修改'die'函数,使其表现得像'confess'?或者,是否有一个Perl解释器设置会从'die'中抛出完整的堆栈跟踪?

perl carp

17
推荐指数
2
解决办法
3423
查看次数

perl 5's carp 的 raku 模拟是什么?

默认情况下,Raku 的 "die" 报告 "die" 所在的行号,如果你想要调用上下文的行号,ala "carp" with perl 5 怎么办?

exception carp die raku

10
推荐指数
1
解决办法
191
查看次数

Perl的Carp模块是否有C等价物?

在我用C完成的一些项目中,我喜欢使用以下类似于Perl的warn和die子例程的宏:

#include <stdio.h>
#include <stdlib.h>

#define warn(...) \
    fprintf(stderr, __VA_ARGS__); \
    fprintf(stderr, " at %s line %d\n", __FILE__, __LINE__)

#define die(...) \
    warn(__VA_ARGS__); \
    exit(0xFF)
Run Code Online (Sandbox Code Playgroud)

有没有像Perl的鲤鱼,呱呱,咯咯和鲤鱼的忏悔子程序那样存在的东西?我想从用户角度报告错误.

如果没有,我知道glibc中有backtrace()和backtrace_symbols()函数,它们与-rdynamic gcc选项一起可以为我提供函数名和代码地址的回溯.但我想要一些更好的东西; 可以访问调用堆栈中的文件,行和函数名称,如Perl的调用者子例程.我可以编写自己的libcarp用于我的c程序.

编辑:2009-10-19

我正在考虑在basename(argv [0])上创建使用gdb的东西,然后处理堆栈跟踪以生成我想要的不同类型的消息.它应该能够确定我是不是在可调试的可执行文件中,还是没有gdb的系统,在这种情况下,carp和cluck会变成警告并且Craok和confess将会死亡.

我之前从未使用过这样的gdb(我只在开始时使用我的程序运行它,而不是在它已经运行时).但我发现glib中的一些函数(g_on_error_stack_trace和stack_trace)看起来非常接近我想要做的事情:它使用参数basename(argv [0])和进程id分配gdb进程,然后写入其stdin(已被重定向到管道)命令"backtrace"后跟"退出".然后它从结果中读取并按照它喜欢的方式解析它.这几乎就是我需要做的.

c perl carp die backtrace

7
推荐指数
1
解决办法
464
查看次数

如何用Carp将呼叫标记为"不安全"?

我有同样的问题,因为某些原因无法在Carp :: croak()中禁用堆栈跟踪.因为堆栈中的每个调用都被认为是"安全的",所以每次croak()打印出完整的堆栈跟踪.我想为某些电话禁用它.

这是一个例子:

use Carp;

sub this_may_fail {
  # Some code...
  croak "This call failed!";
}

sub regular_code {
  this_may_fail();
}

regular_code();
Run Code Online (Sandbox Code Playgroud)

两个子程序都在同一个包中,因此this_may_fail会自动标记为安全.有没有办法告诉Carp this_may_fail应该被视为不安全?

perl carp

6
推荐指数
1
解决办法
105
查看次数

如果每个人都使用的调试代码的机制覆盖了它,您如何捕获有缺陷的 sig die 处理程序?

假设您使用 cpan(或其他外部)模块,就像我们在这里虚构的那样 Stupid::CPAN::Module::OfSatan

package Stupid::CPAN::Module::OfSatan {
  BEGIN { $SIG{__DIE__} = sub { print STDERR "ERROR"; exit; }; }
}
Run Code Online (Sandbox Code Playgroud)

现在在你的代码中你有一些非常无辜的东西,

package main {
  eval { die 42 };
}
Run Code Online (Sandbox Code Playgroud)

这将触发您的错误信号处理程序。你会想知道那个有问题的信号处理程序是在哪里定义的,所以你会做一些合乎逻辑的事情,比如插入一个Carp::Always

package main {
  use Carp::Always;
  eval { die 42 };
}
Run Code Online (Sandbox Code Playgroud)

Carp::Always然后将覆盖有问题的信号处理程序,您的代码将神奇地工作。您如何调试引入错误信号处理程序的代码?

perl signals eval carp die

6
推荐指数
1
解决办法
155
查看次数

为什么不能证明接受-MCarp = verbose?

我运行了这个测试脚本:

use strict;
use warnings;
use Test::More tests => 3;
use Carp;

ok(1<2);
pass();
fail();
croak "example";
Run Code Online (Sandbox Code Playgroud)

使用命令行prove -MCarp=verbose -v foo.pl,并得到以下错误:

Subroutine App::Prove::verbose redefined at /opt/ActivePerl-5.12/lib/App/Prove.pm line 407
        App::Prove::_load_extension('App::Prove=HASH(0x683718)', 'Carp=verbose') called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 419
        App::Prove::_load_extensions('App::Prove=HASH(0x683718)', 'ARRAY(0x683850)') called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 481
        App::Prove::run('App::Prove=HASH(0x683718)') called at /opt/ActivePerl-5.12/bin/prove line 11
Undefined subroutine &Carp::verbose called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 484.
Run Code Online (Sandbox Code Playgroud)

如果我使用它运行它perl -MCarp=verbose foo.pl没有问题.什么导致prove拒绝啰嗦鲤鱼?如果croak没有全局替换croak,我怎样才能从我的测试中获得完整的callstack confess

testing perl carp

4
推荐指数
1
解决办法
368
查看次数

从Moose BUILD方法中呱呱叫

如果BUILD方法失败,我希望我的班级爆炸.但是,如果我croak用来处理错误,则会报告错误Class/MOP/Method.pm,而不是调用者的代码.(也就是说,实例化对象的调用者.)IOW,croak在调用树上没有吠叫.

看吧:

package Test;

use Moose;
use Carp 'croak';

sub BUILD {
    croak 'u r dum';
}

1;
Run Code Online (Sandbox Code Playgroud)

实例化Test结果:

u r dum at /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Class/MOP/Method.pm line 125
Run Code Online (Sandbox Code Playgroud)

Carp.pm应该注意一个名为变量的包变量@CARP_NOT来知道要避免哪些包,但它似乎只关注列表中的一个项目.例如,如果我将其添加到我的Test.pm:

our @CARP_NOT = ( 'Class::MOP::Method' );
Run Code Online (Sandbox Code Playgroud)

然后结果是:

u r dum at /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Moose/Object.pm line 59
Run Code Online (Sandbox Code Playgroud)

所以我也应该将添加到数组中,对吧?

our @CARP_NOT = ( 'Class::MOP::Method', 'Moose::Object'  );
Run Code Online (Sandbox Code Playgroud)

然后结果仍然是:

u r dum at /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Moose/Object.pm line 59
Run Code Online (Sandbox Code Playgroud)

Moose::Object 似乎没有受到影响.

我现在一直在反对这个问题,现在似乎无法弄清楚是什么弄乱了它.

谢谢.

perl moose carp

4
推荐指数
1
解决办法
571
查看次数

如何编写不在 eval 块中触发的 SIG{__DIE__} 处理程序?

根据perldoc -f die, 哪些文件$SIG{__DIE__}

尽管此功能只能在您的程序退出之前运行,但目前并非如此:$SIG{__DIE__}当前甚至在 evaled 块/字符串中也调用了钩子!如果希望钩子在这种情况下什么都不做,请将其die @_ if $^S;作为处理程序的第一行(参见$^Sperlvar)。因为这会促进远距离奇怪的动作,所以这种违反直觉的行为可能会在未来的版本中得到修复。

所以让我们采用一个基本的信号处理程序,它将触发eval { die 42 }

package Stupid::Insanity {
  BEGIN { $SIG{__DIE__} = sub { print STDERR "ERROR"; exit; }; }
}
Run Code Online (Sandbox Code Playgroud)

我们使这安全

package Stupid::Insanity {
  BEGIN { $SIG{__DIE__} = sub { return if $^S; print STDERR "ERROR"; exit; }; }
}
Run Code Online (Sandbox Code Playgroud)

现在这不会用触发eval { die 42 },但是当相同的代码位于BEGIN {}像这样的块中时它会触发

BEGIN { eval { die 42 …
Run Code Online (Sandbox Code Playgroud)

perl signals eval carp die

3
推荐指数
1
解决办法
237
查看次数

压倒呱呱叫咯咯从Perl的鲤鱼模块中忏悔

我知道如何覆盖内置的函数perl,我已经覆盖die warn say,因为print并且printf无法覆盖我已将它绑定到我的日志框架的句柄.

覆盖示例warn:

BEGIN{ *CORE::GLOBAL::warn = sub {
                my ($package, $filename, $line, $subroutine) = caller;
                untie *STDERR;
                my $message;
                foreach my $arg (@_) {
                        $message = $message.$arg;
                }
                print STDERR $message;
                tie *STDERR, __PACKAGE__, (*STDERR);
                logmessage("warn",$message,$filename, $line);
                return;
        }
}
Run Code Online (Sandbox Code Playgroud)

现在我可以croak cluck confess carpcarp模块中覆盖Perl吗?

perl overriding carp die

2
推荐指数
1
解决办法
113
查看次数

Carp :: carp在Perl中做了什么?

任何人都可以carp用Perl代码示例解释子程序吗?

perl carp

0
推荐指数
1
解决办法
743
查看次数

标签 统计

carp ×12

perl ×11

die ×5

eval ×2

signals ×2

backtrace ×1

c ×1

error-handling ×1

exception ×1

module ×1

moose ×1

overriding ×1

raku ×1

testing ×1