=head1 NAME

Object::Simple::Guide -  Object::Simple Guide

=head1 GUIDE

=head2 1. Generate accessor

At first, you create a class extending L<Object::Simple>
to use methods of L<Object::Simple>.

    package SomeClass;
    
    use base 'Object::Simple';

L<Object::Simple> have C<new()> method. This is a constructor.
It can receive hash and hash reference as arguments.
    
    my $obj = SomeClass->new;
    my $obj = SomeClass->new(foo => 1, bar => 2);
    my $obj = SomeClass->new({foo => 1, bar => 2});

You can generate accessor by C<attr()> method.

    __PACKAGE__->attr('foo');

You can set and get the value by accessor.

    # Set the value
    $obj->foo(1);
    
    # Get the value
    my $foo = $obj->foo;

You can specify a default value for the accessor.

    __PACKAGE__->attr(foo => 1);

If the value of C<foo> is not exists and C<foo()> is called,
You can get the default value.

    my $default_value = $obj->foo;

If you want to specify a reference or object as default value,
it must be sub reference, whose return value is the default value.
This is requirment not to share the default value with other objects.

    __PACKAGE__->attr(foo => sub { [] });
    __PACKAGE__->attr(foo => sub { {} });
    __PACKAGE__->attr(foo => sub { SomeClass->new });

You can generate accessors at once.

    __PACKAGE__->attr([qw/foo bar baz/]);
    __PACKAGE__->attr([qw/foo bar baz/] => 0);

You can create accessor more easily.

    __PACKAGE__->attr(
        some => 1,
        other => sub { 5 }
    );

If arguments count is odd number, first argument is
for accessor not having default value.

    __PACKAGE__->attr(
        [qw/foo bar baz/],
        some => 1,
        other => sub { 5 }
    );

This is most easy way of accessor definition.

B<Example:>

I show a example to understand L<Object::Simple> well.

Point class, which have two attribute, C<x> and C<y>,
and C<clear()> method to set C<x> and C<y> to 0.

    package Point;
    
    use strict;
    use warnings;
    
    use base 'Object::Simple';

    __PACKAGE__->attr(x => 0);
    __PACKAGE__->attr(y => 0);
    
    sub clear {
        my $self = shift;
        
        $self->x(0);
        $self->y(0);
    }

Point3D class, which inherit L<Point> class.
This class has C<z> attribute in addition to C<x> and C<y>.
C<clear()> method is overridden to clear C<x>, C<y> and C<z>.
    
    package Point3D;
    
    use strict;
    use warnings;
    
    use base 'Point';
    
    __PACKAGE__->attr(z => 0);
    
    sub clear {
        my $self = shift;
        
        $self->SUPER::clear();
        
        $self->z(0);
    }

=head2 2. Concepts of Object-Oriented programing

=head3 Inheritance

I explain the essence of Object-Oriented programing
to use L<Object::Simple> well.

First concept of Object-Oriented programing is Inheritance.
Inheritance means that
If Class Q inherit Class P, Class Q can call all method of class P.

    +---+
    | P | Base class
    +---+   having method1() and method2()
      |
    +---+
    | Q | Sub class
    +---+   having method3()

Class Q inherits Class P,
so Q can call all methods of P in addition to methods of Q.
In other words, Q can call
C<method1()>, C<method2()>, and C<method3()>

To inherit a class, use L<base> module.

    package P;
    
    sub method1 { ... }
    sub method2 { ... }
    
    package Q;
    
    use base 'P';
    
    sub method3 { ... }

Perl has useful functions and methods to help Object-Oriented programing.

To know the object is belong to what class, use C<ref()> function.

    my $class = ref $obj;

To know whether the object inherits the specified class, use C<isa()> method.

    $obj->isa('SomeClass');

To know whether the object(or class)
can call the specified method,
use C<can()> method 

    SomeClass->can('method1');
    $obj->can('method1');

=head3 Capsulation

Second concept of Object-Oriented programing is capsulation.
Capsulation means that
you don't touch internal data directory.
You must use public methods in documentation.
If you keep this rule, All the things become simple.

To keep this rule,
Use accessor to get and set to the value.

    my $value = $obj->foo;
    $obj->foo(1);

To access the value directory is bad manner.

    my $value = $obj->{foo}; # Bad manner!
    $obj->{foo} = 1;         # Bad manner!

=head3 Polymorphism

Third concept Object-Oriented programing is polymorphism.
Polymorphism is devieded into two concepts,
overloading and overriding.

Perl programer don't have to care overloading.
Perl is dynamic language,
so subroutine can receive any value.
Overloading is worth for languages having static type variable,
like C++ or Java.

Overriding means that in sub class you can change the process of the base class's method.

    package P;
    
    sub method1 { return 1 }
    
    package Q;
    
    use base 'P';
    
    sub method1 { return 2 }

C<method1()> of class P return 1. C<method1()> of class Q return 2.
That is to say, C<method1()> is overridden in class Q.

    my $obj_a = P->new;
    $obj_p->method1; # Return value is 1
    
    my $obj_b = Q->new;
    $obj_q->method1; # Return value is 2

If you want to call the method of base class from sub class,
use SUPER pseudo-class.

    package Q;
    
    sub method1 {
        my $self = shift;
        
        my $value = $self->SUPER::method1(); # return value is 1
        
        return 2 + $value;
    }

If you understand only these three concepts,
you can do enough powerful Object-Oriented programming.
and source code is readable for other language users.

=head2 3. Offten used techniques

=head3 Override new() method

C<new()> method is overridden if needed.

B<Example:>

Initialize the object

    sub new {
        my $self = shift->SUPER::new(@_);
        
        # Initialization
        
        return $self;
    }

B<Example:>

Change arguments of C<new()>.
    
    sub new {
        my $self = shift;
        
        $self->SUPER::new(x => $_[0], y => $_[1]);
        
        return $self;
    }

You can pass array to C<new()> method by overridden C<new()> method.

    my $point = Point->new(4, 5);

=head2 4. Other features

=head3 Strict arguments check

L<Object::Simple> pay attention to the usability.
If wrong number arguments is passed to C<new()> method,
exception is thrown.
    
    my $obj = SomeClass->new(1); # Exception!

as is the accessor.

    $obj->foo(a => 1); # Execption!

=head3 Import methods

You can import methods of L<Object::Simple>.
This is useful in case you don't want to use multiple inheritance.

    package SomeClass;
    
    use Object::Simple qw/new attr/;
    
    __PACKAGE__->attr('foo');

Note that you can't override C<new()> method
because C<new()> method is imported in the class,
not inherited from base class.

=head3 Method chain

Method chain is available because
accessor return self-object when it is called to set the value,

    $obj->foo(1)->bar(4)->baz(6);

=head1 STABILITY

L<Object::Simple> is stable.
APIs and the implementations will not be changed in the future.

=head1 DEPRECATED

C<class_attr> and C<dual_attr> is deprecated because
this is not good practice in Object Oriented programming.
To know the usages, see old documentation before 3.0612.
