OP Basics Cheat Sheet

install OP

sudo perl -MCPAN -e 'install OP'

This installs the latest stable version of OP.

You will also need DBD::mysql.

create a database

OP will create any necessary tables, but a DBA must create the initial database, as well as run any required GRANT statements.

mysql -u root -p
create database yourapp;
grant all on yourapp.* to op@localhost;

create an object class

In file YourApp/Example.pm:

use OP;

create "YourApp::Example" => { };

assert variable types

Asserted types map to same-named database table columns.

create "YourApp::Example" => {
  favoriteNumber => OP::Int->assert(
    ::optional
  ),

  favoriteColor  => OP::Str->assert(
    qw| red green blue |,
    ::optional
  ),
};

By default, instances will already have: id, name, ctime, and mtime.

make a new object

use YourApp::Example;

my $class = "YourApp::Example";

my $example = $class->new(
  name => "HelloWorld"
);

save an object

$example->save;

load an object

Load by GUID:

my $example = $class->load($id);

Load by Name:

my $example = $class->loadByName("HelloWorld");

remove an object

$example->remove

query the database

Use DBI statement handles:

my $sth = $class->query(
  sprintf q| select id, name from %s |,
    $class->tableName
);

while ( my @row = $sth->fetchrow_array ) {
  print join ",", @row;
  print "\n";
};

set, get, and delete an attribute

Explicit:

$example->setFavoriteColor("blue");

my $color = $example->favoriteColor;

$example->deleteFavoriteColor;

Iterative:

$example->set("favoriteColor", "blue");

my $color = $example->get("favoriteColor");

$example->delete("favoriteColor");

dump object to json or yaml

my $json = $object->toJson;

my $yaml = $object->toYaml;

#
# Prints YAML
#
$object->print;

load json or yaml as object

my $examp1 = $class->loadJson($json);

my $examp2 = $class->loadYaml($yaml);

assert a foreign id constraint

Use OP::ExtID:

create "YourApp::ThisClass" => {
  relatedId => OP::ExtID->assert(
    "YourApp::OtherClass"
  ),
};

class method

Inline:

create "YourApp::Example" => {
  someMethod => method(OP::Class $class:) {
    print "No need to shift $class etc\n";
  },

  methodWithArgs => method(
    OP::Class $class: Str $arg, *@slurp
  ) {
    print "No need to shift $class etc\n";
  },

};

Free standing:

method methodWithArgs(
  OP::Class $class: Str $arg, *@slurp
) {
  print "No need to shift $class etc\n";
};

instance method

Inline:

create "YourApp::Example" => {
  someMethod => method() {
    print "No need to shift $self etc\n";
  },

  methodWithArgs => method(Str $arg, *@slurp) {
    print "No need to shift $self etc\n";
  },

};

Free standing:

method methodWithArgs(Str $arg, *@slurp) {
  print "No need to shift $self etc\n";
};
OP Framework loader
OP::Any Wrapper for any type of variable
OP::Array List
OP::Bool Overloaded boolean
OP::DateTime Overloaded time object
OP::Domain Overloaded domain name
OP::Double Overloaded double precision number
OP::EmailAddr Overloaded email address
OP::ExtID Overloaded foreign GUID
OP::Float Overloaded floating point number
OP::Hash Hashtable
OP::ID Overloaded GUID
OP::IPv4Addr Overloaded IPv4 address
OP::Int Overloaded integer
OP::Name A unique secondary key
OP::Num Overloaded number
OP::Rule Regex
OP::Str Overloaded string
OP::TimeSpan Overloaded time range object
OP::URI Overloaded URI

OP classes may be instantiated ($class->new(...)), or declared as inline attributes ($class->assert(...)).

collect array elements

my $collected = $array->collect( sub(Any $item) {
  print "Working with element $item\n"

  return if $item == $foo; # Yield nothing

  break if $item == $bar;  # Stop collecting

  # Upstream $things, continue curr iteration:
  emit $thing1, [$thing2, ...];

  # Upstream $things, skip to next iteration:
  yield $thing1, [$thing2, ...];
} );