so today I was trying to pass a database handle into a constructor, alter the handle, then pass the altered handle around in my object without affecting the caller's handle. basically, the equivalent of this:
my $dbh = DBI->connect("dbi:Oracle:HELM", 'user', 'pass',
{RaiseError => 1, AutoCommit => 0, PrintError => 0})
or die $DBI::errstr;
my $obj = Foo->new($dbh);
package Foo;
sub new {
my ($class, $dbh) = @_;
local $dbh->{RaiseError} = 0;
local $dbh->{AutoCommit} = 1;
return bless { _dbh => $dbh }, $class;
}
well, the net result is that my object's $dbh
looses its custom settings once new()
exits.
after reading the entry for local
in perlsub
, I'm not entirely convinced that this should work the way I want. However, what I want to do seems perfectly legitimate.
so, is this a bug or a feature of local
(or perhaps, and more likely, something wrong with my perl brain)?
It seems to me that you could get around this with a blessed closure that would hold onto the dbh. An autoload method would dereference the closure, and pass it the method name you wanted (to call against the dbh), and any arguments you need to pass it. And the closure would then be something like:
sub {
my ($method, @args) = @_;
local $dbh->{RaiseError} = 0;
local $dbh->{AutoCommit} = 1;
return $dbh->$method( @args );
}
Does that sound like it would work?