Simplify dbh_do invocation, and only alias @_ when needed
Peter Rabbitson [Mon, 7 Jan 2013 18:45:05 +0000 (13:45 -0500)]
lib/DBIx/Class/Storage.pm
lib/DBIx/Class/Storage/DBI.pm

index 6e17e9e..6b88d28 100644 (file)
@@ -180,7 +180,10 @@ sub txn_do {
   DBIx::Class::Storage::BlockRunner->new(
     storage => $self,
     run_code => $coderef,
-    run_args => \@_, # take a ref instead of a copy, to preserve coderef @_ aliasing semantics
+    run_args => @_
+      ? \@_   # take a ref instead of a copy, to preserve @_ aliasing
+      : []    # semantics within the coderef, but only if needed
+    ,         # (pseudoforking doesn't like this trick much)
     wrap_txn => 1,
     retry_handler => sub { ! ( $_[0]->retried_count or $_[0]->storage->connected ) },
   )->run;
index a9a8381..19bc2bc 100644 (file)
@@ -794,11 +794,25 @@ sub dbh_do {
   return $self->$run_target($self->_get_dbh, @_)
     if $self->{_in_do_block} or $self->transaction_depth;
 
-  my $args = \@_;
+  my $cref = (ref $run_target eq 'CODE')
+    ? $run_target
+    : $self->can($run_target) || $self->throw_exception(sprintf (
+      'Can\'t locate object method "%s" via package "%s"',
+      $run_target,
+      (ref $self || $self),
+    ))
+  ;
+
+  # take a ref instead of a copy, to preserve @_ aliasing
+  # semantics within the coderef, but only if needed
+  # (pseudoforking doesn't like this trick much)
+  my $args = @_ ? \@_ : [];
+  unshift @$args, $self, $self->_get_dbh;
 
   DBIx::Class::Storage::BlockRunner->new(
     storage => $self,
-    run_code => sub { $self->$run_target ($self->_get_dbh, @$args ) },
+    run_code => $cref,
+    run_args => $args,
     wrap_txn => 0,
     retry_handler => sub { ! ( $_[0]->retried_count or $_[0]->storage->connected ) },
   )->run;