## 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 strict;
    use warnings;

    use OP qw| :all |;

    create "YourApp::Example" => { };
### assert variable types Asserted types map to same-named database table columns.
    create "YourApp::Example" => {
      favoriteNumber => OP::Int->assert(
        subtype(
          optional => true
        )
      ),

      favoriteColor  => OP::Str->assert(
        qw| red green blue |,
        subtype(
          optional => true
        )
      ),
    };
By default, instances have attributes: 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 key constraint Use OP::ExtID:
    create "YourApp::ThisClass" => {
      relatedId => OP::ExtID->assert(
        "YourApp::OtherClass"
      ),
    };
| ### class method Inline:
    create "YourApp::Example" => {
      someMethod => sub {
        my $class = shift;

        # ...
      },

    };
### instance method Inline:
    create "YourApp::Example" => {
      someMethod => sub {
        my $self = shift;

        # ...
      },

    };
### collect array elements
    my $collected = $array->collect( sub {
      my $item = shift;

      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, ...];
    } );
OP | Framework loader
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 key
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(...)).