Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

tiny object system with privacy settings for properties and methods

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 examples
Octocat-spinner-32 lib
Octocat-spinner-32 script
Octocat-spinner-32 t
Octocat-spinner-32 .gitignore
Octocat-spinner-32 Build.PL
Octocat-spinner-32 CHANGES
Octocat-spinner-32 LICENSE
Octocat-spinner-32 MANIFEST
Octocat-spinner-32 MANIFEST.SKIP
Octocat-spinner-32 META.json
Octocat-spinner-32 META.yml
Octocat-spinner-32 MYMETA.json
Octocat-spinner-32 MYMETA.yml
Octocat-spinner-32 Makefile.PL
Octocat-spinner-32 README
README
NAME
    Pony::Object - An object system.

OVERVIEW
    If you wanna protected methods, abstract classes and other OOP stuff,
    you may use Pony::Object. Also Pony::Objects are strict and modern.

SYNOPSIS
      # Class: MyArticle (Example)
      #   Abstract class for articles.
  
      package MyArticle;
      use Pony::Object qw(-abstract :exceptions);
      use MyArticle::Exception::IO; # Based on Pony::Object::Throwable class.
    
        protected date => undef;
        protected authors => [];
        public title => '';
        public text => '';
    
    
        # Function: init
        #   Constructor.
        #
        # Parameters:
        #   date - Int
        #   authors - ArrayRef
    
        sub init : Public
          {
            my $this = shift;
            ($this->date, $this->authors) = @_;
          }
    
    
        # Function: getDate
        #   Get formatted date.
        #
        # Returns:
        #   Str
    
        sub getDate : Public
          {
            my $this = shift;
            return $this->dateFormat($this->date);
          }
    
    
        # Function: dateFormat
        #   Convert Unix time to good looking string. Not implemented.
        #
        # Parameters:
        #   date - Int
        #
        # Returns:
        #   String
    
        sub dateFormat : Abstract;
    
    
        # Function: fromPdf
        #   Trying to create article from pdf file.
        #
        # Parameters:
        #   file - Str - pdf file.
    
        sub fromPdf : Public
          {
            my $this = shift;
            my $file = shift;
        
            try {
              open F, $file or
                throw MyArticle::Exception::IO(action => "read", file => $file);
          
              # do smth
          
              close F;
            } catch {
              my $e = shift; # get exception object
          
              if ($e->isa('MyArticle::Exception::IO')) {
                # handler for MyArticle::Exception::IO exceptions
              }
            };
          }
    
      1;

Methods and properties
  has
    Keyword "has" declares new property. Also you can define methods via
    "has".

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



      package main;
      use News;
      my $news = new News;
      $news->printAuthors();
      $news->title = 'Sensation!'; # Yep, you can assign property's value via "=".
      $news->printTitle();

  new
    Pony::Objects hasn't method "new". In fact, of course they has. But
    "new" is an internal function, so you should not use "new" as name of
    method.

    Instead of this Pony::Objects has "init" methods, 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;
      use News;
      my $news = new News('Big Event!');
      print $news->lower;

  public, protected, private properties
    You can use "has" keyword to define property. If your variable starts
    with "_", variable becomes protected. "__" 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;
      use News;
      my $news = new News;
      say $news->getAuthorString();

    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;
      use News;
      my $news = new News;
      say $news->getAuthorString();

  Public, Protected, Private methods
    Use attributes "Public", "Private" and "Protected" to define method's
    access type.

      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;
      use News;
      my $news = new News;
      say $news->getAuthorString();

  Static properties
    Just say ""static"" and property will the same in all objects of class.

      package News;
      use Pony::Object;
    
        public static 'default_publisher' => 'Georgy';
        public 'publisher';
    
        sub init : Public
          {
            my $this = shift;
            $this->publisher = $this->default_publisher;
          }
    
      1;



      package main;
      use News;
  
      my $n1 = new News;
      $n1->default_publisher = 'Bazhukov';
      my $n2 = new News;
      print $n1->publisher; # "Georgy"
      print $n2->publisher; # "Bazhukov"

Default methods
  toHash or to_h
    Get object's data structure and return this as a hash.

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



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

  dump
    Shows object's current struct.

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



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

    Returns

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

  Without Objects
    If you like functions "say", "dump", "try"/"catch", you can use them
    without creating object. Use ":noobject" option to enable them but do
    not create object/making class.

      use Pony::Object qw/:noobject :try/;
  
      my $a = {deep => [{deep => ['structure']}]};
      say dump $a;
  
      my $data = try {
        local $/;
        open my $fh, './some/file' or die;
        my $slurp = <$fh>;
        close $fh;
        return $slurp;
      } catch {
        return '';
      };
  
      say "\$data: $data";

Classes
  Inheritance
    You can define base classes via "use" params. For example, "use
    Pony::Object 'Base::Class';"

      package BaseCar;
      use Pony::Object;
    
        public speed => 0;
        protected model => "Base Car";
    
        sub get_status_line : Public
          {
            my $this = shift;
            my $status = ($this->speed ? "Moving" : "Stopped");
            return $this->model . " " . $status;
          }
    
      1;



      package MyCar;
      # extends BaseCar
      use Pony::Object qw/BaseCar/;
    
        protected model => "My Car";
        protected color => undef;
    
        sub set_color : Public
          {
            my $this = shift;
            ($this->color) = @_;
          }
    
      1;



      package main;
      use MyCar;
      my $car = new MyCar;
      $car->speed = 20;
      $car->set_color("White");
      print $car->get_status_line();
      # "My Car Moving"

  Singletons
    Pony::Object has simple syntax for singletons . You can declare this via
    "use" param;

      package Notes;
      use Pony::Object 'singleton';
    
        protected list => [];
    
        sub add : Public
          {
            my $this = shift;
            push @{ $this->list }, @_;
          }
    
        sub show : Public
          {
            my $this = shift;
            say for @{$this->list};
          }
    
        sub flush : Public
          {
            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;
  
      $n1->show();  # Print nothing.
                    # Em... When I should meet Mary?

  Abstract methods and classes
    You can use abstract methods and classes follows 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 qw/abstract Text::Interface/;
    
        protected text => '';
    
        sub getText : Public
          {
            my $this = shift;
            return $this->text;
          }
    
      1;



      # 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 $textBase = 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 functions from left to right in list
    of inheritance. You should define abstract classes in the end of
    Pony::Object param list.

  Exceptions
    See Pony::Object::Throwable.

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

      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 this for Pony::Object introspection. It can be changed in next
    versions.

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

   $Pony::Object::DEFAULT
    This is a global variable. It defines default Pony::Object's params. For
    example you can set "$Pony::Object::DEFAULT-"{''}->{withExceptions} = 1>
    to enable exceptions (try, catch, finally blocks) by default. Use it
    carefully.

      # Startup script
      ...
      use Pony::Object;
  
      BEGIN {
        # Use exceptions by default.
        $Pony::Object::DEFAULT->{''}->{withExceptions} = 1;
        # All classes will extends Default::Base.
        $Pony::Object::DEFAULT->{''}->{baseClass} = [qw/Default::Base/];
        # All classes in namespace "Default::NoBase" will not.
        $Pony::Object::DEFAULT->{'Default::NoBase'}->{baseClass} = [];
      }
      ...

    One more example:

      # Startup script
      ...
      use Pony::Object;
  
      BEGIN {
        $Pony::Object::DEFAULT->{'My::Awesome::Project'} = {
          withExceptions => 1,
          baseClass => [],
        };
    
        $Pony::Object::DEFAULT->{'My::Awesome::Project::Model'} = {
          withExceptions => 1,
          baseClass => [qw/My::Awesome::Project::Model::Abstract/],
        };
      }
      ...

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

COPYRIGHT AND LICENSE
    Copyright (C) 2011 - 2013, 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.

Something went wrong with that request. Please try again.