NAME

Jojo::Base - Mojo::Base + lexical "has"

VERSION

version 0.7.0

SYNOPSIS

  package Cat {
    use Jojo::Base -base;    # requires perl 5.18+

    has name => 'Nyan';
    has ['age', 'weight'] => 4;
  }

  package Tiger {
    use Jojo::Base 'Cat';

    has friend => sub { Cat->new };
    has stripes => 42;
  }

  package main;
  use Jojo::Base -strict;

  my $mew = Cat->new(name => 'Longcat');
  say $mew->age;
  say $mew->age(3)->weight(5)->age;

  my $rawr = Tiger->new(stripes => 38, weight => 250);
  say $rawr->tap(sub { $_->friend->name('Tacgnol') })->weight;

DESCRIPTION

Jojo::Base works kind of like Mojo::Base but has is imported as lexical subroutine.

Jojo::Base, like Mojo::Base, is a simple base class designed to be effortless and powerful.

  # Enables "strict", "warnings", "utf8" and Perl 5.18 and "lexical_subs" features
  use Jojo::Base -strict;
  use Jojo::Base -base;
  use Jojo::Base 'SomeBaseClass';
  use Jojo::Base -role;

All four forms save a lot of typing. Note that role support depends on Jojo::Role (0.5.0+).

  # use Jojo::Base -strict;
  use strict;
  use warnings;
  use utf8;
  use feature ':5.18';
  use experimental 'lexical_subs';
  use IO::Handle ();

  # use Jojo::Base -base;
  use strict;
  use warnings;
  use utf8;
  use feature ':5.18';
  use experimental 'lexical_subs';
  use IO::Handle ();
  push @ISA, 'Jojo::Base';
  state sub has { ... }    # attributes
  state sub with { ... }   # role composition

  # use Jojo::Base 'SomeBaseClass';
  use strict;
  use warnings;
  use utf8;
  use feature ':5.18';
  use experimental 'lexical_subs';
  use IO::Handle ();
  require SomeBaseClass;
  push @ISA, 'SomeBaseClass';
  state sub has { ... }    # attributes
  state sub with { ... }   # role composition

  # use Jojo::Base -role;
  use strict;
  use warnings;
  use utf8;
  use feature ':5.18';
  use experimental 'lexical_subs';
  use IO::Handle ();
  use Jojo::Role;
  state sub has { ... }    # attributes

On Perl 5.20+ you can also append a -signatures flag to all four forms and enable support for subroutine signatures.

  # Also enable signatures
  use Jojo::Base -strict, -signatures;
  use Jojo::Base -base, -signatures;
  use Jojo::Base 'SomeBaseClass', -signatures;
  use Jojo::Base -role, -signatures;

This will also disable experimental warnings on versions of Perl where this feature was still experimental.

DIFFERENCES FROM Mojo::Base

  • All functions are exported as lexical subs

  • Role support depends on Jojo::Role instead of Role::Tiny

  • with is exported alongside has (when Jojo::Role is available)

  • Feature bundle for Perl 5.18 is enabled by default, instead of 5.10

  • Support for lexical subroutines is enabled by default

FUNCTIONS

Jojo::Base implements the following functions, which can be imported with the -base flag, or by setting a base class.

has

  has 'name';
  has ['name1', 'name2', 'name3'];
  has name => 'foo';
  has name => sub {...};
  has ['name1', 'name2', 'name3'] => 'foo';
  has ['name1', 'name2', 'name3'] => sub {...};

Create attributes for hash-based objects, just like the "attr" in Mojo::Base method.

with

  with 'SubClass::Role::One';
  with '+One', '+Two';

Composes the current package with one or more Jojo::Role roles. For roles following the naming scheme MyClass::Role::RoleName you can use the shorthand +RoleName. Note that role support depends on Jojo::Role (0.5.0+).

It works with Jojo::Role or Role::Tiny roles.

METHODS

Jojo::Base inherits all methods from Mojo::Base and implements the following new ones.

with_roles

  my $new_class = SubClass->with_roles('SubClass::Role::One');
  my $new_class = SubClass->with_roles('+One', '+Two');
  $object       = $object->with_roles('+One', '+Two');

Create a new class with one or more roles. If called on a class returns the new class, or if called on an object reblesses the object into the new class. For roles following the naming scheme MyClass::Role::RoleName you can use the shorthand +RoleName. Note that role support depends on Jojo::Role (0.5.0+).

  # Create a new class with the role "SubClass::Role::Foo" and instantiate it
  my $new_class = SubClass->with_roles('+Foo');
  my $object    = $new_class->new;

It works with Jojo::Role or Role::Tiny roles.

CAVEATS

  • Jojo::Base requires perl 5.18 or newer

  • Because a lexical sub does not behave like a package import, some code may need to be enclosed in blocks to avoid warnings like

        "state" subroutine &has masks earlier declaration in same scope at...

SEE ALSO

Mojo::Base, Jojo::Role.

ACKNOWLEDGMENTS

Thanks to Sebastian Riedel and others, the authors and copyright holders of Mojo::Base.

AUTHOR

Adriano Ferreira <ferreira@cpan.org>

COPYRIGHT AND LICENSE

This software is Copyright (c) 2017 by Adriano Ferreira.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)