Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

geoff (2013)

geoff
  reversethis-{gro ... om} {ta} {ffoeg}
http://www.modperlcookbook.org/

see http://www.modperlcookbook.org/~geoff/ [modperlcookbook.org] for personal information, links to presentations, GPG key, and so on.

Journal of geoff (2013)

Wednesday July 17, 2002
12:49 PM

local woes

[ #6423 ]
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)?
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • It's working exactly as documented.

    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.

    I need a vacation.
  • 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