It is not a "miscellaneous extra" that \%attrs is a parameter to virtually every method in the DBI or that passing \%attrs does a fundamentally different thing than passing $dsn, or $sql or $value.
I was not referring to \%attrs in my comment. Rather, I see those as being fundamentally the same as $dsn or $sql or $value because those are all *method arguments*. It is just positional vs named arguments, but arguments none-the-less.
If you change $dbh->{RaiseError}=1 to $dbh->raise_error(1), what is it you are proposing for DBI->connect( ..., {RaiseError=>1, PrintError=0} )?
In this case, I'm not proposing any change for connect(). Your two examples are not the same, as I see it. The first is a tied-hash interface, and the second is a non-tied hash ref, that is a method argument.
Another way to look at it is that DBI is made up of handles which have the very important property that the behaviour of a handle's methods can be modified by setting its attributes independent of other sorts of parameters passed to the method.
If the kind of functionality you are looking for is to have symetry between
the way you use a hashesque named list notation to set attributes on an existing object (tied interface) vs a new object (method argument), then try these:
DBI->attrs( {RaiseError=>1, PrintError=0} ); $dbh->attrs( {RaiseError=>1, PrintError=0} );
That looks *more* like the connect() syntax than $dbh->{RaiseError}=1 does, and it satisfies the issue of not having a caller access an object's insides directly.
Incidentally, I should point out that I see the conceptual point of a tied variable (hash or otherwise) to act and be used like the normal Perl-built-in, meaning *caller program data storage*. This is different than the way DBI's handles are used, where setting their attributes is more akin to making a "do this" procedure call. Do you see what I am talking about?
-- Darren Duncan