X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2F_Util.pm;h=933aa79ae0d5c4cd1114f81890b3e62db2f28db6;hb=e85eb407cd475abef6c489dfd36b4866785e00be;hp=358a3aa7e61a5eca04b3a7efc33a645f2f698ad9;hpb=08a8d8f1b8a69ea29bcceb9f399214943a34905c;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/_Util.pm b/lib/DBIx/Class/_Util.pm index 358a3aa..933aa79 100644 --- a/lib/DBIx/Class/_Util.pm +++ b/lib/DBIx/Class/_Util.pm @@ -1,6 +1,8 @@ package # hide from PAUSE DBIx::Class::_Util; +use DBIx::Class::StartupCheck; # load es early as we can, usually a noop + use warnings; use strict; @@ -52,6 +54,24 @@ BEGIN { require mro; constant->import( OLD_MRO => 0 ); } + + # Both of these are no longer used for anything. However bring + # them back after they were purged in 08a8d8f1, as there appear + # to be outfits with *COPY PASTED* pieces of lib/DBIx/Class/Storage/* + # in their production codebases. There is no point in breaking these + # if whatever they used actually continues to work + my $warned; + my $sigh = sub { + + require Carp; + my $cluck = "The @{[ (caller(1))[3] ]} constant is no more - adjust your code" . Carp::longmess(); + + warn $cluck unless $warned->{$cluck}++; + + 0; + }; + sub DBICTEST () { &$sigh } + sub PEEPEENESS () { &$sigh } } # FIXME - this is not supposed to be here @@ -62,8 +82,8 @@ use B (); use Carp 'croak'; use Storable 'nfreeze'; use Scalar::Util qw(weaken blessed reftype refaddr); -use List::Util qw(first); -use Sub::Quote qw(qsub quote_sub); +use Sub::Quote qw(qsub); +use Sub::Name (); # Already correctly prototyped: perlbrew exec perl -MStorable -e 'warn prototype \&Storable::dclone' BEGIN { *deep_clone = \&Storable::dclone } @@ -72,16 +92,55 @@ use base 'Exporter'; our @EXPORT_OK = qw( sigwarn_silencer modver_gt_or_eq modver_gt_or_eq_and_lt fail_on_internal_wantarray fail_on_internal_call - refdesc refcount hrefaddr + refdesc refcount hrefaddr set_subname scope_guard detected_reinvoked_destructor is_exception dbic_internal_try - quote_sub qsub perlstring serialize deep_clone + quote_sub qsub perlstring serialize deep_clone dump_value parent_dir mkdir_p UNRESOLVABLE_CONDITION ); use constant UNRESOLVABLE_CONDITION => \ '1 = 0'; +BEGIN { + Sub::Quote->VERSION(2.002); +} +# Override forcing no_defer, and adding naming consistency checks +sub quote_sub { + Carp::confess( "Anonymous quoting not supported by the DBIC sub_quote override - supply a sub name" ) if + @_ < 2 + or + ! defined $_[1] + or + length ref $_[1] + ; + + Carp::confess( "The DBIC sub_quote override expects sub name '$_[0]' to be fully qualified" ) + unless $_[0] =~ /::/; + + Carp::confess( "The DBIC sub_quote override expects the sub name '$_[0]' to match the supplied 'package' argument" ) if + $_[3] + and + defined $_[3]->{package} + and + index( $_[0], $_[3]->{package} ) != 0 + ; + + my @caller = caller(0); + my $sq_opts = { + package => $caller[0], + hints => $caller[8], + warning_bits => $caller[9], + hintshash => $caller[10], + %{ $_[3] || {} }, + + # explicitly forced for everything + no_defer => 1, + }; + + my $cref = Sub::Quote::quote_sub( $_[0], $_[1], $_[2]||{}, $sq_opts ); +} + sub sigwarn_silencer ($) { my $pattern = shift; @@ -116,11 +175,57 @@ sub refcount ($) { B::svref_2object($_[0])->REFCNT; } +# FIXME In another life switch this to a polyfill like the one in namespace::clean +sub set_subname ($$) { + + # fully qualify name + splice @_, 0, 1, caller(0) . "::$_[0]" + if $_[0] !~ /::|'/; + + &Sub::Name::subname; +} + sub serialize ($) { local $Storable::canonical = 1; nfreeze($_[0]); } +my $dd_obj; +sub dump_value ($) { + local $Data::Dumper::Indent = 1 + unless defined $Data::Dumper::Indent; + + my $dump_str = ( + $dd_obj + ||= + do { + require Data::Dumper; + my $d = Data::Dumper->new([]) + ->Purity(0) + ->Pad('') + ->Useqq(1) + ->Terse(1) + ->Freezer('') + ->Quotekeys(0) + ->Bless('bless') + ->Pair(' => ') + ->Sortkeys(1) + ->Deparse(1) + ; + + $d->Sparseseen(1) if modver_gt_or_eq ( + 'Data::Dumper', '2.136' + ); + + $d; + } + )->Values([$_[0]])->Dump; + + $dd_obj->Reset->Values([]); + + $dump_str; +} + sub scope_guard (&) { croak 'Calling scope_guard() in void context makes no sense' if ! defined wantarray; @@ -161,6 +266,7 @@ sub is_exception ($) { my ($not_blank, $suberror); { + local $SIG{__DIE__} if $SIG{__DIE__}; local $@; eval { # The ne() here is deliberate - a plain length($e), or worse "$e" ne @@ -270,9 +376,7 @@ sub is_exception ($) { unless $callstack_state->{in_internal_try}; # always unset - someone may have snuck it in - local $SIG{__DIE__} - if $SIG{__DIE__}; - + local $SIG{__DIE__} if $SIG{__DIE__}; if( $wantarray ) { @ret = $try_cref->(); @@ -309,10 +413,13 @@ sub is_exception ($) { my $destruction_registry = {}; sub CLONE { - $destruction_registry = { map - { defined $_ ? ( refaddr($_) => $_ ) : () } - values %$destruction_registry - }; + %$destruction_registry = map { + (defined $_) + ? ( refaddr($_) => $_ ) + : () + } values %$destruction_registry; + + weaken($_) for values %$destruction_registry; # Dummy NEXTSTATE ensuring the all temporaries on the stack are garbage # collected before leaving this scope. Depending on the code above, this @@ -383,8 +490,8 @@ sub modver_gt_or_eq ($$) { local $SIG{__WARN__} = sigwarn_silencer( qr/\Qisn't numeric in subroutine entry/ ) if SPURIOUS_VERSION_CHECK_WARNINGS; + local $SIG{__DIE__} if $SIG{__DIE__}; local $@; - local $SIG{__DIE__}; eval { $mod->VERSION($ver) } ? 1 : 0; }; @@ -498,8 +605,8 @@ sub mkdir_p ($) { ), 'with_stacktrace'); } - my $mark = []; - weaken ( $list_ctx_ok_stack_marker = $mark ); + weaken( $list_ctx_ok_stack_marker = my $mark = [] ); + $mark; } } @@ -511,7 +618,7 @@ sub fail_on_internal_call { $fr = [ CORE::caller(1) ]; $argdesc = ref $DB::args[0] ? DBIx::Class::_Util::refdesc($DB::args[0]) - : undef + : ( $DB::args[0] . '' ) ; }; @@ -523,7 +630,7 @@ sub fail_on_internal_call { $fr->[1] !~ /\b(?:CDBICompat|ResultSetProxy)\b/ # no point touching there ) { DBIx::Class::Exception->throw( sprintf ( - "Illegal internal call of indirect proxy-method %s() with argument %s: examine the last lines of the proxy method deparse below to determine what to call directly instead at %s on line %d\n\n%s\n\n Stacktrace starts", + "Illegal internal call of indirect proxy-method %s() with argument '%s': examine the last lines of the proxy method deparse below to determine what to call directly instead at %s on line %d\n\n%s\n\n Stacktrace starts", $fr->[3], $argdesc, @{$fr}[1,2], ( $fr->[6] || do { require B::Deparse; no strict 'refs';