use Sub::Name 'subname';
use Module::Find();
use Storable();
+use B qw/svref_2object/;
use namespace::clean;
use base qw/DBIx::Class/;
use warnings 'redefine';
# ensure classes are loaded and attached in inheritance order
- $class->ensure_class_loaded($_) foreach(values %results);
+ for my $res (values %results) {
+ $class->ensure_class_loaded($res);
+ }
my %inh_idx;
my @subclass_last = sort {
=cut
sub source {
- my ($self, $moniker) = @_;
+ my $self = shift;
+
+ $self->throw_exception("source() expects a source name")
+ unless @_;
+
+ my $moniker = shift;
+
my $sreg = $self->source_registrations;
return $sreg->{$moniker} if exists $sreg->{$moniker};
=head2 freeze
-This doesn't actually do anything more than call L<Storable/freeze>, it is just
+This doesn't actually do anything more than call L<Storable/nfreeze>, it is just
provided here for symmetry.
=cut
sub freeze {
- return Storable::freeze($_[1]);
+ return Storable::nfreeze($_[1]);
}
=head2 dclone
$self->class_mappings(\%map);
}
+{
+ my $global_phase_destroy;
+
+ END { $global_phase_destroy++ }
+
+ sub DESTROY {
+ return if $global_phase_destroy;
+
+ my $self = shift;
+ my $srcs = $self->source_registrations;
+
+ for my $moniker (keys %$srcs) {
+ # find first source that is not about to be GCed (someone other than $self
+ # holds a reference to it) and reattach to it, weakening our own link
+ if (ref $srcs->{$moniker} and svref_2object($srcs->{$moniker})->REFCNT > 1) {
+ $srcs->{$moniker}->schema($self);
+ weaken $srcs->{$moniker};
+ last;
+ }
+ }
+ }
+}
+
sub _unregister_source {
my ($self, $moniker) = @_;
my %reg = %{$self->source_registrations};