accessors(3pm)
β¨ accessors β¨
okay bestie, so this is the accessors page from the User Contributed Perl Documentation (section 3pm, Perl modules, iykyk) π
and it's genuinely one of the cutest little pragmas out there. here's the whole thing, no skips, no cap.
π NAME π
accessors β create accessor methods in caller's package. that's it. that's the whole job. she's simple like that π
πΈ SYNOPSIS πΈ
package Foo;
use accessors qw( foo bar baz );
my $obj = bless {}, 'Foo';
# generates chaining accessors
# that you can set like this:
$obj->foo( 'hello ' )
->bar( 'world' )
->baz( "!\n" );
# you get the values by passing no params:
print $obj->foo, $obj->bar, $obj->baz;
look at that chain π it's giving fluent API main character energy and you didn't even have to write a single sub yourself.
π¦ DESCRIPTION π¦
so the accessors pragma lets you create simple accessors at compile-time. not runtime, not "whenever you feel like it" β compile-time, periodt β¨
this saves you from writing them by hand, which lowkey always ends in cut-n-paste errors and a whole mess of duplicated code. it can also help you reduce the ammount of unwanted direct-variable access that creeps into your codebase when you're feeling lazy. (yes, that's the original's spelling of "ammount", we're keeping it exactly as-is bestie, no edits π)
and lowkey? accessors was designed with laziness in mind. the founder of this module understood the assignment π
method-chaining accessors are generated by default. but heads up: you can still use accessors::chained directly for reasons of backwards compatibility, if that's your vibe.
and if method chaining isn't your thing and you want accessors that always return the current value, go see accessors::classic. different flavor, same energy π
π GENERATED METHODS π
accessors will generate methods that return the current object on set:
sub foo {
my $self = shift;
if (@_) { $self->{-foo} = shift; return $self; }
else { return $self->{-foo}; }
}
see how it returns $self when you're setting? that's the trick. this way they can be chained together and you get the whole $obj->foo(...)->bar(...)->baz(...) slay π
π Why prepend the dash?
the dash (-) is prepended to the property name for a few reasons:
- interoperability with
Error. - to make it difficult to accidentally access the property directly, ala:
use accessors qw( foo );
$obj->{foo}; # prevents this by mistake
$obj->foo; # when you probably meant this
(this might sound woolly, but it's easy enough to do).
- syntactic sugar (this is woolly :).
bestie, you shouldn't care too much about how the property is stored anyway. if you do care, you're likely trying to do something special β and honestly you should really consider writing the accessors out long hand. or it's simply a matter of preference, in which case you can use accessors::classic, or sub-class this module. either way, options! π
π₯ PERFORMANCE π₯
there is little-to-no performace hit when using generated accessors. in fact there is usually a performance gain. (again: that's the original's spelling of "performace", we do not touch the source text, we respect the source text π«Ά)
- typically 10-30% faster than hard-coded accessors (like the above example).
- typically 1-15% slower than optimized accessors (less readable).
- typically a small performance hit at startup (accessors are created at compile-time).
- uses the same anonymous sub to reduce memory consumption (sometimes by 80%).
see the benchmark tests included with this distribution for more details β receipts exist, go look π
π MOTIVATION π
the main difference between the accessors pragma and other accessor generators is simplicity.
- interface
use accessors qw( ... ) is as easy as it gets. literally one line. that's the whole onboarding.
- a pragma
it fits in nicely with the base pragma:
use base qw( Some::Class );
use accessors qw( foo bar baz );
and accessors get created at compile-time. cute, tidy, done.
- no bells and whistles
the module is extensible instead. minimal queen behavior π
π§ SUB-CLASSING π§
if you prefer a different style of accessor, or you need to do something more complicated, there's nothing to stop you from sub-classing. it should be pretty easy, fr fr.
look through accessors::classic, accessors::ro, and accessors::rw to see how it's done. go peek, take notes, steal the vibe π
π CAVEATS π
classes using blessed scalarrefs, arrayrefs, etc. are not supported β for sake of simplicity. only hashrefs are supported.
that's the deal, bestie. no exceptions, no secret workaround listed here. hashrefs only. periodt.
π THANKS π
thanks to Michael G. Schwern for indirectly inspiring this module, and for his feedback & suggestions. icon behavior.
also to Paul Makepeace and David Wright for showing me faster accessors, to chocolateboy for his contributions, to the CPAN Testers for their bug reports, and to James Duncan and people on London.pm for their feedback. y'all ate π
π AUTHOR π
Steve Purkis <spurkis@cpan.org>
π SEE ALSO π
accessors::classic, accessors::chained
similar and related modules:
base, fields, Class::Accessor, Class::Struct, Class::Methodmaker, Class::Generate, Class::Class, Class::Tangram, Object::Tiny
aaaand that's the whole page bestie, every option, every default, every caveat, nothing skipped π«Ά this was perl v5.36.0, dated 2022-10-13, accessors(3pm) β go chain some accessors and slay π
β¨π
π¦ where this page comes from
- ubuntu noble: libaccessors-perl 1.01-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libaccessors-perl 1.01-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libaccessors-perl 1.01-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms