Carp::Object(3pm)

๐Ÿ“ฆ
version 1.02 ยท 2 versions
, in ubuntu resolute, ubuntu stonking

โœจ Carp::Object โœจ

okay bestie, buckle up, we're doing Carp::Object from User Contributed Perl Documentation and honestly? it's giving glow-up. ๐Ÿ’…


๐Ÿ’– NAME ๐Ÿ’–

Carp::Object โ€” a replacement for Carp or Carp::Clan, object-oriented. periodt.


๐ŸŒธ SYNOPSIS ๐ŸŒธ

๐ŸŽ€ Object-oriented API

use Carp::Object ();
my $carper = Carp::Object->new(%options);

# warn of error (from the perspective of caller)
$carper->carp("this is very wrong") if some_bad_condition();

# die of error (from the perspective of caller)
$carper->croak("that's a dead end") if some_deadly_condition();

# warn with full stacktrace
$carper->cluck("this is very wrong");

# die with full stacktrace
$carper->confess("that's a dead end");

๐Ÿฆ‹ Functional API

use Carp::Object qw/:all/;            # many other import options are available, see below
our %CARP_OBJECT_CONSTRUCTOR = (...); # optional opportunity to tune the carping behaviour
our @CARP_NOT = (...);                # optional opportunity to exclude packages from stack traces

# warn of error (from the perspective of caller)
carp "this is very wrong" if some_bad_condition();

# die of error (from the perspective of caller)
croak "that's a dead end" if some_deadly_condition();

# full stacktrace
cluck "this is very wrong";
confess "that's a dead end";

# temporary change some parameters, like for example the "clan" of modules to ignore
{ local %CARP_OBJECT_CONSTRUCTOR = (clan => qw(^(Foo|Bar)));
   croak "wrong call to Foo->.. or to Bar->.." if $something_is_wrong; }

๐Ÿ‘‘ DESCRIPTION ๐Ÿ‘‘

So this is an object-oriented alternative to croak in Carp or croak in Carp::Clan, for reporting errors in modules from the perspective of the caller instead of snitching on the internal implementation line where the error actually happens. no cap.

Carp or Carp::Clan were designed long ago, back when Perl had no support yet for object-oriented programming. so they only have a functional API that is not very well suited for extensions. tragic, honestly. The present module attempts to mimic the same behaviour, but with an object-oriented implementation that offers more tuning options, and also supports errors raised as Exception objects. slay.

Unlike Carp or Carp::Clan, where the presentation of stack frames is hard-coded, here it is delegated to Devel::StackTrace. This means that clients can also take advantage of options in Devel::StackTrace to tune the output โ€” or even replace it by another class. main character energy fr fr.

Clients can choose between the object-oriented API, presented in the next chapter, or a traditional functional API compatible with Carp or Carp::Clan, presented in the following chapter. pick your fighter. ๐Ÿซถ

DISCLAIMER: this module is very young and not battle-proofed yet. Despite many efforts to make it behave as close as possible to the original Carp, there might be some edge cases where it is not strictly equivalent. If you encounter such situations, please open an issue at <https://github.com/damil/Carp-Object/issues>. bestie please file the bug, we're begging ๐Ÿ™ˆ

๐Ÿ’œ METHODS ๐Ÿ’œ

๐Ÿ’… new

use Carp::Object (); # '()' to avoid importing any symbols
my $carper = Carp::Object->new(%options);

This is the constructor for a "carper" object. Options are :

  • verbose โ€” if true, a 'croak' method call is treated as a 'confess', and a 'carp' is treated as a 'cluck'. yes it just says more words. ๐Ÿ’€
  • stacktrace_class โ€” The class to be used for inspecting stack traces. Default is Devel::StackTrace.
  • clan โ€” A regexp for identifying packages that should be skipped in stack traces, like in Carp::Clan. This option internally computes a "frame_filter" and therefore is incompatible with the "frame_filter" option. pick one, you can't have both. ๐Ÿ™…
  • display_frame โ€” A reference to a subroutine for computing a textual representation of a stack frame. The default is _default_display_frame, which is a light wrapper on top of "as_string" in Devel::StackTrace::Frame, with improved representation of method calls. The given subroutine will receive three arguments :
    1. a reference to a Devel::StackTrace::Frame instance
    2. a boolean flag telling if this is the first stack frame in the list (because the display algorithm is usually different for the first stack frame).
    3. A hashref of optional parameters. Currently there is only one option "max_arg_length", discribed in "as_string(\%p)" in Devel::StackTrace.
  • display_frame_param โ€” The optional hashref to be supplied as third parameter to the "display_frame" subroutine.
  • ignore_class โ€” an arrayref of classes that will be passed to Devel::StackTrace; any class that belongs to or inherits from that list will be ignored in stack traces. "Carp::Object" will automatically add itself to the list supplied by the client. humble of it. ๐Ÿ’…

In addition to these options, the constructor also accepts all options to "new" in Devel::StackTrace, like for example "ignore_package", "skip_frames", "frame_filter", "indent", etc. the whole menu, bestie. ๐Ÿ“


๐Ÿ’€ croak

Die of error, from the perspective of the caller.

๐Ÿ”ฅ carp

Warn of error, from the perspective of the caller.

๐Ÿ˜ญ confess

Die of error, with full stack backtrace.

๐ŸŒˆ cluck

Warn of error, with full stack backtrace.

โญ msg

my $msg = $carper->msg($errstr, $n_frames);

Build the message to be used for dieing or warning. $errstr is the initial error message; it may be a plain string or an exception object with a stringification method. $n_frames is the number of stack frames to display (usually 1); if undefined, the whole stack trace is displayed.


๐Ÿงš FUNCTIONAL API: THE IMPORT() METHOD ๐Ÿงš

use Carp::Object;                # no import list => defaults to (':carp');
# or
use Carp::Object @import_list;

When using this functional API, subroutines equivalent to their corresponding object-oriented methods are exported into the caller's symbol table: the caller can then call "carp", "croak", etc. like with the venerable Carp module. nostalgic core fr. ๐Ÿฅน

๐ŸŒธ Import list

The import list accepts the following items :

  • "carp", "croak", "confess" and/or "cluck" โ€” Individual import of specific routines.
  • ":carp" โ€” Import group equivalent to the list "carp", "croak", "confess".
  • ":all" โ€” Import group equivalent to the list "carp", "croak", "confess", "cluck".
  • "\%options" โ€” A hashref within the import list is interpreted as a collection of importing options, in the spirit of Sub::Exporter or Exporter::Tiny. Admitted options are :
    • "-as"
use Carp::Object carp => {-as => 'complain'}, croak => {-as => 'explode'};

Local name for the last imported function. glow-up name, honestly. โœจ

  • "-prefix"
use Carp::Object qw/carp croak/, {-prefix => 'CO_'};
...
CO_croak "aargh";

Names of imported functions will be prefixed by this string.

  • "-suffix"
use Carp::Object qw/carp croak/, {-suffix => '_CO'};
...
croak_CO "ouch";

Names of imported functions will be suffixed by this string.

  • "-constructor_args"
use Carp::Object qw/carp croak/, {-constructor_args => {indent => 0}};

The given hashref will be passed to "new" in Carp::Object at each call to an imported function.

  • "-reexport"
use Carp::Object -reexport => qw/carp croak/;

Imported symbols will be reexported into the caller of the caller ! This is useful when several modules from a same family share a common carping module. See DBIx::DataModel::Carp for an example (actually, this was the initial motivation for working on "Carp::Object"(). โ€” yes the parentheses are just like that in the original, iconic. ๐Ÿ‘‘

  • regexp
use Carp::Object qw(^(MyClan::|FriendlyOther::));

If the import item "looks like a regexp", it is interpreted as syntactic sugar for use Carp::Object {-constructor_args => {clan => ..}}, in order to be compatible with the API of Carp::Clan.

The import item "looks like a regexp" if it starts with a '^' character, or contains a '|' or a '('.

๐Ÿ’œ Global variables

When using the functional API, customization of "Carp::Object" can be done indirectly through global variables in the calling package. Such variables can be localized in inner blocks if some specific behaviour is needed. localize responsibly bestie. ๐Ÿซถ

  • %CARP_OBJECT_CONSTRUCTOR
{ local %CARP_OBJECT_CONSTRUCTOR = (indent => 0);
  confess "I'm a great sinner"; # for this call, stack frames will not be indented
}

The content of this hash will be passed to "new" in Carp::Object at each call to an imported function.

  • @CARP_NOT

The content of this array will be passed as "ignore_package" argument to to "new" in Carp::Object at each call to an imported function. (yes, "to to", we're keeping it, it's part of the lore ๐Ÿ’–)

  • $Carp::Verbose

if true, a 'croak' method call is treated as a 'confess', and a 'carp' is treated as a 'cluck'.


๐Ÿ”ฎ INTERNAL SUBROUTINES ๐Ÿ”ฎ

๐ŸŒˆ _default_display_frame

This is the internal routine for displaying a stack frame.

It calls "as_string" in Devel::StackTrace::Frame for doing most of the work. An additional feature is that the presentation string is rewritten for frames that "look like a method call" : instead of "Foobar::method('Foobar=...', @other_args)", we write "Foobar=...->method(@other_args)", so that method calls become apparent within the stack trace. the way that transformation ate, honestly. ๐Ÿ”ฅ

A frame "looks like a method call" if the first argument to the routine is a string identical to the class, or reference blessed into that class.


๐ŸŽ€ AUTHOR ๐ŸŽ€

Laurent Dami, <dami at cpan.org> โ€” legend behavior. ๐Ÿซถ


Copyright 2024 by Laurent Dami.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


and that's the whole page bestie!! ๐Ÿ’… written up for perl v5.40.0, dated 2024-10-06, and living at Carp::Object(3pm) โ€” go forth and croak responsibly, mwah ๐ŸŽ€โœจ

๐Ÿ“ฆ where this page comes from