Overriding autogenerated accessors

Overriding Autogenerated Accessors

Problem

You want to override an accessor that Class::DBI automatically created for one of your columns, do some work and then call back into the original Class::DBI code so it can carry on as normal.

Solution 1

As Class::DBI is a Class::Accessor sub class you can use the alias methods that it generates.

e.g. Say you have an email column that you would like to accept Mail::Address objects as well as plain strings. We use an override to convert any such objects to strings so they can be stored in the database.

sub email { my $self = shift; # If passed a Mail::Address convert it to a string. if (@_ and ref $_[0] eq 'Mail::Address') { $_[0] = $_[0]->format; }    # Back to normal Class::DBI return $self->_email_accessor(@_); }

Discussion

For each column (e.g. email) you get the normal accessor and one called _ _accessor (e.g. _email_accessor). If you define your own accessor with the name of a column then Class::Accessor won't generate a method for it but will still install the alias method, so you can call that from your custom accessor. This is much like using SUPER when overriding methods in sub classes.

Solution 2

A variation of the above approach (devised by PerrinHarkins) is to use Class::DBI's accessor_name_for sub to give the column's accessor a name like "email_value" instead of email. Then write your own email accessor that does exactly what you want and calls email_value for the database reads and writes. (*Note:* Solution 1 is going to be cleaner in most circumstances, so try that first. -- PerrinHarkins)

--MarkAddison