NAME

Class::More - A fast, lightweight class builder for Perl

VERSION

Version v0.1.1

SYNOPSIS

package My::Class;
use Class::More;

# Define attributes
has 'name' => ( required => 1 );
has 'age'  => ( default => 0 );
has 'tags' => ( default => sub { [] } );

# Set up inheritance
extends 'My::Parent';

# Custom constructor logic
sub BUILD {
    my ($self, $args) = @_;
    $self->{initialized} = time;
}

sub greet {
    my $self = shift;
    return "Hello, " . $self->name;
}

1;

# Usage
my $obj = My::Class->new(
    name => 'Alice',
    age  => 30
);

print $obj->name;  # Alice
print $obj->age;   # 30

DESCRIPTION

Class::More provides a fast, lightweight class building system for Perl with attribute support, inheritance, and constructor building. It's designed for performance and simplicity while providing essential object-oriented features.

The module focuses on speed with optimized method generation, caching, and minimal runtime overhead.

FEATURES

Core Features

  • Fast Attribute System: Simple attributes with required flags and defaults

  • Automatic Accessors: Automatically generates getter/setter methods

  • Inheritance Support: Multiple inheritance with proper method resolution

  • BUILD Methods: Constructor-time initialisation hooks

  • Performance Optimised: Extensive caching and optimised code paths

  • Role Integration: Works seamlessly with Role when available

Performance Features

  • Pre-generated accessors for maximum speed

  • Method resolution order caching

  • Attribute specification caching

  • Fast inheritance checks

  • Batch accessor installation

METHODS

Class Definition Methods

These methods are exported to your class when you use Class::More.

has

has 'attribute_name';
has 'count' => ( default => 0 );
has 'items' => ( default => sub { [] } );
has 'name'  => ( required => 1 );

Defines an attribute in your class. Creates an accessor method that can get and set the attribute value.

Supported options:

  • default - Default value or code reference that returns default value

  • required - Boolean indicating if attribute must be provided to constructor

extends

extends 'Parent::Class';
extends 'Parent1', 'Parent2';

Sets up inheritance for your class. Can specify multiple parents for multiple inheritance. Automatically loads parent classes if needed.

new

my $obj = My::Class->new(%attributes);
my $obj = My::Class->new( name => 'test', count => 42 );

The constructor method. Automatically provided by Class::More. Handles:

  • Attribute initialisation with defaults

  • Required attribute validation

  • BUILD method calling in proper inheritance order

Special Methods

BUILD

sub BUILD {
    my ($self, $args) = @_;
    # Custom initialization logic
    $self->{internal_field} = process($args->{external_field});
}

Optional method called after object construction but before returning from new. Receives the object and the hashref of constructor arguments.

BUILD methods are called in inheritance order (parent classes first).

meta

my $meta = My::Class->meta;
print $meta->{can_handle_attributes};  # 1
print keys %{$meta->{attributes}};     # name, age, tags

Returns metadata about the class. Currently provides:

  • can_handle_attributes - Always true

  • attributes - Hashref of attribute specifications

ATTRIBUTE SYSTEM

Basic Usage

package User;
use Class::More;

has 'username' => ( required => 1 );
has 'email'    => ( required => 1 );
has 'status'   => ( default => 'active' );
has 'created'  => ( default => sub { time } );

Attributes defined with has automatically get accessor methods:

my $user = User->new(
    username => 'alice',
    email    => 'alice@example.com'
);

# Getter
print $user->username;  # alice

# Setter
$user->status('inactive');

Required Attributes

has 'critical_data' => ( required => 1 );

If a required attribute is not provided to the constructor, an exception is thrown:

# Dies: "Required attribute 'critical_data' not provided for class User"
User->new( username => 'test' );

Default Values

has 'counter' => ( default => 0 );
has 'list'    => ( default => sub { [] } );
has 'complex' => ( default => sub {
    return { computed => time }
});

Defaults can be simple values or code references. Code references are executed at construction time and receive the object and constructor arguments.

Inheritance and Attributes

package Parent;
use Class::More;
has 'parent_attr' => ( default => 'from_parent' );

package Child;
use Class::More;
extends 'Parent';
has 'child_attr' => ( default => 'from_child' );

Child classes inherit parent attributes. If both parent and child define the same attribute, the child's specification takes precedence.

PERFORMANCE OPTIMISATIONS

Class::More includes several performance optimisations:

  • Pre-generated Accessors: Simple accessors are pre-compiled and reused

  • Attribute Caching: Combined attribute specifications are cached per class

  • BUILD Order Caching: BUILD method call order is computed once per class

  • Fast Inheritance Checks: Optimised inheritance tree traversal

  • Batch Operations: Multiple accessors installed in batch when possible

EXAMPLES

Simple Class

package Person;
use Class::More;

has 'name' => ( required => 1 );
has 'age'  => ( default => 0 );

sub introduce {
    my $self = shift;
    return "I'm " . $self->name . ", age " . $self->age;
}

1;

Class with Inheritance

package Animal;
use Class::More;

has 'species' => ( required => 1 );
has 'sound'   => ( required => 1 );

sub speak {
    my $self = shift;
    return $self->sound;
}

package Dog;
use Class::More;
extends 'Animal';

sub BUILD {
    my ($self, $args) = @_;
    $self->{species} = 'Canine' unless $args->{species};
    $self->{sound}   = 'Woof!'  unless $args->{sound};
}

sub fetch {
    my $self = shift;
    return $self->name . " fetches the ball!";
}

Class with Complex Attributes

package Configuration;
use Class::More;

has 'settings' => ( default => sub { {} } );
has 'counters' => ( default => sub { { success => 0, failure => 0 } } );
has 'log_file' => ( required => 1 );

sub BUILD {
    my ($self, $args) = @_;

    # Initialize complex data structures
    $self->{internal_cache} = {};
    $self->{start_time} = time;
}

sub increment {
    my ($self, $counter) = @_;
    $self->counters->{$counter}++;
}

INTEGRATION WITH Role

When Role is available, Class::More automatically exports:

with

package My::Class;
use Class::More;

with 'Role::Printable', 'Role::Serialisable';

Composes roles into your class. See Role for complete documentation.

does

if ($obj->does('Role::Printable')) {
    $obj->print;
}

Checks if an object consumes a specific role.

LIMITATIONS

Attribute System Limitations

  • No Type Constraints: Attributes don't support type checking

  • No Access Control: All attributes are readable and writable

  • No Coercion: No automatic value transformation

  • No Triggers: No callbacks when attributes change

  • No Lazy Building: Defaults are applied immediately at construction

  • No Private/Protected: All attributes are publicly accessible via accessors

Inheritance Limitations

  • No Interface Enforcement: No compile-time method requirement checking

  • Limited Meta-Object Protocol: Basic metadata only

  • No Traits: No trait-based composition

  • Diamond Problem: Multiple inheritance may have ambiguous method resolution

General Limitations

  • No Immutability: Can't make classes immutable for performance

  • No Serialisation: No built-in serialisation/deserialisation

  • No Database Integration: No ORM-like features

  • No Exception Hierarchy: No custom exception classes

Compatibility Notes

  • Designed for simplicity and speed over feature completeness

  • Uses standard Perl OO internals (blessed hashrefs)

  • Compatible with most CPAN modules that expect blessed hashrefs

  • Not compatible with Moose/Mouse object systems

  • Role integration requires separate Role module

DIAGNOSTICS

Common Errors

  • "Required attribute 'attribute_name' not provided for class Class::Name"

    A required attribute was not passed to the constructor.

  • "Recursive inheritance detected: ClassA cannot extend itself"

    A class tries to inherit from itself, directly or indirectly.

  • "Invalid attribute option 'option_name' for 'attribute_name' in Class::Name"

    An unsupported attribute option was used.

  • "Can't locate Parent/Class.pm in @INC"

    A parent class specified in extends couldn't be loaded.

Performance Tips

  • Use simple defaults when possible (avoid sub refs for static values)

  • Define all attributes before calling extends for optimal caching

  • Keep BUILD methods lightweight

  • Use the provided new method rather than overriding it

SEE ALSO

  • Role - Companion role system for Class::More

  • Moo - Lightweight Moose-like OO system

  • Mojo::Base - Minimalistic base class for Mojolicious

  • Object::Tiny - Extremely lightweight class builder

  • Class::Accessor - Simple class builder with accessors

  • Moose - Full-featured object system

AUTHOR

Mohammad Sajid Anwar, <mohammad.anwar at yahoo.com>

REPOSITORY

https://github.com/manwar/Class-Mite

BUGS

Please report any bugs or feature requests through the web interface at https://github.com/manwar/Class-Mite/issues. I will be notified and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Class::More

You can also look for information at:

LICENSE AND COPYRIGHT

Copyright (C) 2025 Mohammad Sajid Anwar.

This program is free software; you can redistribute it and / or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at:

http://www.perlfoundation.org/artistic_license_2_0

Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.

If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.

This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.

This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.

Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.