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

NAME

Data::Object

ABSTRACT

Development Framework

SYNOPSIS

  package User;

  use Data::Object 'Class';

  extends 'Identity';

  has 'fname';
  has 'lname';

  1;

DESCRIPTION

This package aims to provide a modern Perl development framework and foundational set of types, functions, classes, patterns, and interfaces for jump-starting application development. This package inherits all behavior from Data::Object::Config, and offers the same functionality as the Do package. Please see that documentation to learn more, or get started quickly by reviewing basic usage, configurations, the overview, and the project wiki.

OVERVIEW

The following describes this distribution in a few key points:

  • It enables advanced object-orientation

  • It provides a pluggable standard library (of sorts)

  • It enables sane defaults on import (strict, warnings, say, etc)

  • It enables calling methods on native data types

  • It enables type-constrainable class attributes and subroutine signatures

  • It enables user-defined type libraries with simple syntax

  • It's all modular; i.e. use as much, or as little, as is needed

CONVENTION

Contrary to the opinion of some, modern Perl programming can be extremely well-structured and beautiful, leveraging many advanced concepts found in other languages, and some which aren't. Abilities like method modification also referred to as augmentation, reflection, advanced object-orientation, type-constrainable object attributes, type-constrainable subroutine signatures (with named and positional arguments), as well roles (similar to mixins or interfaces in other languages). This framework aims to serve as an entrypoint to leveraging those abilities.

  use Do;

The "Do" package is an alias and subclass of this package. It encapsulates all of the framework's features, is minimalist, and is meant to be the first import in a new class or module.

  use Data::Object;

Both import statements are funcationally equivalent, enable the same functionality, and can be configured equally. This is what's enabled whenever you import the "Do" or "Data::Object" package into your namespace.

  # basics
  use strict;
  use warnings;

  # loads say, state, switch, etc
  use feature ':5.14';

  # loads type constraints
  use Data::Object::Library;

  # loads function/method signatures
  use Data::Object::Signatures;

  # imports keywords and super "do" function, etc
  use Data::Object::Export;

  # enables method calls on native data types
  use Data::Object::Autobox;

To explain by way of example: The following established a user-defined type library where user-defined classes, roles, etc, will be automatically registered.

  package App;

  use Do 'Library';

  1;

The following creates a class representing a user which has the ability to greet another person. This class is type-library aware and will register itself as a type constraint.

  package App::User;

  use Do 'Class', 'App';

  has name => (
    is  => 'ro',
    isa => 'Str',
    req => 1
  );

  method hello(AppUser $user) {
    return 'Hello '. $user->name .'. How are you?';
  }

  1;

The following is a script which is type-library aware that creates a function that returns how one user greets another user.

  package main;

  use App::User;

  use Do 'Core', 'App';

  fun greetings(AppUser $u1, AppUser $u2) {
    return $u1->hello($u2);
  }

  my $u1 = User->new(name => 'Jane');
  my $u2 = User->new(name => 'June');

  say(greetings($u1, $u2)); # Hello June ...

This demonstrates much of the power of this framework in one simple example. If you're new to Perl, the code above creates a class with a single (read-only string) attribute called name and a single method called hello, then registers the class in a user-defined type-library called App where all user-defined type constraints will be stored and retrieved (and reified). The main program (namespace) initializes the framework and specifies the user-defined type library to use in the creation of a single function greetings which takes two arguments which must both be instances of the class we just created.

FRAMEWORK

The Data-Object framework is a robust modern Perl development framework, embracing Perl's multi-paradigm programming nature, flexibility and vast ecosystem that many engineers already know and love.

keywords

  package main;

  use Do;

  raise 'Oops';

  1;

The framework automatically makes the following short list of new keyword functions available to the calling package: cast, const, do, is_false, is_true, false, true, and raise. Please see Data::Object::Export for details on each keyword function.

core

  package main;

  use Do;

  fun main() {
    # ...
  }

  1;

The framework's core configuration enables strict, warnings, Perl's 5.14 features, and configures the core type library, method signatures, and autoboxing.

library

  package App::Library;

  use Do 'Library';

  our $User = declare 'User',
    as InstanceOf["App::User"];

  1;

The framework's library configuration established a Type::Library compliant type library, as well as configuring Type::Utils in the calling package. Read more at Data::Object::Library.

class

  package App::User;

  use Do 'Class';

  has 'fname';
  has 'lname';

  1;

The framework's class configuration configures the calling package as a Moo class, having the "has", "with", and "extends" keywords available. Read more at Data::Object::Class.

role

  package App::Queuer;

  use Do 'Role';

  has 'queue';

  method dequeue() {
    # ...
  }

  method enqueue($job) {
    # ...
  }

  1;

The framework's role configuration configures the calling package as a Moo role, having the "has", "with", and "extends" keywords available. Read more at Data::Object::Role.

rule

  package App::Queueable;

  use Do 'Rule';

  requires 'dequeue';
  requires 'enqueue';

  1;

The framework's rule configuration configures the calling package as a Moo role, intended to be used to classify interfaces. Read more at Data::Object::Rule.

state

  package App::Env;

  use Do 'State';

  has 'vars';
  has 'args';
  has 'opts';

  1;

The framework's state configuration configures the calling package as a singleton class with global state. Read more at Data::Object::State.

struct

  package App::Data;

  use Do 'Struct';

  has 'auth';
  has 'user';
  has 'args';

  1;

The framework's struct configuration configures the calling package as a class whose state becomes immutable after instantiation. Read more at Data::Object::Struct.

args

  package App::Args;

  use Do 'Args';

  method validate() {
    # ...
  }

  1;

The framework's args configuration configures the calling package as a class representation of the @ARGV variable. Read more at Data::Object::Args.

array

  package App::Args;

  use Do 'Array';

  method command() {
    return $self->get(0);
  }

  1;

The framework's array configuration configures the calling package as a class which extends the Array class. Read more at Data::Object::Array.

code

  package App::Func;

  use Do 'Code';

  around BUILD($args) {
    $self->$orig($args);

    # ...
  }

  1;

The framework's code configuration configures the calling package as a class which extends the Code class. Read more at Data::Object::Code.

cli

  package App::Cli;

  use Do 'Cli';

  method main(%args) {
    # ...
  }

  1;

The framework's cli configuration configures the calling package as a class capable of acting as a command-line interface. Read more at Data::Object::Cli.

data

  package App::Data;

  use Do 'Data';

  method generate() {
    # ...
  }

  1;

The framework's data configuration configures the calling package as a class capable of parsing POD. Read more at Data::Object::Data.

float

  package App::Amount;

  use Do 'Float';

  method currency(Str $code) {
    # ...
  }

  1;

The framework's float configuration configures the calling package as a class which extends the Float class. Read more at Data::Object::Float.

hash

  package App::Data;

  use Do 'Hash';

  method logline() {
    # ...
  }

  1;

The framework's hash configuration configures the calling package as a class which extends the Hash class. Read more at Data::Object::Hash.

number

  package App::ID;

  use Do 'Number';

  method find() {
    # ...
  }

  1;

The framework's number configuration configures the calling package as a class which extends the Number class. Read more at Data::Object::Number.

opts

  package App::Opts;

  use Do 'Opts';

  method validate() {
    # ...
  }

  1;

The framework's opts configuration configures the calling package as a class representation of the command-line arguments. Read more at Data::Object::Opts.

regexp

  package App::Path;

  use Do 'Regexp';

  method match() {
    # ...
  }

  1;

The framework's regexp configuration configures the calling package as a class which extends the Regexp class. Read more at Data::Object::Regexp.

scalar

  package App::OID;

  use Do 'Scalar';

  method find() {
    # ...
  }

  1;

The framework's scalar configuration configures the calling package as a class which extends the Scalar class. Read more at Data::Object::Scalar.

string

  package App::Title;

  use Do 'String';

  method generate() {
    # ...
  }

  1;

The framework's string configuration configures the calling package as a class which extends the String class. Read more at Data::Object::String.

undef

  package App::Fail;

  use Do 'Undef';

  method explain() {
    # ...
  }

  1;

The framework's undef configuration configures the calling package as a class which extends the Undef class. Read more at Data::Object::Undef.

vars

  package App::Vars;

  use Do 'Vars';

  method config() {
    # ...
  }

  1;

The framework's vars configuration configures the calling package as a class representation of the %ENV variable. Read more at Data::Object::Vars.

METHODS

This package implements the following methods.

array

  array(ArrayRef $arg) : ArrayObject

The array constructor function returns a Data::Object::Array object for given argument.

array example
  # given [1..4]

  my $object = Data::Object->array([1..4]);

boolean

  boolean(Any $arg) : BooleanObject

The boolean constructor function returns a Data::Object::Boolean object for the given argument.

boolean example
  # given 1

  my $bool = Data::Object->boolean(1); # true

code

  code(CodeRef $arg) : CodeObject

The code constructor function returns a Data::Object::Code object for given argument.

code example
  # given sub { shift + 1 }

  my $object = Data::Object->code(sub { $_[0] + 1 });

exception

  exception(HashRef $arg) : ExceptionObject

The exception constructor function returns a Data::Object::Exception object for given argument.

exception example
  # given { message => 'Oops' }

  my $object = Data::Object->exception({ message => 'Oops' });

float

  float(Num $arg) : FloatObject

The float constructor function returns a Data::Object::Float object for given argument.

float example
  # given 1.23

  my $object = Data::Object->float(1.23);

hash

  hash(HashRef $arg) : HashObject

The hash constructor function returns a Data::Object::Hash object for given argument.

hash example
  # given {1..4}

  my $object = Data::Object->hash({1..4});

new

  new(Str $arg) : SpaceObject

The new method expects a string representing a class name under the Data::Object namespace and returns a Data::Object::Space object.

new example
  # given 'String'

  my $space = Data::Object->new('String');

  my $string = $space->build('hello world');

number

  number(Num $arg) : NumberObject

The number constructor function returns a Data::Object::Number object for given argument.

number example
  # given 123

  my $object = Data::Object->number(123);

regexp

  regexp(Regexp $arg) : RegexpObject

The regexp constructor function returns a Data::Object::Regexp object for given argument.

regexp example
  # given qr(\w+)

  my $object = Data::Object->regexp(qr(\w+));

scalar

  scalar(Any $arg) : ScalarObject

The scalar constructor function returns a Data::Object::Scalar object for given argument.

scalar example
  # given \*main

  my $object = Data::Object->scalar(\*main);

string

  string(Str $arg) : ScalarObject

The string constructor function returns a Data::Object::String object for given argument.

string example
  # given 'hello'

  my $object = Data::Object->string('hello');

undef

  undef(Maybe[Undef] $arg) : UndefObject

The undef constructor function returns a Data::Object::Undef object for given argument.

undef example
  # given undef

  my $object = Data::Object->undef(undef);

SLOGAN

If you're doing something modern with Perl, start here!

INSTALLATION

If you have cpanm, you only need one line:

  $ cpanm -qn Do

If you don't have cpanm, get it! It takes less than a minute, otherwise:

  $ curl -L https://cpanmin.us | perl - -qn Do

Add Do to the list of dependencies in cpanfile:

  requires "Do" => "1.87"; # 1.87 or newer

If cpanm doesn't have permission to install modules in the current Perl installation, it will automatically set up and install to a local::lib in your home directory. See the local::lib documentation for details on enabling it in your environment. We recommend using a Perlbrew or Plenv environment. These tools will help you manage multiple Perl installations in your $HOME directory. They are completely isolated Perl installations.

CREDITS

Al Newkirk, +319

Anthony Brummett, +10

Adam Hopkins, +2

José Joaquín Atria, +1

AUTHOR

Al Newkirk, awncorp@cpan.org

LICENSE

Copyright (C) 2011-2019, Al Newkirk, et al.

This is free software; you can redistribute it and/or modify it under the terms of the The Apache License, Version 2.0, as elucidated here, https://github.com/iamalnewkirk/do/blob/master/LICENSE.

PROJECT

Wiki

Project

Initiatives

Milestones

Contributing

Issues

SEE ALSO

To get the most out of this distribution, consider reading the following:

Do

Data::Object

Data::Object::Class

Data::Object::ClassHas

Data::Object::Role

Data::Object::RoleHas

Data::Object::Library