Introduction to Object Orientation

Dave Rolsky

What is OO For?

None of the Above

The Value of OO

OO is Just One Paradigm

Perl is Multi-Paradigm

Why Moose?

OO?

An Object Has Methods

An Object Is ...

Data + Operations

Class?

Perl Classes

Perl Objects

# Never actually write this!
my $object = bless {}, 'MyClass';

use Scalar::Util 'blessed';
if ( blessed($object) { ... }

print blessed $object; # MyClass

Constructors

A Very Simple Class

package File;
use Moose;

Slightly Less Simple Class

package File;
use Moose;

has path => ( is => 'ro' );

Making a File Object

use File;

my $file =
    File->new( path => 'path/to/file' );

Method Invocation

Defining Methods

package File;

sub write {
    my $self = shift;

    # do something with file content
}

Method Invocation (again)

my $file = File->new(
    path    => 'path/to/file',
    content => $content,
);

$file->write();

Method Invocation

# Never write this!
File::write($file);

Method Parameters

package File;

sub rename {
    my $self     = shift;
    my $new_name = shift;

    # do something with new name
}

Passing Parameters

$file->rename('new-name.foo');

# Bad code again
File::rename( $file, 'new-name.foo' );

Method Resolution

# Don't copy this
my $object = bless {}, $class_name;

Public Versus Private

Public/Private Conventions

Object Construction

Writing a Constructor

package File;
use Moose;

# This now works
my $file = File->new();

An Alternate Constructor

sub open {
    my ( $class, $path ) = @_;

    open my $fh, '<', $path or die $!;
    my $content = do { local $/; <$fh> };

    return $class->new(
        path    => $path,
        content => $content,
    );
}

my $file = File->open( 'path/to/file' );

Attributes

Setting Attributes

Attribute Example

package File;
use Moose;

has path    => ( is => 'ro' );
has content => ( is => 'rw' );

Attribute Example

my $file =
    File->new( path => 'path/to/file' );
$file->content($new_content);

Defining Attributes

Attribute Read-(Only|Write)

Attribute Accessors

Accessor Types

Accessor Naming

Attribute Values

What's in a Class?

What's in a Class?

Minimal Class Example

package File;
use Moose;
use autodie;

has path    => ( is => 'ro' );
has content => ( is => 'rw' );

sub write {
    my $self = shift;

    open my $fh, '>', $self->path();
    print {$fh} $self->content();
}

Intermission

Inheritance, Roles, Polymorphism

Inheritance

Why Subclass?

Inheritance Defined

Inheritance Example

Inheritance in Code

package File::MP3;
use Moose;

extends 'File';

Overriding Methods

Overriding Example

package File::MP3;
use Moose;
extends 'File';

has title => ( is => 'ro' );

override write => sub {
    my $self = shift;

    # make sure content contains mp3 tags

    super();
};

Inheritance Continued

Method Resolution

Polymorphism

Polymorphism Versus If/Then

if ( $file->{type} eq 'mp3' ) {
    # write file with title tag
} else {
    # write file
}

# Polymorphism lets us write ...
$file->write();

Why Polymorphism Matters

Encapsulation

Why Encapsulation Matters

Encapsulation How-To

Overloading

Overloading Example

package File;
use Moose;

use overload q{""} => 'as_string';

sub as_string {
    my $self = shift;

    return 'File: ' . $self->path();
}

print File->new( path => 'foo/bar' );
# File: foo/bar

Roles

Roles and Classes

Roles Versus Classes

What's in a Role?

Simple Role Example

package Comparable;
use Moose::Role;

requires 'compare';

Another Role Example

package HasLogger;
use Moose::Role;

has logger => ( is => 'ro' );

sub log {
    my $self = shift;
    $self->logger()->log(@_);
}

Consuming Roles

package File;
use Moose;

with 'HasLogger';

Consuming Multiple Roles

package File;
use Moose;

with 'Comparable', 'HasLogger';

sub compare { ... }

Roles Versus Inheritance

Roles and Polymorphism

Role Introspection

if ( $object->does('Comparable')
     && $other->does('Comparable') ) {
    if ( $object->compare($other) ) {
        print "They're the same\n";
    }
    else {
        print "They're not the same\n";
    }
}
else {
    print "They're not comparable\n";
}

Composition

Composition Example

package File;
use Moose;

has last_mod => (
    is  => 'ro',
    isa => 'DateTime',
);

print $file->last_mod()->ymd();

Composition

Delegation

Delegation Example

package File;
use Moose;

has last_mod => (
    is      => 'ro',
    isa     => 'DateTime',
    handles => { last_mod_ymd => 'ymd' },
);

print $file->last_mod_ymd();

Delegation Is Good

Advice

When to Use OO

When to Use OO

When to Use OO

When to Use OO

Live (Clothed) Coding

Questions?

More Information

The End