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: data method: destroy method: does method: export method: from method: import method: item method: meta method: name method: role method: subs method: test

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(Str $name, Any @args) (Str | 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(Str $role) (Str | 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(Str $name) (Str | 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 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 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 $USERS = 0;

sub BUILD {
  return $USERS++;
}

sub DESTROY {
  return $USERS--;
}

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(Str $name) (Bool)

{ since => '1.00', }

=example-1 does

package Admin;

use base 'Venus::Core';

package User;

use base 'Venus::Core';

User->ROLE('Admin');

sub BUILD {
  return;
}

sub BUILDARGS {
  return;
}

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(Str $name) (Str | 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 IMPORT method is a class building lifecycle hook which dispatches the "EXPORT" lifecycle hook whenever the "ROLE" or "TEST" hooks are used.

IMPORT(Str $into, Any @args) (Str | 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(Str $name, Any @args) (Str | 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 META method return a Venus::Meta object which describes the invocant's configuration.

META() (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(Str $name) (Str | 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() (Str)

{ 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(Str $name) (Str | 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 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(Str $name) (Str | 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')

t/Venus.t: pdml: authors t/Venus.t: pdml: license

84 POD Errors

The following errors were encountered while parsing the POD:

Around line 13:

Unknown directive: =name

Around line 21:

Unknown directive: =tagline

Around line 29:

Unknown directive: =abstract

Around line 37:

Unknown directive: =includes

Around line 63:

Unknown directive: =synopsis

Around line 96:

Unknown directive: =description

Around line 108:

Unknown directive: =method

Around line 113:

Unknown directive: =signature

Around line 117:

Unknown directive: =metadata

Around line 153:

=cut found outside a pod block. Skipping to next block.

Around line 175:

=cut found outside a pod block. Skipping to next block.

Around line 187:

Unknown directive: =method

Around line 192:

Unknown directive: =signature

Around line 196:

Unknown directive: =metadata

Around line 261:

=cut found outside a pod block. Skipping to next block.

Around line 277:

Unknown directive: =method

Around line 282:

Unknown directive: =signature

Around line 286:

Unknown directive: =metadata

Around line 346:

=cut found outside a pod block. Skipping to next block.

Around line 357:

Unknown directive: =method

Around line 363:

Unknown directive: =signature

Around line 367:

Unknown directive: =metadata

Around line 437:

=cut found outside a pod block. Skipping to next block.

Around line 466:

=cut found outside a pod block. Skipping to next block.

Around line 476:

Unknown directive: =method

Around line 481:

Unknown directive: =signature

Around line 485:

Unknown directive: =metadata

Around line 526:

=cut found outside a pod block. Skipping to next block.

Around line 552:

=cut found outside a pod block. Skipping to next block.

Around line 592:

=cut found outside a pod block. Skipping to next block.

Around line 629:

=cut found outside a pod block. Skipping to next block.

Around line 640:

Unknown directive: =method

Around line 646:

Unknown directive: =signature

Around line 650:

Unknown directive: =metadata

Around line 724:

=cut found outside a pod block. Skipping to next block.

Around line 739:

Unknown directive: =method

Around line 745:

Unknown directive: =signature

Around line 749:

Unknown directive: =metadata

Around line 795:

Unknown directive: =method

Around line 801:

Unknown directive: =signature

Around line 805:

Unknown directive: =metadata

Around line 854:

=cut found outside a pod block. Skipping to next block.

Around line 866:

Unknown directive: =method

Around line 871:

Unknown directive: =signature

Around line 875:

Unknown directive: =metadata

Around line 916:

Unknown directive: =method

Around line 921:

Unknown directive: =signature

Around line 925:

Unknown directive: =metadata

Around line 993:

=cut found outside a pod block. Skipping to next block.

Around line 1003:

Unknown directive: =method

Around line 1009:

Unknown directive: =signature

Around line 1013:

Unknown directive: =metadata

Around line 1056:

Unknown directive: =method

Around line 1062:

Unknown directive: =signature

Around line 1066:

Unknown directive: =metadata

Around line 1144:

=cut found outside a pod block. Skipping to next block.

Around line 1157:

Unknown directive: =method

Around line 1162:

Unknown directive: =signature

Around line 1166:

Unknown directive: =metadata

Around line 1223:

Unknown directive: =method

Around line 1229:

Unknown directive: =signature

Around line 1233:

Unknown directive: =metadata

Around line 1287:

=cut found outside a pod block. Skipping to next block.

Around line 1297:

Unknown directive: =method

Around line 1302:

Unknown directive: =signature

Around line 1306:

Unknown directive: =metadata

Around line 1337:

Unknown directive: =method

Around line 1347:

Unknown directive: =signature

Around line 1351:

Unknown directive: =metadata

Around line 1384:

Unknown directive: =method

Around line 1389:

Unknown directive: =signature

Around line 1393:

Unknown directive: =metadata

Around line 1433:

=cut found outside a pod block. Skipping to next block.

Around line 1443:

Unknown directive: =method

Around line 1454:

Unknown directive: =signature

Around line 1458:

Unknown directive: =metadata

Around line 1521:

=cut found outside a pod block. Skipping to next block.

Around line 1534:

Unknown directive: =method

Around line 1539:

Unknown directive: =signature

Around line 1543:

Unknown directive: =metadata

Around line 1571:

Unknown directive: =method

Around line 1577:

Unknown directive: =signature

Around line 1581:

Unknown directive: =metadata

Around line 1636:

Unknown directive: =partials