Venus::Core
Core Base Class
Core Base Class for Perl 5
method: args method: attr method: audit method: base method: bless method: build method: buildargs method: clone method: construct method: data method: deconstruct method: destroy method: does method: export method: from method: get method: import method: item method: mask method: meta method: mixin method: name method: role method: set method: subs method: test method: use method: unimport
package User;
use base 'Venus::Core';
package main;
my $user = User->BLESS(
fname => 'Elliot',
lname => 'Alderson',
);
# bless({fname => 'Elliot', lname => 'Alderson'}, 'User')
# i.e. BLESS is somewhat equivalent to writing
# User->BUILD(bless(User->ARGS(User->BUILDARGS(@args) || User->DATA), 'User'))
This package provides a base class for "class" and "role" (kind) derived packages and provides class building, object construction, and object deconstruction lifecycle hooks. The Venus::Class and Venus::Role packages provide a simple DSL for automating Venus::Core derived base classes.
The ARGS method is a object construction lifecycle hook which accepts a list of arguments and returns a blessable data structure.
ARGS(any @args) (hashref)
{ since => '1.00', }
=example-1 args
# given: synopsis
package main;
my $args = User->ARGS;
# {}
The ATTR method is a class building lifecycle hook which installs an attribute accessors in the calling package.
ATTR(string $name, any @args) (string | object)
{ since => '1.00', }
=example-1 attr
package User;
use base 'Venus::Core';
User->ATTR('name');
package main;
my $user = User->BLESS;
# bless({}, 'User')
# $user->name;
# ""
# $user->name('Elliot');
# "Elliot"
The AUDIT method is a class building lifecycle hook which exist in roles and is executed as a callback when the consuming class invokes the "TEST" hook.
AUDIT(string $role) (string | object)
{ since => '1.00', }
=example-1 audit
package HasType;
use base 'Venus::Core';
sub AUDIT {
die 'Consumer missing "type" attribute' if !$_[1]->can('type');
}
package User;
use base 'Venus::Core';
User->TEST('HasType');
package main;
my $user = User->BLESS;
# Exception! Consumer missing "type" attribute
The BASE method is a class building lifecycle hook which registers a base class for the calling package. Note: Unlike the "FROM" hook, this hook doesn't invoke the "AUDIT" hook.
BASE(string $name) (string | object)
{ since => '1.00', }
=example-1 base
package Entity;
sub work {
return;
}
package User;
use base 'Venus::Core';
User->BASE('Entity');
package main;
my $user = User->BLESS;
# bless({}, 'User')
The BLESS method is an object construction lifecycle hook which returns an instance of the calling package.
BLESS(any @args) (object)
{ since => '1.00', }
=example-1 bless
package User;
use base 'Venus::Core';
package main;
my $example = User->BLESS;
# bless({}, 'User')
The BUILD method is an object construction lifecycle hook which receives an object and the data structure that was blessed, and should return an object although its return value is ignored by the "BLESS" hook.
BUILD(hashref $data) (object)
{ since => '1.00', }
=example-1 build
package User;
use base 'Venus::Core';
sub BUILD {
my ($self) = @_;
$self->{name} = 'Mr. Robot';
return $self;
}
package main;
my $example = User->BLESS(name => 'Elliot');
# bless({name => 'Mr. Robot'}, 'User')
The BUILDARGS method is an object construction lifecycle hook which receives the arguments provided to the constructor (unaltered) and should return a list of arguments, a hashref, or key/value pairs.
BUILDARGS(any @args) (any @args | hashref $data)
{ since => '1.00', }
=example-1 buildargs
package User;
use base 'Venus::Core';
sub BUILD {
my ($self) = @_;
return $self;
}
sub BUILDARGS {
my ($self, @args) = @_;
my $data = @args == 1 && !ref $args[0] ? {name => $args[0]} : {};
return $data;
}
package main;
my $user = User->BLESS('Elliot');
# bless({name => 'Elliot'}, 'User')
The CLONE method is an object construction lifecycle hook that returns a deep clone of the invocant. The invocant must be blessed, meaning that the method only applies to objects that are instances of a package. If the invocant is not blessed, an exception will be raised. This method uses deep cloning to create an independent copy of the object, including any private instance data, nested structures or references within the object.
clone() (object)
{ since => '4.15', }
The CONSTRUCT method is an object construction lifecycle hook that is automatically called after the "BLESS" method, without any arguments. It is intended to prepare the instance for usage, separate from the build process, allowing for any setup or post-processing needed after the object has been blessed. This method's return value is not used in any subsequent processing, so its primary purpose is side effects or additional setup.
construct() (any)
{ since => '4.15', }
The DATA method is an object construction lifecycle hook which returns the default data structure reference to be blessed when no arguments are provided to the constructor. The default data structure is an empty hashref.
DATA() (Ref)
{ since => '1.00', }
=example-1 data
package Example;
use base 'Venus::Core';
sub DATA {
return [];
}
package main;
my $example = Example->BLESS;
# bless([], 'Example')
The DECONSTRUCT method is an object destruction lifecycle hook that is called just before the "DESTROY" method. It provides an opportunity to perform any necessary cleanup or resource release on the instance before it is destroyed. This can include actions like disconnecting from external resources, clearing caches, or logging. The method returns the instance, but its return value is not used in subsequent processing.
deconstruct() (any)
{ since => '4.15', }
The DESTROY method is an object destruction lifecycle hook which is called when the last reference to the object goes away.
DESTROY() (any)
{ since => '1.00', }
=example-1 destroy
package User;
use base 'Venus::Core';
our $TRIES = 0;
sub BUILD {
return $TRIES++;
}
sub DESTROY {
return $TRIES--;
}
package main;
my $user = User->BLESS(name => 'Elliot');
undef $user;
# undef
The DOES method returns true or false if the invocant consumed the role or interface provided.
DOES(string $name) (boolean)
{ since => '1.00', }
=example-1 does
package Admin;
use base 'Venus::Core';
package User;
use base 'Venus::Core';
User->ROLE('Admin');
sub BUILD {
my ($self) = @_;
return $self;
}
sub BUILDARGS {
my ($self, @args) = @_;
return (@args);
}
package main;
my $admin = User->DOES('Admin');
# 1
The EXPORT method is a class building lifecycle hook which returns an arrayref of routine names to be automatically imported by the calling package whenever the "ROLE" or "TEST" hooks are used.
EXPORT(any @args) (arrayref)
{ since => '1.00', }
=example-1 export
package Admin;
use base 'Venus::Core';
sub shutdown {
return;
}
sub EXPORT {
['shutdown']
}
package User;
use base 'Venus::Core';
User->ROLE('Admin');
package main;
my $user = User->BLESS;
# bless({}, 'User')
The FROM method is a class building lifecycle hook which registers a base class for the calling package, automatically invoking the "AUDIT" and "IMPORT" hooks on the base class.
FROM(string $name) (string | object)
{ since => '1.00', }
=example-1 from
package Entity;
use base 'Venus::Core';
sub AUDIT {
my ($self, $from) = @_;
die "Missing startup" if !$from->can('startup');
die "Missing shutdown" if !$from->can('shutdown');
}
package User;
use base 'Venus::Core';
User->ATTR('startup');
User->ATTR('shutdown');
User->FROM('Entity');
package main;
my $user = User->BLESS;
# bless({}, 'User')
The GET method is a class instance lifecycle hook which is responsible for "getting" instance items (or attribute values). By default, all class attributes "getters" are dispatched to this method.
GET(string $name) (any)
{ since => '2.91', }
The IMPORT method is a class building lifecycle hook which dispatches the "EXPORT" lifecycle hook whenever the "ROLE" or "TEST" hooks are used.
IMPORT(string $into, any @args) (string | object)
{ since => '1.00', }
=example-1 import
package Admin;
use base 'Venus::Core';
our $USES = 0;
sub shutdown {
return;
}
sub EXPORT {
['shutdown']
}
sub IMPORT {
my ($self, $into) = @_;
$self->SUPER::IMPORT($into);
$USES++;
return $self;
}
package User;
use base 'Venus::Core';
User->ROLE('Admin');
package main;
my $user = User->BLESS;
# bless({}, 'User')
The ITEM method is a class instance lifecycle hook which is responsible for "getting" and "setting" instance items (or attributes). By default, all class attributes are dispatched to this method.
ITEM(string $name, any @args) (string | object)
{ since => '1.11', }
=example-1 item
package User;
use base 'Venus::Core';
User->ATTR('name');
package main;
my $user = User->BLESS;
# bless({}, 'User')
my $item = $user->ITEM('name', 'unknown');
# "unknown"
The MASK method is a class-building lifecycle hook that installs private instance data accessors in the calling package. The accessor created allows private access to an instance variable, ensuring that it can only be accessed within the class or its subclasses. The method takes the name of the private variable as the first argument and any additional parameters needed for configuration. Attempting to access or set this variable outside of the class will raise an exception. This feature is useful for creating encapsulated attributes that maintain controlled visibility.
mask(string $name, any @args) (string | object)
{ since => '4.15', }
The META method return a Venus::Meta object which describes the invocant's configuration.
META() (Venus::Meta)
{ since => '1.00', }
=example-1 meta
package User;
use base 'Venus::Core';
package main;
my $meta = User->META;
# bless({name => 'User'}, 'Venus::Meta')
The MIXIN method is a class building lifecycle hook which consumes the mixin provided, automatically invoking the mixin's "IMPORT" hook. The role composition semantics are as follows: Routines to be consumed must be explicitly declared via the "EXPORT" hook. Routines will be copied to the consumer even if they already exist. If multiple roles are consumed having routines with the same name (i.e. naming collisions) the last routine copied wins.
MIXIN(string $name) (string | object)
{ since => '1.02', }
=example-1 mixin
package Action;
use base 'Venus::Core';
package User;
use base 'Venus::Core';
User->MIXIN('Action');
package main;
my $admin = User->DOES('Action');
# 0
The NAME method is a class building lifecycle hook which returns the name of the package.
NAME() (string)
{ since => '1.00', }
=example-1 name
package User;
use base 'Venus::Core';
package main;
my $name = User->NAME;
# "User"
The ROLE method is a class building lifecycle hook which consumes the role provided, automatically invoking the role's "IMPORT" hook. Note: Unlike the "TEST" and "WITH" hooks, this hook doesn't invoke the "AUDIT" hook. The role composition semantics are as follows: Routines to be consumed must be explicitly declared via the "EXPORT" hook. Routines will be copied to the consumer unless they already exist (excluding routines from base classes, which will be overridden). If multiple roles are consumed having routines with the same name (i.e. naming collisions) the first routine copied wins.
ROLE(string $name) (string | object)
{ since => '1.00', }
=example-1 role
package Admin;
use base 'Venus::Core';
package User;
use base 'Venus::Core';
User->ROLE('Admin');
package main;
my $admin = User->DOES('Admin');
# 1
The SET method is a class instance lifecycle hook which is responsible for "setting" instance items (or attribute values). By default, all class attributes "setters" are dispatched to this method.
SET(string $name, any @args) (any)
{ since => '2.91', }
The SUBS method returns the routines defined on the package and consumed from roles, but not inherited by superclasses.
SUBS() (arrayref)
{ since => '1.00', }
=example-1 subs
package Example;
use base 'Venus::Core';
package main;
my $subs = Example->SUBS;
# [...]
The TEST method is a class building lifecycle hook which consumes the role provided, automatically invoking the role's "IMPORT" hook as well as the "AUDIT" hook if defined.
TEST(string $name) (string | object)
{ since => '1.00', }
=example-1 test
package Admin;
use base 'Venus::Core';
package IsAdmin;
use base 'Venus::Core';
sub shutdown {
return;
}
sub AUDIT {
my ($self, $from) = @_;
die "${from} is not a super-user" if !$from->DOES('Admin');
}
sub EXPORT {
['shutdown']
}
package User;
use base 'Venus::Core';
User->ROLE('Admin');
User->TEST('IsAdmin');
package main;
my $user = User->BLESS;
# bless({}, 'User')
The UNIMPORT method is a class building lifecycle hook which is invoked whenever the "no" in perlfunc declaration is used.
UNIMPORT(string $into, any @args) (any)
{ since => '2.91', }
=example-1 unimport
package User;
use base 'Venus::Core';
package main;
User->UNIMPORT;
# 'User'
The USE method is a class building lifecycle hook which is invoked whenever the "use" in perlfunc declaration is used.
USE(string $into, any @args) (any)
{ since => '2.91', }
=example-1 use
package User;
use base 'Venus::Core';
package main;
User->USE;
# 'User'
t/Venus.t: present: authors t/Venus.t: present: license
118 POD Errors
The following errors were encountered while parsing the POD:
- Around line 14:
Unknown directive: =name
- Around line 22:
Unknown directive: =tagline
- Around line 30:
Unknown directive: =abstract
- Around line 38:
Unknown directive: =includes
- Around line 73:
Unknown directive: =synopsis
- Around line 106:
Unknown directive: =description
- Around line 118:
Unknown directive: =method
- Around line 123:
Unknown directive: =signature
- Around line 127:
Unknown directive: =metadata
- Around line 163:
=cut found outside a pod block. Skipping to next block.
- Around line 185:
=cut found outside a pod block. Skipping to next block.
- Around line 197:
Unknown directive: =method
- Around line 202:
Unknown directive: =signature
- Around line 206:
Unknown directive: =metadata
- Around line 271:
=cut found outside a pod block. Skipping to next block.
- Around line 287:
Unknown directive: =method
- Around line 292:
Unknown directive: =signature
- Around line 296:
Unknown directive: =metadata
- Around line 356:
=cut found outside a pod block. Skipping to next block.
- Around line 367:
Unknown directive: =method
- Around line 373:
Unknown directive: =signature
- Around line 377:
Unknown directive: =metadata
- Around line 447:
=cut found outside a pod block. Skipping to next block.
- Around line 476:
=cut found outside a pod block. Skipping to next block.
- Around line 486:
Unknown directive: =method
- Around line 491:
Unknown directive: =signature
- Around line 495:
Unknown directive: =metadata
- Around line 536:
=cut found outside a pod block. Skipping to next block.
- Around line 562:
=cut found outside a pod block. Skipping to next block.
- Around line 602:
=cut found outside a pod block. Skipping to next block.
- Around line 639:
=cut found outside a pod block. Skipping to next block.
- Around line 650:
Unknown directive: =method
- Around line 656:
Unknown directive: =signature
- Around line 660:
Unknown directive: =metadata
- Around line 734:
=cut found outside a pod block. Skipping to next block.
- Around line 749:
Unknown directive: =method
- Around line 755:
Unknown directive: =signature
- Around line 759:
Unknown directive: =metadata
- Around line 805:
Unknown directive: =method
- Around line 814:
Unknown directive: =signature
- Around line 818:
Unknown directive: =metadata
- Around line 840:
=cut found outside a pod block. Skipping to next block.
- Around line 868:
=cut found outside a pod block. Skipping to next block.
- Around line 909:
=cut found outside a pod block. Skipping to next block.
- Around line 926:
Unknown directive: =method
- Around line 935:
Unknown directive: =signature
- Around line 939:
Unknown directive: =metadata
- Around line 967:
=cut found outside a pod block. Skipping to next block.
- Around line 980:
Unknown directive: =method
- Around line 986:
Unknown directive: =signature
- Around line 990:
Unknown directive: =metadata
- Around line 1039:
=cut found outside a pod block. Skipping to next block.
- Around line 1051:
Unknown directive: =method
- Around line 1060:
Unknown directive: =signature
- Around line 1064:
Unknown directive: =metadata
- Around line 1102:
=cut found outside a pod block. Skipping to next block.
- Around line 1114:
Unknown directive: =method
- Around line 1119:
Unknown directive: =signature
- Around line 1123:
Unknown directive: =metadata
- Around line 1164:
Unknown directive: =method
- Around line 1169:
Unknown directive: =signature
- Around line 1173:
Unknown directive: =metadata
- Around line 1249:
=cut found outside a pod block. Skipping to next block.
- Around line 1259:
Unknown directive: =method
- Around line 1265:
Unknown directive: =signature
- Around line 1269:
Unknown directive: =metadata
- Around line 1312:
Unknown directive: =method
- Around line 1318:
Unknown directive: =signature
- Around line 1322:
Unknown directive: =metadata
- Around line 1400:
=cut found outside a pod block. Skipping to next block.
- Around line 1413:
Unknown directive: =method
- Around line 1419:
Unknown directive: =signature
- Around line 1423:
Unknown directive: =metadata
- Around line 1449:
=cut found outside a pod block. Skipping to next block.
- Around line 1459:
Unknown directive: =method
- Around line 1464:
Unknown directive: =signature
- Around line 1468:
Unknown directive: =metadata
- Around line 1525:
Unknown directive: =method
- Around line 1531:
Unknown directive: =signature
- Around line 1535:
Unknown directive: =metadata
- Around line 1589:
=cut found outside a pod block. Skipping to next block.
- Around line 1599:
Unknown directive: =method
- Around line 1610:
Unknown directive: =signature
- Around line 1614:
Unknown directive: =metadata
- Around line 1638:
=cut found outside a pod block. Skipping to next block.
- Around line 1665:
=cut found outside a pod block. Skipping to next block.
- Around line 1708:
=cut found outside a pod block. Skipping to next block.
- Around line 1721:
Unknown directive: =method
- Around line 1726:
Unknown directive: =signature
- Around line 1730:
Unknown directive: =metadata
- Around line 1761:
Unknown directive: =method
- Around line 1771:
Unknown directive: =signature
- Around line 1775:
Unknown directive: =metadata
- Around line 1808:
Unknown directive: =method
- Around line 1813:
Unknown directive: =signature
- Around line 1817:
Unknown directive: =metadata
- Around line 1857:
=cut found outside a pod block. Skipping to next block.
- Around line 1867:
Unknown directive: =method
- Around line 1878:
Unknown directive: =signature
- Around line 1882:
Unknown directive: =metadata
- Around line 1945:
=cut found outside a pod block. Skipping to next block.
- Around line 1958:
Unknown directive: =method
- Around line 1964:
Unknown directive: =signature
- Around line 1968:
Unknown directive: =metadata
- Around line 1994:
=cut found outside a pod block. Skipping to next block.
- Around line 2004:
Unknown directive: =method
- Around line 2009:
Unknown directive: =signature
- Around line 2013:
Unknown directive: =metadata
- Around line 2041:
Unknown directive: =method
- Around line 2047:
Unknown directive: =signature
- Around line 2051:
Unknown directive: =metadata
- Around line 2106:
Unknown directive: =method
- Around line 2111:
Unknown directive: =signature
- Around line 2115:
Unknown directive: =metadata
- Around line 2143:
Unknown directive: =method
- Around line 2148:
Unknown directive: =signature
- Around line 2152:
Unknown directive: =metadata
- Around line 2180:
Unknown directive: =partials