Class:...uilder(3pm)
β¨ Class::Meta::AccessorBuilder β¨
okay so bestie, gather round, because today we're talking about Class::Meta::AccessorBuilder β it's a Perl module, it lives in the User Contributed Perl Documentation section of the manual (3pm, iykyk), and it is literally the thing that builds your accessors for you. The whole page is right here, no skips, no cap. π«Ά
πΈ NAME πΈ
Class::Meta::AccessorBuilder β Perl style accessor generation π
π SYNOPSIS π
package MyApp::TypeDef;
use strict;
use Class::Meta::Type;
use IO::Socket;
my $type = Class::Meta::Type->add(
key => 'io_socket',
builder => 'default',
desc => 'IO::Socket object',
name => 'IO::Socket Object'
);
π DESCRIPTION π
So this module is the default accessor builder for Class::Meta. It builds standard, regular-degular Perl-style accessors, and it does it flawlessly. For example? An attribute named io_socket gets exactly one accessor method, and that method is also called io_socket. Iconic. Simple. Slay. β¨
π¦ Accessors π¦
Class::Meta::AccessorBuilder creates three different flavors of accessor: read-only, write-only, and read/write. Which one you get depends entirely on the value of the authz attribute on the Class::Meta::Attribute object the accessor is being made for. Vibe check your authz, basically.
For example, if authz is Class::Meta::RDWR, then the method can both read and write the attribute:
my $value = $obj->io_socket;
$obj->io_socket($value);
If authz is Class::Meta::READ, then the method is not allowed to change the attribute's value:
my $value = $obj->io_socket;
$obj->io_socket($value); # Has no effect.
And finally, if authz is Class::Meta::WRITE, the method won't hand back the attribute's value at all. And honestly? The original author is right there with us on this one: why anyone would want this is beyond me, but it's provided for the sake of completeness. π
$obj->io_socket($value);
my $value = $obj->io_socket; # Always returns undef.
π Data Type Validation π
Class::Meta::AccessorBuilder uses all of the validation checks that get passed to it to validate new values before it assigns them to an attribute. It also checks whether the attribute is required, and if it is, it adds a check to make sure its value is never undef. Periodt. β
It does not currently check that private and protected methods are only used in their appropriate contexts β but it might do so in a future release. So, like, watch this space. π
π Class Attributes π
If the context attribute of the attribute object you're building accessors for is Class::Meta::CLASS, then Class::Meta::AccessorBuilder will build accessors for a class attribute instead of an object attribute. And yes bestie, that means exactly what you think it means: change the value of that class attribute anywhere β via an object, via the class name, or via an inherited class name or object β and the value changes everywhere. One change, all the vibes. π
For example, for a class attribute count, you can expect the following to work:
MyApp::Custom->count(10);
my $count = MyApp::Custom->count; # Returns 10.
my $obj = MyApp::Custom->new;
$count = $obj->count; # Returns 10.
$obj->count(22);
$count = $obj->count; # Returns 22.
my $count = MyApp::Custom->count; # Returns 22.
MyApp::Custom->count(35);
$count = $obj->count; # Returns 35.
my $count = MyApp::Custom->count; # Returns 35.
Currently, class attribute accessors are not designed to be inheritable the way Class::Data::Inheritable does it, though that might change in a future release. For now, the expectation is that this simple approach covers the vast majority of circumstances. Lowkey fine. π«Ά
Note: Class attribute accessors will not work accurately in multiprocess environments like mod_perl. If you change a class attribute's value in one process, it will not be changed in any of the others. Furthermore, class attributes are not currently shared across threads. So if you're using Class::Meta class attributes in a multi-threaded environment (such as iThreads in Perl 5.8.0 and later), changes to a class attribute in one thread will not be reflected in other threads. fr fr, this one bites.
π§ Private and Protected Attributes π§
Any attributes whose view attribute is set to Class::Meta::Private or Class::Meta::Protected get additional validation installed to make sure they're truly private or truly protected. And yes, that includes when they're set via parameters passed to constructors generated by Class::Meta. The validation works by checking the caller of the accessors, and throwing an exception when:
- the caller isn't the class that owns the attribute β that's the private case, or
- the caller doesn't inherit from the class that owns the attribute β that's the protected case.
As an implementation note π, this validation is performed for parameters passed to constructors created by Class::Meta by ignoring and looking for the first caller that isn't Class::Meta::Constructor:
my $caller = caller;
# Circumvent generated constructors.
for (my $i = 1; $caller eq 'Class::Meta::Constructor'; $i++) {
$caller = caller($i);
}
This works because Class::Meta::Constructor installs the closures that become constructors, and so when those closures call accessors to set new values for attributes, the caller is Class::Meta::Constructor. By walking up the stack until we find another package, we correctly check what context is setting attribute values via a constructor, rather than the constructor method itself being the context. Big brain behavior. π§ β¨
This is a bit of a hack, but since Perl uses call stacks for checking security in this way, it's the best that could be come up with. Other suggestions welcome. Or see Class::Meta::Type to create your own accessor generation code. π
π INTERFACE π
The following functions must be implemented by any Class::Meta accessor generation module. Like, non-negotiable. π
π Functions π
build_attr_get
my $code = Class::Meta::AccessorBuilder::build_attr_get();
This function is called by Class::Meta::Type::make_attr_get() and returns a code reference that can be used by the get() method of Class::Meta::Attribute to return the value stored for that attribute for the object passed to the code reference. π«΄
build_attr_set
my $code = Class::Meta::AccessorBuilder::build_attr_set();
This function is called by Class::Meta::Type::make_attr_set() and returns a code reference that can be used by the set() method of Class::Meta::Attribute to set the value stored for that attribute for the object passed to the code reference. π«³
build
Class::Meta::AccessorBuilder::build($pkg, $attribute, $create, @checks);
This method is called by the build() method of Class::Meta::Type, and it does the actual work of generating the accessors for an attribute object. The arguments passed to it are:
$pkgβ the name of the class to which the accessors will be added.$attributeβ theClass::Meta::Attributeobject that specifies the attribute for which the accessors will be created.$createβ the value of thecreateattribute of theClass::Meta::Attributeobject, which determines what accessors, if any, are to be created.@checksβ a list of code references that validate the value of an attribute. These get used in the set accessor (mutator) to validate new attribute values.
π SUPPORT π
This module is stored in an open GitHub repository <http://github.com/theory/class-meta/>. Feel free to fork and contribute! Go off bestie, the repo is right there. π΄
Please file bug reports via GitHub Issues <http://github.com/theory/class-meta/issues/> or by sending mail to bug-Class-Meta@rt.cpan.org <mailto:bug-Class-Meta@rt.cpan.org>.
β AUTHOR β
David E. Wheeler <david@justatheory.com> π
π SEE ALSO π
Class::Metaβ this class contains most of the documentation you need to get started withClass::Meta.Class::Meta::AccessorBuilder::Affordanceβ this module generates affordance style accessors (e.g.,get_foo()andset_foo().Class::Meta::AccessorBuilder::SemiAffordanceβ this module generates semi-affordance style accessors (e.g.,foo()andset_foo().Class::Meta::Typeβ this class manages the creation of data types.Class::Meta::Attributeβ this class managesClass::Metaclass attributes, most of which will have generated accessors.
π COPYRIGHT AND LICENSE π
Copyright (c) 2002-2011, David E. Wheeler. Some Rights Reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
and that's the whole page, bestie π«Ά this one came from the perl v5.34.0 docs, dated 2022-06-11, and yeah β it'sClass:...uilder(3pm), theUser Contributed Perl Documentationone. go forth and build accessors, you absolute icon πβ¨
π¦ where this page comes from
- debian bookworm: libclass-meta-perl 0.66-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libclass-meta-perl 0.66-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libclass-meta-perl 0.66-3 Β· 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