The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Data::Object

ABSTRACT

Modern Perl Development Framework and Standard Library

SYNOPSIS

  # Root Namespace and Type Library
  package App;

  use Data::Object 'Library';

  # Type Library Aware Application Class
  package User;

  use Data::Object 'Class', 'App';

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

  method greet(User $user) {
    return 'Hello '. $user->name .', How are you?';
  }

  # Type Library Aware Application Package
  package main;

  use User;

  use Data::Object 'Core', 'App';

  fun greetings(User $u1, User $u2) {
    return $u1->greet($u2);
  }

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

  say(greetings($u1, $u2)); # Hey June

  1;

DESCRIPTION

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

This framework aims to provide a standardized and cohesive set of classes, types, objects, functions, patterns, and tools for jump-starting application development with modern conventions and best practices.

INSTALLATION

If you have cpanm, you only need one line:

  $ cpanm -qn Data::Object

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

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

Add Data::Object to the list of dependencies in cpanfile:

  requires "Data::Object" => "0.97"; # 0.97 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.

OVERVIEW

The power of this framework comes from the extendable (yet fully optional) type library which is integrated into the object system and type-constrainable subroutine signatures (supporting functions, methods and method modifiers). We also provide classes which wrap Perl 5 native data types and provides methods for operating on the data.

Contrary to popular opinion, modern Perl programming can be extremely well-structured and beautiful, leveraging many advanced concepts found on other languages, and some which aren't. Abilities like method modification also referred to as augmenting, 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).

  use Data::Object;

This is what's enabled whenever you import the Data::Object framework.

  # basics
  use strict;
  use warnings;

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

  # loads types and signatures
  use Data::Object::Library;
  use Data::Object::Signatures;

  # load super "do" function, etc
  use Data::Object::Export;

To explain the example in the synopsis: The following creates a class representing a user which has the ability to greet user person.

  package User;

  use Data::Object 'Class', 'App';

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

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

  1;

The following is a script that creates a function that returns how one user greets another user.

  #!/usr/bin/perl

  use User;

  use Data::Object 'Core', 'App';

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

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

  say(greetings($u1, $u2)); # Hey 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. It's important to note that in order for the code above to execute, the App type library must exist. This could be as simple as:

  package App;

  use Data::Object 'Library';

  1;

That having been explained, it's also important to note that while this example showcases much of what's possible with this framework, all of the sophistication is totally optional. For example, method and function signatures are optionally typed, so the declarations would work just as well without the types specified. In fact, you could then remove the App type library declarations from both packages and even resort rewriting the method and function as plain-old Perl subroutines. This flexibility to be able to enable more advanced capabilities is common in the Perl ecosystem and is one of the things we love most. The wiring-up of things! If you're familiar with Perl, this framework is in-part the wiring up of Moo (with Moose support), Type::Tiny, Function::Parameters, Try::Tiny and data objects in a cooperative and cohesive way that feels like it's native to the language.

FUNCTIONS

This package implements the following functions.

any

  any(Any $arg) : Object

The any constructor function returns a Data::Object::Any object for given argument.

any example
  # given \*main

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

array

  array(ArrayRef $arg) : Object

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]);

code

  code(CodeRef $arg) : Object

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) : Object

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) : Object

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) : Object

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});

integer

  integer(Int $arg) : Object

The integer constructor function returns a Data::Object::Integer object for given argument.

integer example
  # given -123

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

number

  number(Num $arg) : Object

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) : Object

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) : Object

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) : Object

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(Undef $arg?) : Object

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

undef example
  # given undef

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

METHODS

This package implements the following methods.

new

  new(Str $arg) : Object

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