Codex

Class::Accessor

Section: User Contributed Perl Documentation (3pm)

Updated: 2009-09-15

Index?action=index Return to Main Contents


NAME

SYNOPSIS

DESCRIPTION

This module automagically generates accessors/mutators for your class.

Most of the time, writing accessors is an exercise in cutting and pasting. You usually wind up with a series of methods like this:

One for each piece of data in your object. While some will be unique, doing value checks and special storage tricks, most will simply be exercises in repetition. Not only is it Bad Style to have a bunch of repetitious code, but it's also simply not lazy, which is the real tragedy.

If you make your module a subclass of Class::Accessor and declare your accessor fields with mk_accessors() then you'll find yourself with a set of automatically generated accessors which can even be customized!

The basic set up is very simple:

Done. Foo now has simple far(), bar() and car() accessors defined.

Alternatively, if you want to follow Damian's best practice guidelines you can use:

Note: you must call before calling .

Moose-like

By popular demand we now have a simple Moose-like interface. You can now do:

Currently only the attribute is supported.

CONSTRUCTOR

Class::Accessor provides a basic constructor, . It generates a hash-based object and can be called as either a class method or an object method.

new

It takes an optional hash which is used to initialize the object (handy if you use read-only accessors). The fields of the hash correspond to the names of your accessors, so...
however can contain anything, new() will shove them all into your object.

MAKING ACCESSORS

follow_best_practice

In Damian's Perl Best Practices book he recommends separate get and set methods with the prefix set_ and get_ to make it explicit what you intend to do. If you want to create those accessor methods instead of the default ones, call:

before you call any of the accessor-making methods.

accessor_name_for / mutator_name_for

You may have your own crazy ideas for the names of the accessors, so you can make those happen by overriding and in your subclass. (I copied that idea from Class::DBI.)

mk_accessors

This creates accessor/mutator methods for each named field given in . Foreach field in it will generate two accessors. One called ``field()' and the other called ``_field_accessor()'. For example:

See ``Overriding autogenerated accessors'' in CAVEATS AND TRICKS for details.

mk_ro_accessors

Same as mk_accessors() except it will generate read-only accessors (ie. true accessors). If you attempt to set a value with these accessors it will throw an exception. It only uses get() and not set().

mk_wo_accessors

Same as mk_accessors() except it will generate write-only accessors (ie. mutators). If you attempt to read a value with these accessors it will throw an exception. It only uses set() and not get().

NOTE I'm not entirely sure why this is useful, but I'm sure someone will need it. If you've found a use, let me know. Right now it's here for orthoginality and because it's easy to implement.

Moose!

If you prefer a Moose-like interface to create accessors, you can use by importing this module like this:

or

Then you can declare accessors like this:

Currently only the attribute is supported. And our also supports the ``wo'' value to make a write-only accessor.
If you are using the Moose-like interface then you should use the rather than tweaking your directly. Basically, replace

with

DETAILS

An accessor generated by Class::Accessor looks something like this:

Very simple. All it does is determine if you're wanting to set a value or get a value and calls the appropriate method. Class::Accessor provides default get() and set() methods which your class can override. They're detailed later.

Modifying the behavior of the accessor

Rather than actually modifying the accessor itself, it is much more sensible to simply override the two key methods which the accessor calls. Namely set() and get().

If you -really- want to, you can override make_accessor().

set

set() defines how generally one stores data in the object.

override this method to change how data is stored by your accessors.

get

get() defines how data is retreived from your objects.

override this method to change how it is retreived.

make_accessor

Generates a subroutine reference which acts as an accessor for the given . It calls get() and set().

If you wish to change the behavior of your accessors, try overriding get() and set() before you start mucking with make_accessor().

make_ro_accessor

Generates a subroutine refrence which acts as a read-only accessor for the given . It only calls get().

Override get() to change the behavior of your accessors.

make_wo_accessor

Generates a subroutine refrence which acts as a write-only accessor (mutator) for the given . It only calls set().

Override set() to change the behavior of your accessors.

EXCEPTIONS

If something goes wrong Class::Accessor will warn or die by calling Carp::carp or Carp::croak. If you don't like this you can override _carp() and _croak() in your subclass and do whatever else you want.

EFFICIENCY

Class::Accessor does not employ an autoloader, thus it is much faster than you'd think. Its generated methods incur no special penalty over ones you'd write yourself.

Class::Accessor::Fast is faster than methods written by an average programmer (where ``average'' is based on Schwern's example code).

Class::Accessor is slower than average, but more flexible.

Class::Accessor::Faster is even faster than Class::Accessor::Fast. It uses an array internally, not a hash. This could be a good or bad feature depending on your point of view.

Direct hash access is, of course, much faster than all of these, but it provides no encapsulation.

Of course, it's not as simple as saying ``Class::Accessor is slower than average''. These are benchmarks for a simple accessor. If your accessors do any sort of complicated work (such as talking to a database or writing to a file) the time spent doing that work will quickly swamp the time spend just calling the accessor. In that case, Class::Accessor and the ones you write will be roughly the same speed.

EXAMPLES

Here's an example of generating an accessor for every public field of your class.

Here's a simple example of altering the behavior of your accessors.

CAVEATS AND TRICKS

Class::Accessor has to do some internal wackiness to get its job done quickly and efficiently. Because of this, there's a few tricks and traps one must know about.

Hey, nothing's perfect.

Don't make a field called DESTROY

This is bad. Since DESTROY is a magical method it would be bad for us to define an accessor using that name. Class::Accessor will carp if you try to use it with a field named ``DESTROY''.

Overriding autogenerated accessors

You may want to override the autogenerated accessor with your own, yet have your custom accessor call the default one. For instance, maybe you want to have an accessor which checks its input. Normally, one would expect this to work:

There's a subtle problem in the last example, and it's in this line:

If we look at how Foo was defined, it called mk_accessors() which stuck email() right into Foo's namespace. There *is* no SUPER::email() to delegate to! Two ways around this... first is to make a ``pure'' base class for Foo. This pure class will generate the accessors and provide the necessary super class for Foo to use:

And now Foo::email() can override the generated Pure::Organic::Foo::email() and use it as SUPER::email().

This is probably the most obvious solution to everyone but me. Instead, what first made sense to me was for mk_accessors() to define an alias of email(), _email_accessor(). Using this solution, Foo::email() would be written with:

instead of the expected SUPER::email().

AUTHORS

Copyright 2009 Marty Pauley <[email protected]>

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. That means either (a) the GNU General Public License or (b) the Artistic License.

ORIGINAL AUTHOR

Michael G Schwern <[email protected]>

THANKS

Liz and RUZ for performance tweaks.

Tels, for his big feature request/bug report.

Various presenters at YAPC::Asia 2009 for criticising the non-Moose interface.

SEE ALSO

See Class::Accessor::Fast and Class::Accessor::Faster if speed is more important than flexibility.

These are some modules which do similar things in different ways Class::Struct, Class::Methodmaker, Class::Generate, Class::Class, Class::Contract, Moose, Mouse

See Class::DBI for an example of this module in use.


Index

NAME

SYNOPSIS

DESCRIPTION

Moose-like

CONSTRUCTOR

new

MAKING ACCESSORS

follow_best_practice

accessor_name_for / mutator_name_for

mk_accessors

mk_ro_accessors

mk_wo_accessors

Moose!

DETAILS

Modifying the behavior of the accessor

set

get

make_accessor

make_ro_accessor

make_wo_accessor

EXCEPTIONS

EFFICIENCY

EXAMPLES

CAVEATS AND TRICKS

Don't make a field called DESTROY

Overriding autogenerated accessors

AUTHORS

ORIGINAL AUTHOR

THANKS

SEE ALSO