Venus::Mixin

Mixin Builder

Mixin Builder for Perl 5

function: attr function: base function: catch function: error function: false function: from 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::Mixin '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';

mixin '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 mixin builder which when used causes the consumer to inherit from Venus::Core::Mixin which provides mixin building and lifecycle hooks. A mixin can do almost everything that a role can do but differs from a "role" in that whatever routines are declared using "export" will be exported and will overwrite routines of the same name in the consumer.

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::Mixin;

attr 'name';

# "Example"

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::Mixin;

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.02', }

=example-1 catch

package Ability;

use Venus::Mixin 'catch';

sub attempt_catch {
  catch {die};
}

sub EXPORT {
  ['attempt_catch']
}

package Example;

use Venus::Class 'with';

mixin 'Ability';

package main;

my $example = Example->new;

my $error = $example->attempt_catch;

$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.02', }

=example-1 error

package Ability;

use Venus::Mixin 'error';

sub attempt_error {
  error;
}

sub EXPORT {
  ['attempt_error']
}

package Example;

use Venus::Class 'with';

with 'Ability';

package main;

my $example = Example->new;

my $error = $example->attempt_error;

# 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::Mixin;

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::Role;

attr 'startup';
attr 'shutdown';

sub EXPORT {
  ['startup', 'shutdown']
}

package Record;

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;

with 'Entity';

from 'Record';

# "Example"

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::Mixin;

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.02', }

=example-1 raise

package Ability;

use Venus::Mixin 'raise';

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

sub EXPORT {
  ['attempt_raise']
}

package Example;

use Venus::Class 'with';

with 'Ability';

package main;

my $example = Example->new;

my $error = $example->attempt_raise;

# 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

49 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 56:

Unknown directive: =synopsis

Around line 155:

Unknown directive: =description

Around line 168:

Unknown directive: =function

Around line 173:

Unknown directive: =signature

Around line 177:

Unknown directive: =metadata

Around line 207:

Unknown directive: =function

Around line 213:

Unknown directive: =signature

Around line 217:

Unknown directive: =metadata

Around line 254:

Unknown directive: =function

Around line 260:

Unknown directive: =signature

Around line 264:

Unknown directive: =metadata

Around line 310:

Unknown directive: =function

Around line 315:

Unknown directive: =signature

Around line 319:

Unknown directive: =metadata

Around line 365:

Unknown directive: =function

Around line 371:

Unknown directive: =signature

Around line 375:

Unknown directive: =metadata

Around line 411:

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

Around line 421:

Unknown directive: =function

Around line 427:

Unknown directive: =signature

Around line 431:

Unknown directive: =metadata

Around line 483:

Unknown directive: =function

Around line 488:

Unknown directive: =signature

Around line 492:

Unknown directive: =metadata

Around line 574:

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

Around line 587:

Unknown directive: =function

Around line 593:

Unknown directive: =signature

Around line 597:

Unknown directive: =metadata

Around line 644:

Unknown directive: =function

Around line 649:

Unknown directive: =signature

Around line 653:

Unknown directive: =metadata

Around line 710:

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

Around line 721:

Unknown directive: =function

Around line 728:

Unknown directive: =signature

Around line 732:

Unknown directive: =metadata

Around line 780:

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

Around line 790:

Unknown directive: =function

Around line 796:

Unknown directive: =signature

Around line 800:

Unknown directive: =metadata

Around line 836:

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

Around line 846:

Unknown directive: =function

Around line 853:

Unknown directive: =signature

Around line 857:

Unknown directive: =metadata

Around line 914:

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

Around line 925:

Unknown directive: =partials