Venus::Class

Class Builder

Class Builder for Perl 5

function: after function: around function: attr function: base function: before function: catch function: error function: false function: from function: handle function: hook function: mask function: mixin function: raise function: role function: test function: true function: with

package Person;

use Venus::Class 'attr';

attr 'fname';
attr 'lname';

package Identity;

use Venus::Role 'attr';

attr 'id';
attr 'login';
attr 'password';

sub EXPORT {
  # explicitly declare routines to be consumed
  ['id', 'login', 'password']
}

package Authenticable;

use Venus::Role;

sub authenticate {
  return true;
}

sub AUDIT {
  my ($self, $from) = @_;
  # ensure the caller has a login and password when consumed
  die "${from} missing the login attribute" if !$from->can('login');
  die "${from} missing the password attribute" if !$from->can('password');
}

sub BUILD {
  my ($self, $data) = @_;
  $self->{auth} = undef;
  return $self;
}

sub EXPORT {
  # explicitly declare routines to be consumed
  ['authenticate']
}

package User;

use Venus::Class;

base 'Person';

with 'Identity';

attr 'email';

test 'Authenticable';

sub valid {
  my ($self) = @_;
  return $self->login && $self->password ? true : false;
}

package main;

my $user = User->new(
  fname => 'Elliot',
  lname => 'Alderson',
);

# bless({fname => 'Elliot', lname => 'Alderson'}, 'User')

This package provides a class builder which when used causes the consumer to inherit from Venus::Core::Class which provides object construction and lifecycle hooks.

The after function installs a method modifier that executes after the original method, allowing you to perform actions after a method call. Note: The return value of the modifier routine is ignored; the wrapped method always returns the value from the original method. Modifiers are executed in the order they are stacked. This function is only exported when requested.

after(string $name, coderef $code) (coderef)

{ since => '4.15', }

=example-1 after

package Example1;

use Venus::Class 'after', 'attr';

attr 'calls';

sub BUILD {
  my ($self) = @_;
  $self->calls([]);
}

sub test {
  my ($self) = @_;
  push @{$self->calls}, 'original';
  return 'original';
}

after 'test', sub {
  my ($self) = @_;
  push @{$self->calls}, 'after';
  return 'ignored';
};

package main;

my $example = Example1->new;
my $result = $example->test;

# "original"

The around function installs a method modifier that wraps around the original method. The callback provided will recieve the original routine as its first argument. This function is only exported when requested.

around(string $name, coderef $code) (coderef)

{ since => '4.15', }

=example-1 around

package Example2;

use Venus::Class 'around', 'attr';

sub test {
  my ($self, $value) = @_;
  return $value;
}

around 'test', sub {
  my ($orig, $self, $value) = @_;
  return $self->$orig($value) * 2;
};

package main;

my $result = Example2->new->test(5);

# 10

The attr function creates attribute accessors for the calling package. This function is always exported unless a routine of the same name already exists.

attr(string $name) (string)

{ since => '1.00', }

=example-1 attr

package Example;

use Venus::Class;

attr 'name';

# "Example"

The before function installs a method modifier that executes before the original method, allowing you to perform actions before a method call. Note: The return value of the modifier routine is ignored; the wrapped method always returns the value from the original method. Modifiers are executed in the order they are stacked. This function is only exported when requested.

before(string $name, coderef $code) (coderef)

{ since => '4.15', }

=example-1 before

package Example3;

use Venus::Class 'attr', 'before';

attr 'calls';

sub BUILD {
  my ($self) = @_;
  $self->calls([]);
}

sub test {
  my ($self) = @_;
  push @{$self->calls}, 'original';
  return $self;
}

before 'test', sub {
  my ($self) = @_;
  push @{$self->calls}, 'before';
  return $self;
};

package main;

my $example = Example3->new;
$example->test;
my $calls = $example->calls;

# ['before', 'original']

The base function registers one or more base classes for the calling package. This function is always exported unless a routine of the same name already exists.

base(string $name) (string)

{ since => '1.00', }

=example-1 base

package Entity;

use Venus::Class;

sub output {
  return;
}

package Example;

use Venus::Class;

base 'Entity';

# "Example"

The catch function executes the code block trapping errors and returning the caught exception in scalar context, and also returning the result as a second argument in list context. This function isn't export unless requested.

catch(coderef $block) (Venus::Error, any)

{ since => '1.01', }

=example-1 catch

package Example;

use Venus::Class 'catch';

sub attempt {
  catch {die};
}

package main;

my $example = Example->new;

my $error = $example->attempt;

$error;

# "Died at ..."

The error function throws a Venus::Error exception object using the exception object arguments provided. This function isn't export unless requested.

error(maybe[hashref] $args) (Venus::Error)

{ since => '1.01', }

=example-1 error

package Example;

use Venus::Class 'error';

sub attempt {
  error;
}

package main;

my $example = Example->new;

my $error = $example->attempt;

# bless({...}, 'Venus::Error')

The false function returns a falsy boolean value which is designed to be practically indistinguishable from the conventional numerical 0 value. This function is always exported unless a routine of the same name already exists.

false() (boolean)

{ since => '1.00', }

=example-1 false

package Example;

use Venus::Class;

my $false = false;

# 0

The from function registers one or more base classes for the calling package and performs an "audit". This function is always exported unless a routine of the same name already exists.

from(string $name) (string)

{ since => '1.00', }

=example-1 from

package Entity;

use Venus::Class;

sub AUDIT {
  my ($self, $from) = @_;
  die "Missing startup" if !$from->can('startup');
  die "Missing shutdown" if !$from->can('shutdown');
}

package Example;

use Venus::Class;

attr 'startup';
attr 'shutdown';

from 'Entity';

# "Example"

The handle function installs a method modifier that wraps a method, providing low-level control. The callback provided will recieve the original routine as its first argument (or undef if the source routine doesn't exist). This function is only exported when requested.

handle(string $name, coderef $code) (coderef)

{ since => '4.15', }

=example-1 handle

package Example4;

use Venus::Class 'attr', 'handle';

sub test {
  my ($self, $value) = @_;
  return $value;
}

handle 'test', sub {
  my ($orig, $self, $value) = @_;
  return $orig ? $self->$orig($value * 2) : 0;
};

package main;

my $result = Example4->new->test(5);

# 10

The hook function installs a method modifier on a lifecycle hook method. The first argument is the type of modifier desired, e.g., "before", "after", "around", and the callback provided will recieve the original routine as its first argument. This function is only exported when requested.

hook(string $type, string $name, coderef $code) (coderef)

{ since => '4.15', }

=example-1 hook

package Example5;

use Venus::Class 'attr', 'hook';

attr 'startup';

sub BUILD {
  my ($self, $args) = @_;
  $self->startup('original');
}

hook 'after', 'build', sub {
  my ($self) = @_;
  $self->startup('modified');
};

package main;

my $result = Example5->new->startup;

# "modified"

The mask function creates private attribute accessors that can only be accessed from within the class or its subclasses. This function is exported on-demand unless a routine of the same name already exists.

mask(string $name) (string)

{ since => '4.15', }

=example-1 mask

package Example;

use Venus::Class;

mask 'secret';

sub set_secret {
  my ($self, $value) = @_;
  $self->secret($value);
}

sub get_secret {
  my ($self) = @_;
  return $self->secret;
}

package main;

my $example = Example->new;

# $example->set_secret('...')

# $example->get_secret

# Exception! (if accessed externally)
# $example->secret

The mixin function registers and consumes mixins for the calling package. This function is always exported unless a routine of the same name already exists.

mixin(string $name) (string)

{ since => '1.02', }

=example-1 mixin

package YesNo;

use Venus::Mixin;

sub no {
  return 0;
}

sub yes {
  return 1;
}

sub EXPORT {
  ['no', 'yes']
}

package Answer;

use Venus::Class;

mixin 'YesNo';

# "Answer"

The raise function generates and throws a named exception object derived from Venus::Error, or provided base class, using the exception object arguments provided. This function isn't export unless requested.

raise(string $class | tuple[string, string] $class, maybe[hashref] $args) (Venus::Error)

{ since => '1.01', }

=example-1 raise

package Example;

use Venus::Class 'raise';

sub attempt {
  raise 'Example::Error';
}

package main;

my $example = Example->new;

my $error = $example->attempt;

# bless({...}, 'Example::Error')

The role function registers and consumes roles for the calling package. This function is always exported unless a routine of the same name already exists.

role(string $name) (string)

{ since => '1.00', }

=example-1 role

package Ability;

use Venus::Role;

sub action {
  return;
}

package Example;

use Venus::Class;

role 'Ability';

# "Example"

The test function registers and consumes roles for the calling package and performs an "audit", effectively allowing a role to act as an interface. This function is always exported unless a routine of the same name already exists.

test(string $name) (string)

{ since => '1.00', }

=example-1 test

package Actual;

use Venus::Role;

package Example;

use Venus::Class;

test 'Actual';

# "Example"

The true function returns a truthy boolean value which is designed to be practically indistinguishable from the conventional numerical 1 value. This function is always exported unless a routine of the same name already exists.

true() (boolean)

{ since => '1.00', }

=example-1 true

package Example;

use Venus::Class;

my $true = true;

# 1

The with function registers and consumes roles for the calling package. This function is an alias of the "test" function and will perform an "audit" if present. This function is always exported unless a routine of the same name already exists.

with(string $name) (string)

{ since => '1.00', }

=example-1 with

package Understanding;

use Venus::Role;

sub knowledge {
  return;
}

package Example;

use Venus::Class;

with 'Understanding';

# "Example"

t/Venus.t: present: authors t/Venus.t: present: license

66 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 63:

Unknown directive: =synopsis

Around line 162:

Unknown directive: =description

Around line 172:

Unknown directive: =function

Around line 180:

Unknown directive: =signature

Around line 184:

Unknown directive: =metadata

Around line 232:

Unknown directive: =function

Around line 238:

Unknown directive: =signature

Around line 242:

Unknown directive: =metadata

Around line 280:

Unknown directive: =function

Around line 285:

Unknown directive: =signature

Around line 289:

Unknown directive: =metadata

Around line 321:

Unknown directive: =function

Around line 329:

Unknown directive: =signature

Around line 333:

Unknown directive: =metadata

Around line 382:

Unknown directive: =function

Around line 388:

Unknown directive: =signature

Around line 392:

Unknown directive: =metadata

Around line 429:

Unknown directive: =function

Around line 435:

Unknown directive: =signature

Around line 439:

Unknown directive: =metadata

Around line 475:

Unknown directive: =function

Around line 480:

Unknown directive: =signature

Around line 484:

Unknown directive: =metadata

Around line 520:

Unknown directive: =function

Around line 526:

Unknown directive: =signature

Around line 530:

Unknown directive: =metadata

Around line 556:

Unknown directive: =function

Around line 562:

Unknown directive: =signature

Around line 566:

Unknown directive: =metadata

Around line 607:

Unknown directive: =function

Around line 614:

Unknown directive: =signature

Around line 618:

Unknown directive: =metadata

Around line 656:

Unknown directive: =function

Around line 663:

Unknown directive: =signature

Around line 667:

Unknown directive: =metadata

Around line 707:

Unknown directive: =function

Around line 713:

Unknown directive: =signature

Around line 717:

Unknown directive: =metadata

Around line 768:

Unknown directive: =function

Around line 773:

Unknown directive: =signature

Around line 777:

Unknown directive: =metadata

Around line 859:

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

Around line 872:

Unknown directive: =function

Around line 878:

Unknown directive: =signature

Around line 882:

Unknown directive: =metadata

Around line 919:

Unknown directive: =function

Around line 924:

Unknown directive: =signature

Around line 928:

Unknown directive: =metadata

Around line 985:

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

Around line 996:

Unknown directive: =function

Around line 1003:

Unknown directive: =signature

Around line 1007:

Unknown directive: =metadata

Around line 1056:

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

Around line 1066:

Unknown directive: =function

Around line 1072:

Unknown directive: =signature

Around line 1076:

Unknown directive: =metadata

Around line 1112:

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

Around line 1122:

Unknown directive: =function

Around line 1129:

Unknown directive: =signature

Around line 1133:

Unknown directive: =metadata

Around line 1190:

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

Around line 1202:

Unknown directive: =partials