The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Venus::Role - Role Builder

ABSTRACT

Role Builder for Perl 5

SYNOPSIS

  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')

DESCRIPTION

This package provides a role builder which when used causes the consumer to inherit from Venus::Core::Role which provides role construction and lifecycle hooks. A role differs from a "class" in that it can't be instantiated using the new method. A role can act as an interface by defining an "audit" hook which is invoked automatically by the "test" function.

FUNCTIONS

This package provides the following functions:

attr

  attr(Str $name) (Str)

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

Since 1.00

attr example 1
  package Example;

  use Venus::Class;

  attr 'name';

  # "Example"

base

  base(Str $name) (Str)

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.

Since 1.00

base example 1
  package Entity;

  use Venus::Class;

  sub output {
    return;
  }

  package Example;

  use Venus::Class;

  base 'Entity';

  # "Example"

catch

  catch(CodeRef $block) (Error, Any)

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.

Since 1.01

catch example 1
  package Ability;

  use Venus::Role 'catch';

  sub attempt_catch {
    catch {die};
  }

  sub EXPORT {
    ['attempt_catch']
  }

  package Example;

  use Venus::Class 'with';

  with 'Ability';

  package main;

  my $example = Example->new;

  my $error = $example->attempt_catch;

  $error;

  # "Died at ..."

error

  error(Maybe[HashRef] $args) (Error)

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

Since 1.01

error example 1
  package Ability;

  use Venus::Role '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')

false

  false() (Bool)

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.

Since 1.00

false example 1
  package Example;

  use Venus::Class;

  my $false = false;

  # 0
false example 2
  package Example;

  use Venus::Class;

  my $true = !false;

  # 1

from

  from(Str $name) (Str)

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.

Since 1.00

from example 1
  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"

mixin

  mixin(Str $name) (Str)

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.

Since 1.02

mixin example 1
  package YesNo;

  use Venus::Mixin;

  sub no {
    return 0;
  }

  sub yes {
    return 1;
  }

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

  package Answer;

  use Venus::Role;

  mixin 'YesNo';

  # "Answer"
mixin example 2
  package YesNo;

  use Venus::Mixin;

  sub no {
    return 0;
  }

  sub yes {
    return 1;
  }

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

  package Answer;

  use Venus::Role;

  mixin 'YesNo';

  sub no {
    return [0];
  }

  sub yes {
    return [1];
  }

  my $package = "Answer";

  # "Answer"

raise

  raise(Str $class | Tuple[Str, Str] $class, Maybe[HashRef] $args) (Error)

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.

Since 1.01

raise example 1
  package Ability;

  use Venus::Role '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')

role

  role(Str $name) (Str)

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.

Since 1.00

role example 1
  package Ability;

  use Venus::Role;

  sub action {
    return;
  }

  package Example;

  use Venus::Class;

  role 'Ability';

  # "Example"
role example 2
  package Ability;

  use Venus::Role;

  sub action {
    return;
  }

  sub EXPORT {
    return ['action'];
  }

  package Example;

  use Venus::Class;

  role 'Ability';

  # "Example"

test

  test(Str $name) (Str)

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.

Since 1.00

test example 1
  package Actual;

  use Venus::Role;

  package Example;

  use Venus::Class;

  test 'Actual';

  # "Example"
test example 2
  package Actual;

  use Venus::Role;

  sub AUDIT {
    die "Example is not an 'actual' thing" if $_[1]->isa('Example');
  }

  package Example;

  use Venus::Class;

  test 'Actual';

  # "Example"

true

  true() (Bool)

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.

Since 1.00

true example 1
  package Example;

  use Venus::Class;

  my $true = true;

  # 1
true example 2
  package Example;

  use Venus::Class;

  my $false = !true;

  # 0

with

  with(Str $name) (Str)

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.

Since 1.00

with example 1
  package Understanding;

  use Venus::Role;

  sub knowledge {
    return;
  }

  package Example;

  use Venus::Class;

  with 'Understanding';

  # "Example"
with example 2
  package Understanding;

  use Venus::Role;

  sub knowledge {
    return;
  }

  sub EXPORT {
    return ['knowledge'];
  }

  package Example;

  use Venus::Class;

  with 'Understanding';

  # "Example"