Carp-Proxy
view release on metacpan or search on metacpan
lib/Carp/Proxy.pm view on Meta::CPAN
I<$content> is expected to be a string. If I<$content> is the empty
string then no Section is generated and an empty string is returned.
I<$title> is converted into a Section title string using
L<header()|/header>.
I<$content> is split into lines on newline ("\n") characters for
processing. Trailing whitespace is removed. Embedded tabs are converted
to the equivalent number of spaces assuming eight character boundarys.
Indentation corresponding to the sum of
L<header_indent|/header_indent> and
L<body_indent|/body_indent> is added to the beginning of each
line. Lines are joined with platform-appropriate line termination.
Trailing whitespace is removed, the section-title is prepended and a
single blank line is added to the end.
=head2 header
Usage:
<String> $cp->header( $title );
B<header()> produces an introductory line for a Section of paragraphs.
The line is indented from the left margin by
L<header_indent|/header_indent> spaces. The line is formed
using the following template:
<indent>*** <$title> ***
The intent is to provide an introductory heading for Section paragraphs.
*** Description ***
The database server is refusing connections.
If I<$title> is undef then the L<section_title|/section_title>
attribute is used in its place. Passing an empty string (C<''>) for
I<title> causes B<header()> to omit Header generation. In this case an
empty string is returned.
B<header()> is called by the Section creating methods
L<filled_section()|/filled_section> and
L<fixed_section()|/fixed_section>.
Subclass B<Carp::Proxy> and override B<header()> for a different look.
=head2 identifier_presentation
Usage:
<String> $class->identifier_presentation( $name );
The Banner reads better when words in the
L<handler_name|/handler_name> are separated by spaces rather
than underscores (C<_>). Likewise with camelCasedIdentifiers.
Underscores are replaced by single spaces everywhere they occur. Spaces
are inserted everywhere character-case changes from lower to upper, and
upper-case characters are folded to lower-case. The following are example
conversions:
'no_user_credentials' => 'no user credentials'
'nonexistentRecord' => 'nonexistent record'
Sub-class B<Carp::Proxy> and override B<identifier_presentation()> if
you want a different convention.
=head2 import
Usage:
<void> $class->import( <%attrs_by_proxy>);
B<import()> accepts specifications for Proxy construction. Specifications
take the form of a proxyname and a hashref of attribute initializations.
proxyname1 => {
attributeA => initial_valueA,
attributeB => initial_valueB,
...
}
Any number of proxyname, hashref pairs may be specified; a proxy subroutine
will be constructed for each pair.
If there is only one argument it is taken to be a proxyname introducing an
empty hashref. If there are no arguments then it is assumed that the
builder-specified default for the L<proxy_name|/proxy_name> attribute
(C<'fatal'>), should be used for the proxyname and an empty hashref used for
the attribute initializations.
B<import()> probes the callstack to determine the package and filename of
the user code that called B<import()>. B<import()> uses these values to create
a hash containing the attributes L<proxy_filename|/proxy_filename>,
L<proxy_name|/proxy_name> L<proxy_package|/proxy_package> and
L<fq_proxy_name|/fq_proxy_name>. Any supplied attributes are added to the
hash. The builtin handler L<*configuration*|/configuration> returns a
reference to this hash.
=head2 list_handler_packages
Usage:
<list> $cp->list_handler_packages();
B<list_handler_packages()> is sugar that dereferences the
L<handler_pkgs|/handler_pkgs> attribute (an ArrayRef) and
returns the contents.
=head2 list_sections
Usage:
<list> $cp->list_sections();
The L<sections|/sections> attribute is an ArrayRef.
B<list_sections()> is sugar to return all the elements of
L<sections|/sections>.
=head2 new
Usage:
<Carp::Proxy object> $class->new
( arg => harvested $_,
eval_error => harvested $@,
lib/Carp/Proxy.pm view on Meta::CPAN
use Carp::Proxy fatal => { handler_pkgs => [qw( Support Common )]};
You can also sub-class B<Carp::Proxy> and override
B<_build_handler_pkgs()> to return an ArrayRef of the desired packages.
The Proxy always appends a copy of
L<proxy_package|/proxy_package> to
L<handler_pkgs|/handler_pkgs> after object construction.
L<proxy_package|/proxy_package> is the package that issued the
B<use()>, or made the call to L<import()|/import>. In the above example
L<handler_pkgs|/handler_pkgs> becomes:
[qw( Support Common main )]
The subroutine that is the target of the search is influenced by the
setting of L<handler_prefix|/handler_prefix>. When the
L<handler_prefix|/handler_prefix> attribute is undef, the Proxy
builds three templates from L<handler_name|/handler_name>. The
first subroutine that exists is used as the Handler.
<package>::_cp_<handler_name>
<package>::_<handler_name>
<package>::<handler_name>
If L<handler_prefix|/handler_prefix> is not undef then only one
template is tried:
<package>::<handler_prefix><handler_name>
If a Handler subroutine is not found by the template search then a check
is made to see if L<handler_name|/handler_name> matches one of
the B<Carp::Proxy> builtin Handlers. The builtin Handlers are surrounded
by C<'*'> characters since those are guaranteed not to collide with user
Handlers.
*assertion_failure*
*internal_error*
*configuration*
See L<BUILTIN HANDLERS|/BUILTIN-HANDLERS:> for a description of their
functionality.
Finally, if a suitable Handler is not found by any of the above searches
the Proxy concludes that you forgot to define a Handler. In response, the
Proxy attempts to shame you into compliance by throwing an exception of
its own:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Oops << embarrassed developers >>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** Description ***
There was an error. The developers caught the error and
attempted to pass diagnosis off to a handler. Unfortunately
they forgot to define the handler. Now there are two
errors. You should complain!
*** Please contact the maintainer ***
your.name@support.org 555-1212
*** Missing Handler ***
handler_name: no_credentials
handler_pkgs: main
handler_prefix: (undef)
*** Stacktrace ***
fatal called from line 443 of /usr/local/bin/hibs
validate_user called from line 510 of /usr/local/bin/hibs
cmdline called from line 216 of /usr/local/bin/hibs
main called from line 17 of /usr/local/bin/hibs
=head1 BUILTIN HANDLERS
These are handler subroutines that come with B<Carp::Proxy>.
=head2 internal_error
Usage:
<void> fatal '*internal_error*', @strings;
The C<'*internal_error*'> Handler can be used to promote warnings to
errors or to turn miscellaneous B<die()> exceptions to full B<Carp::Proxy>
exceptions. The typical use is to trap B<$SIG{__DIE__}> or
B<$SIG{__WARN__}>.
use English;
$SIG{__DIE__} = sub{
fatal '*internal_error*', @_
if not $EXCEPTIONS_BEING_CAUGHT;
};
A Filled Section is generated from the string interpolation of
I<@strings>. In the above example, the argument is the message that was
passed to B<die()>, like "Illegal division by zero". A
L<contact_maintainer()|/contact_maintainer> Section is also added.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fatal: << internal error >>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** Description ***
Illegal division by zero at ./combine_decks line 27.
*** Please contact the maintainer ***
your.name@support.org 555-1212
*** Stacktrace ***
...
=head2 assertion_failure
Usage:
<void> fatal '*assertion_failure*', $description <, $hashref>;
If a failing assertion is indicative of a programmer fault then the
primary audience for a diagnostic message will be a maintainer rather than
an end user. Maintainers are most often helped by knowledge of the
surrounding state. The builtin Handler B<*assertion_failure*> attempts to
be a generic Handler, useful for transmitting state to maintainers.
Using B<*assertion_failure*> frees the programmer from having to write a
( run in 0.311 second using v1.01-cache-2.11-cpan-2b0bae70ee8 )