NAME
    Pony::Object the object system.

OVERVIEW
    Pony::Object is an object system, which provides simple way to use cute
    objects.

SYNOPSIS
        use Pony::Object;

DESCRIPTION
    When some package uses Pony::Object, it's becomes strict (and shows
    warnings) and modern (can use perl 5.10 features like as "say"). Also
    "dump" function is redefined and shows data structure. It's useful for
    debugging.

  Specific moments
    Besides new function "dump" Pony::Object has other specific moments.

   has
    Keyword "has" declares new fields. All fields are public. You can also
    describe object methods via "has"... If you want.

        package News;
        use Pony::Object;
    
            # Fields
            has 'title';
            has text => '';
            has authors => [ qw/Alice Bob/ ];
        
            # Methods
            sub printTitle
                {
                    my $this = shift;
                    say $this->title;
                }

            sub printAuthors
                {
                    my $this = shift;
                    print @{ $this->authors };
                }
        1;

        package main;
    
        my $news = new News;
        $news->printAuthors();
        $news->title = 'Something important';
        $news->printTitle();

    Pony::Object fields assigned via "=". For example: $obj->field = 'a'.

   new
    Pony::Object doesn't have method "new". In fact, of course it has. But
    "new" is an internal function, so you should not use it if you want not
    have additional fun. Instead of this Pony::Object has "init" function,
    where you can write the same, what you wish write in "new". "init" is
    after-hook for "new".

        package News;
        use Pony::Object;
    
            has title => undef;
            has lower => undef;
        
            sub init
                {
                    my $this = shift;
                    $this->title = shift;
                    $this->lower = lc $this->title;
                }
        1;

        package main;
    
        my $news = new News('Big Event!');
    
        print $news->lower;

   ALL
    If you wanna get all default values of Pony::Object-based class (fields,
    of course), you can call "ALL" method. I don't know why you need them,
    but you can do it.

        package News;
        use Pony::Object;
    
            has 'title';
            has text => '';
            has authors => [ qw/Alice Bob/ ];
        
        1;

        package main;
    
        my $news = new News;
    
        print for keys %{ $news->ALL() };

   META
    One more internal method. It provides access to special hash %META. You
    can use it for Pony::Object introspection but do not trust it. It can be
    changed in next versions.

        my $news = new News;
        say dump $news->META;

   toHash
    Get object's data structure and return it in hash.

        package News;
        use Pony::Object;
    
            has title => 'World';
            has text => 'Hello';
        
        1;

        package main;
    
        my $news = new News;
        print $news->toHash()->{text};
        print $news->toHash()->{title};

   dump
    Return string which shows object current struct.

        package News;
        use Pony::Object;
    
            has title => 'World';
            has text => 'Hello';
        
        1;

        package main;
    
        my $news = new News;
        $news->text = 'Hi';
        print $news->dump();

    Returns

        $VAR1 = bless( {
          'text' => 'Hi',
          'title' => 'World'
        }, 'News' );

   protected, private properties
    For properties you can use "has" keyword if your variable starts with _
    (for protected) or __ (for private).

        package News;
        use Pony::Object;
    
            has text => '';
            has __authors => [ qw/Alice Bob/ ];
        
            sub getAuthorString
                {
                    my $this = shift;
                    return join(' ', @{ $this->__authors });
                }
        
        1;

        package main;
    
        my $news = new News;
        say $news->getAuthorString();

    Or the same but with keywords "public", "protected" and "private".

        package News;
        use Pony::Object;
    
            public text => '';
            private authors => [ qw/Alice Bob/ ];
        
            sub getAuthorString
                {
                    my $this = shift;
                    return join(' ', @{ $this->authors });
                }
        
        1;

        package main;
    
        my $news = new News;
        say $news->getAuthorString();

   protected, private method
    To define access for methods you can use attributes "Public", "Private"
    and "Protected".

        package News;
        use Pony::Object;
    
            public text => '';
            private authors => [ qw/Alice Bob/ ];
        
            sub getAuthorString : Public
                {
                    return shift->joinAuthors(', ');
                }
        
            sub joinAuthors : Private
                {
                    my $this = shift;
                    my $delim = shift;
                
                    return join( $delim, @{ $this->authors } );
                }
        1;

        package main;
    
        my $news = new News;
        say $news->getAuthorString();

   Inheritance
    To define base classes you should set them as params on Pony::Object
    use. For example, use Pony::Object 'Base::Class';

        package FirstPonyClass;
        use Pony::Object;
    
            # properties
            has a => 'a';
            has d => 'd';
        
            # method
            has b => sub
                {
                    my $this = shift;
                       $this->a = 'b';
                   
                    return ( @_ ?
                                shift:
                                'b'  );
                };
        
            # traditional perl method
            sub c { 'c' }
    
        1;

        package SecondPonyClass;
        # extends FirstPonyClass
        use Pony::Object qw/FirstPonyClass/;
    
            # Redefine property.
            has d => 'dd';
        
            # Redefine method.
            has b => sub
                {
                    my $this = shift;
                       $this->a = 'bb';
                   
                    return ( @_ ?
                                shift:
                                'bb'  );
                };
        
            # New method.
            has e => sub {'e'};
    
        1;

   Singletons
    For singletons Pony::Object has simple syntax. You just should declare
    that on use Pony::Object;

        package Notes;
        use Pony::Object 'singleton';
    
            has list => [];
        
            sub add
                {
                    my $this = shift;
                    push @{ $this->list }, @_;
                }
        
            sub flush
                {
                    my $this = shift;
                    $this->list = [];
                }
    
        1;

        package main;
        use Notes;
    
        my $n1 = new Notes;
        my $n2 = new Notes;
    
        $n1->add( qw/eat sleep/ );
        $n1->add( 'Meet with Mary at 8 o`clock' );
    
        $n2->flush;
    
        # Em... When I must meet Mary?

   Abstract methods and classes
    You can use use abstract methods and classes in the following way:

        # Let's define simple interface for texts.
        package Text::Interface;
        use Pony::Object -abstract; # Use 'abstract' or '-abstract'
                                    # params to define abstract class.
    
            sub getText : Abstract; # Use 'Abstract' attribute to
            sub setText : Abstract; # define abstract method.
    
        1;

        # Now we can define base class for texts.
        # It's abstract too but now it has some code.
        package Text::Base;
        use Pony::Object abstract => 'Text::Interface';
    
            protected text => '';
        
            sub getText : Public
                {
                    my $this = shift;
                    return $this->text;
                }
    
        1;

        # And in the end we can write Text class.
        package Text;
        use Pony::Object 'Text::Base';
    
            sub setText : Public
                {
                    my $this = shift;
                    $this->text = shift;
                }
    
        1;

        # Main file.
        package main;
        use Text;
        use Text::Base;
    
        my $text = new Text::Base;  # Raises an error!
    
        my $text = new Text;
        $text->setText('some text');
        print $text->getText();     # Returns 'some text';

    Don't forget, that perl looking for function from left to right in list
    of inheritance packages. You should define abstract classes in the end
    of Pony::Object param list.

SEE
    Discussion
        <http://lorcode.org/thread/2338>

    Git <https://github.com/h15/pony-object>

COPYRIGHT AND LICENSE
    Copyright (C) 2011 - 2012, Georgy Bazhukov.

    This program is free software, you can redistribute it and/or modify it
    under the terms of the Artistic License version 2.0.

