Wednesday July 17, 2002
12:49 PM
local woes
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)?
local (Score:2)
local() changes something for its current scope _until_ it exits that scope _at runtime_. It's a runtime, temporary effect.
You're expected a compile time effect, basically.
I agree that the docs aren't so hot, though.
duh (Score:1)
I need a vacation.
call me crazy, but... (Score:1)
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