Hi Tim,

> I'd be happy to allow "local_", "_", and perhaps "x_" to be used as
> 'private use' prefixes that would never be registered to a driver.

So to put this into an example, to make sure I understand correctly,
if I had a function I wanted to make available automatically via
install_method() -- say db::query_cache_report(), I'd name it with one
of the above, and people could then automatically say:

    $dbh->_query_cache_report()      # or
    $dbh->local_query_cache_report() # or
    $dbh->x_query_cache_report()

I'm not 100% sure that I like any of those options, for a variety
of reasons:

1) '_' is commonly used to denote a private method. If install_method()
    suddenly started registering methods starting with an underscore
    prefix, that could expose a lot of stuff that shouldn't really 
    be exposed. That may not be such a huge deal, considering Perl's
    OO implementation of "private" methods and functions is essentially
    a bit in the documentation asking people to be respectful and play
    nice, but since DBI has added an extra hoop to jump through (via
    the func() method) to access the private methods, I don't really
    want to expose more than I really choose to.

2) 'x_' is kind of meaningless, as far as prefixes go, and is completely
    arbitrary.

3) 'local_' is not so bad, but I feel like it could limit the potential
    namespace of methods -- it's a word which has definite meanings,
    in a variety of contexts. For example, when I see 'local_', I
    automatically wonder if there is a 'remote_' counterpart method.
    
4) There are several places in DBI::DBD that stress naming conventions,
    and choosing a prefix for private class data, etc. After doing that,
    and choosing a prefix of 'pts_', I find it odd to name methods I
    want to expose to the user with 'x_' or 'local_'.
    
5) As a user of the driver, it goes against everything I'd expect, in
    terms of naming, too. If I use, say Oracle, and am using
    DBD::Oracle, then I know any extra methods available start with a
    leading 'ora_' prefix. Consequently, I'd find it odd, when using 
    this custom driver, to have to use a prefix of 'x_' or 'local_'
    for those extra methods, when 'pts_' is much more logical 
    (particularly since the driver is DBD::PTSProxy).

What if, rather than simply blocking off an arbitrary prefix to DBD::
developers, there were a mechanism to allow us to specify what our 
prefix is? One possible method, for example, is to simply declare a 
specific variable in the DBD::Driver package:

    package DBD::PTSProxy;

    use vars qw($prefix);
    $prefix = 'pts_';

The install_method() function would then need some minor modifications:

    my $reg_info = do { 
        no strict 'refs';
        $dbd_prefix_registry->{$prefix} || ${"DBD::${subtype}::db::prefix"}
    }

That feels like a hack. A better option could be to add a
DBI::register_prefix() function:

    sub register_prefix {
        my ($prefix) = @_;

        my ($caller_pkg) = caller;

        Carp::croak("invalid prefix registration location '$caller_pkg'")
            unless $caller_pkg =~ m/^DBD::(\w+)$/;
        my $driver = $1;

        Carp::croak("invalid prefix '$prefix'")
            unless $prefix =~ m/^[A-Za-z]\w*_$/;

        Carp::croak("prefix '$prefix' is assigned to distributed driver") 
            if exists $dbd_prefix_registry->{$prefix};

        $dbd_prefix_registry->{$prefix} = { class => $caller_pkg };
    }

Then, in the driver, I can write:

    package DBD::PTSProxy;

    DBI::register_prefix('pts_');

    # ...

The benefit of doing it this way is that users of the driver don't have
to relearn the rule that extra functions are named as ${prefix}function,
except in the cases where it isn't. The user writes:

    $dbh->pts_query_cache_report()

The downside, of course, is the danger of a prefix collision with
a database driver which gets registered officially in DBI at a later
date. I don't think this is really a big issue, since it appears 
(according to a quick grep of DBI.pm, anyway) that the registry is
only used in install_method(), and if the prefix already exists, I
can just delete the call to register_prefix().

Cheers,
Ammon

-- 
Ammon Riley
Senior Pipeline Programmer
Rhythm & Hues
[EMAIL PROTECTED]

Reply via email to