NAME
Class - Lightweight Perl object system with parent-first BUILD and method copying
VERSION
Version v0.1.1
SYNOPSIS
use Class;
# Simple class with attributes and BUILD
package Person;
use Class;
sub BUILD {
my ($self, $attrs) = @_;
$self->{full_name} = $attrs->{first} . ' ' . $attrs->{last};
}
package Employee;
use Class;
extends 'Person';
sub BUILD {
my ($self, $attrs) = @_;
$self->{employee_id} = $attrs->{id};
}
# Create an object
my $emp = Employee->new(first => 'John', last => 'Doe', id => 123);
print $emp->{full_name}; # John Doe
print $emp->{employee_id}; # 123
# Using roles if Role.pm is available
package Manager;
use Class;
with 'SomeRole';
my $mgr = Manager->new();
DESCRIPTION
Class provides a lightweight Perl object system with:
Parent-first constructor building via
BUILDmethods.Simple inheritance via
extendswith method copying.Optional role consumption via
withanddoes(ifRolemodule is available).Automatic caching of BUILD order for efficient object creation.
Optimized method copying for better performance.
This module includes performance optimizations such as cached BUILD method resolution, efficient parent class loading, and optimized method copying with caching.
BUILD METHODS
Classes can define a BUILD method:
sub BUILD {
my ($self, $attrs) = @_;
# initialize object
}
All BUILD methods in the inheritance chain are called in parent-first order during new. The order is determined by depth-first traversal, ensuring that parent classes are always initialized before their children.
For diamond inheritance patterns:
A
/ \
B C
\ /
D
BUILD methods are called in the order: A, B, C, D (true parent-first order)
METHOD COPYING
This system copies public methods from parent classes to child classes. This design enables:
Direct method access in child symbol tables
Proper functioning of object cloning
Better performance for frequently called methods
Compatibility with code that expects direct method access
The following methods are NOT copied:
Special methods (BUILD, new, extends, with, does, import, AUTOLOAD, DESTROY)
Private methods (starting with underscore)
Package metadata (ISA, VERSION, EXPORT, etc.)
ROLES
If a Role module is available, you can consume roles via:
with 'RoleName';
does 'RoleName';
This provides role-based composition for shared behavior. The Role module must be installed separately.
PERFORMANCE OPTIMISATIONS
This version includes significant performance improvements:
Cached BUILD method resolution using depth-first parent-first order
Precomputed skip patterns for fast method filtering
Method copying cache to avoid duplicate operations
Efficient parent class loading with minimal overhead
Optimized symbol table scanning
CACHING
Class uses internal caches to optimise performance:
%BUILD_METHODS_CACHE- caches linearised parent-first build order%METHOD_COPY_CACHE- tracks which parent-child pairs have had methods copied
Caches are automatically updated when inheritance changes via extends.
ERROR HANDLING
Recursive inheritance is detected and throws an exception.
Failure to load a parent class is non-fatal (parent might be defined inline).
EXAMPLES
Basic Inheritance with Method Copying
package Animal;
use Class;
sub speak { "animal sound" }
sub eat { "eating" }
package Dog;
use Class;
extends 'Animal';
sub speak { "woof" } # Overrides parent method
my $dog = Dog->new;
print $dog->speak; # "woof" (from Dog)
print $dog->eat; # "eating" (copied from Animal)
# Method is copied to Dog's symbol table
no strict 'refs';
print defined &Dog::eat ? "copied" : "not copied"; # "copied"
Diamond Inheritance
package A;
use Class;
sub BUILD { print "A BUILD\n" }
package B;
use Class;
extends 'A';
sub BUILD { print "B BUILD\n" }
package C;
use Class;
extends 'A';
sub BUILD { print "C BUILD\n" }
package D;
use Class;
extends 'B', 'C';
sub BUILD { print "D BUILD\n" }
my $d = D->new;
# Output: A BUILD, B BUILD, C BUILD, D BUILD
Object Cloning with Method Copying
package Base;
use Class;
sub clone_method { "works" }
package Child;
use Class;
extends 'Base';
my $original = Child->new;
my $cloned = bless { %$original }, ref($original);
# Works because methods are copied to Child
print $cloned->clone_method; # "works"
METHODS
new
my $obj = Class->new(%attributes);
Constructs a new object of the class, calling all BUILD methods from parent classes in parent-first order. All attributes are passed to BUILD as a hashref.
The constructor uses cached BUILD method references for optimal performance, especially in deep inheritance hierarchies.
_compute_build_methods
my $build_methods = _compute_build_methods($class);
Internal method that computes the BUILD methods in parent-first order using depth-first traversal.
This ensures BUILD methods are called from the root parent down to the child class, which is essential for proper initialisation in inheritance hierarchies.
_depth_first_traverse
_depth_first_traverse($class, \@order, \%visited);
Internal recursive method that performs depth-first traversal of the inheritance hierarchy.
This method ensures that parent classes are always processed before their children, which is crucial for correct BUILD method ordering.
extends
extends 'ParentClass';
extends 'Parent1', 'Parent2';
Adds one or more parent classes to the calling class. This method:
Automatically loads parent classes if not already loaded
Prevents recursive inheritance
Copies public methods from parents to children
Maintains inheritance via
@ISAClears relevant caches to ensure consistency
Method copying is performed to ensure that inherited methods are directly available in the child class's symbol table, which enables features like object cloning to work correctly.
_copy_public_methods
_copy_public_methods($child_class, $parent_class);
Internal method that copies public methods from parent to child class. This method:
Skips special methods (BUILD, new, extends, etc.)
Skips private methods (starting with underscore)
Uses caching to avoid duplicate copying
Only copies methods not already defined in child
This optimised implementation uses precomputed skip patterns and caching for better performance.
_delete_build_cache
_delete_build_cache($class);
Internal method that clears the BUILD methods cache for a class and all classes that inherit from it.
This ensures cache consistency when inheritance relationships change. Also clears method copy caches for affected classes.
_inherits_from
_inherits_from($class, $parent);
Internal recursive method that checks if a class inherits from another class, either directly or indirectly.
Returns true if $class inherits from $parent, false otherwise.
IMPORT
use Class;
use Class 'extends' => 'Parent';
When imported, Class automatically installs the following functions into the caller's namespace:
new- constructorextends- inheritance helperwithanddoes- if Role.pm is available
Optionally, you can specify extends in the import statement to immediately set a parent class:
use Class 'extends' => 'Parent';
The import method also enables strict and warnings in the calling package.
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
You can also look for information at:
BUG Report
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.