Error-Base
view release on metacpan or search on metacpan
lib/Error/Base.pm view on Meta::CPAN
return $self->{-quiet};
};
sub get_nest {
my $self = shift;
return $self->{-nest};
};
sub get_prepend {
my $self = shift;
return $self->{-prepend};
};
sub get_indent {
my $self = shift;
return $self->{-indent};
};
sub get_all {
my $self = shift;
return $self->{-all};
};
sub get_lines {
my $self = shift;
return $self->{-lines};
};
sub get_frames {
my $self = shift;
return $self->{-frames};
};
## accessors
#----------------------------------------------------------------------------#
#=========# INTERNAL OBJECT METHOD
#
# $out = $self->_late( $in ); # late interpolate
#
# Wrapper method; see Error::Base::Late::_late().
sub _late { return Error::Base::Late::_late(@_) };
##
} #=====# ... Entire package inside bare block, not indented.
#=========# END PACKAGE BLOCK
package Error::Base::Late; # switch package to avoid pseudo-global lexicals
{
#=========# INTERNAL FUNCTION IN FOREIGN PACKAGE
#
# $out = _late( $self, $in ); # late interpolate
#
# Purpose : ____
# Parms : $in : scalar string
# Reads : every key in $self starting with a $, @, or % sigil
# : $self : available as '$self'
# Returns : $out : scalar string
# Writes : ____
# Throws : ____
# See also : ____
#
# I hope this is the worst possible implementation of late().
# Late interpolation is accomplished by multiple immediate interpolations,
# inside and outside of a string eval.
# Non-core PadWalker is not used to derive interpolation context;
# caller is required to pass context inside the $self object.
# To avoid collision and unintended interpolation, I make housekeeping
# variables internal to this routine, package variables.
# These are fully qualified to a "foreign" package; caller cannot
# accidentally access them (although I cannot stop you from doing stupid).
# Some work is done in a bare "setup" block with lexical variables.
# But package variables are used to pass values within the routine,
# from block to block, inside to outside, within and without the eval.
# Quoting is a major concern. Heredocs are used in three places for
# double-quoted interpolation; they may not conflict with each other
# or with any string that may exist within any of:
# - the string to be interpolated, $in
# - values passed in $self against @keys (keys with leading sigils)
# Rather than attempt to exclude all of these from a generic q//,
# I chose heredocs and three long, arbitrary strings.
#
sub _late {
use strict;
use warnings;
no warnings 'uninitialized'; # too many to count
#~ ##### CASE:
#~ ##### @_
# No lexical variables loose in the outer block of the subroutine.
$Error::Base::Late::self = shift;
if ( not ref $Error::Base::Late::self ) {
die 'Error::Base internal error: no $self';
};
$Error::Base::Late::in = shift || undef;
return $Error::Base::Late::in
unless $Error::Base::Late::in =~ /[\$\@%]/; # no sigil, don't bother
# Y0uMaYFiReWHeNReaDYGRiDLeY # quite unlikely to collide
@Error::Base::Late::code = undef; # to be eval-ed
$Error::Base::Late::out = undef; # interpolated
#--------------------------------------------------------------------#
{ # setup block
# Some preamble.
push @Error::Base::Late::code,
q**,
q*#--------------------------------------------------------#*,
q*# START EVAL *,
q**,
q*my $self = $Error::Base::Late::self;*,
q**,
;
# Unpack all appropriate k/v pairs into their own lexical variables...
# Each key includes leading sigil.
my @keys = grep { /^[\$\@%]/ } keys %$Error::Base::Late::self;
return $Error::Base::Late::in # abort if not interpolating today
#~ unless ( @keys or $Error::Base::Late::in =~ /\$self/ );
unless ( @keys );
my $key ; # placeholder includes sigil!
my $val ; # value to be interpolated
my $rt ; # builtin 'ref' returns (unwanted) class of blessed ref
( run in 0.614 second using v1.01-cache-2.11-cpan-39bf76dae61 )