Log in

No account? Create an account
entries friends calendar profile Previous Previous Next Next
Object Oriented Perl - Ed's journal
Object Oriented Perl
I started taking a look at object oriented perl the other day. Mostly because I was deconstructing something that didn't work quite right. Anyone a little bit familiar with Perl, will realise that the .. they've probably already seen it, because the in Perl, OO is driven by hashes, references and packages.

(Here's a hint - any time you've used '->' that's probably calling an object, and - because OO lets you encapsulate - there's a lot of that in imported modules).

The basics are - an object is a package, with an internal hash. And ... that's about it.
There's one 'new thing' that you may not have seen - 'bless'. Which is perl's way of giving a generic reference a class. Because they're applicable to objects, you'll see the subroutines within the package referred to as 'methods'.

You 'use' a method, with '->'. This is exactly the same as just running the subroutine, but perl passes the object reference (that you 'blessed') into the subroutine as the first argument.
my $object -> get_value ( "fish" );
Is equivalent to:
&Package::get_value ( $object, "fish" );

You then rely on the 'get_value' sub to 'know what to do' with $object. (Which is one of the underlying principles of OO - you ask it to do something, you don't deal with how it accomplishes it).

By convention too, packages should include a method 'new' - a constructor that sets up the blessed reference, and does any other initialisation that's necessary. (Doesn't have to be called this, but it's usually a good idea). Similarly - 'internal' subroutines are prefixed with _ to indicate they shouldn't be called directly. Unlike stricter languages, perl doesn't enforce privacy within objects. You _can_ diddle with attributes and internal methods, but it's asking for future pain, so don't do it.

If you create a sub called 'DESTROY' then this is called when an object would be deleted (usually due to going out of scope, or on program termination).

That's about it, really. Quite a bare bones implementation. If you want more 'OO' style features, there's a module called Moose, which implements a lot of more advanced features.

Here's some sample, illustrative code:

use strict;
use warnings;

package MyObject;

sub new
  my ( $class ) = @_;
  print "New called\n";
  print join ( "\n", @_);

  my $self = {};
    #need to give self something, because it needs to be 
    #a reference to something - in this case, an empty hash
    #you don't need to do this if you do something like:
  #my $self;
  #$self -> {_description} = "New Object"; 
  #because if you do that, self is no longer an undefined scalar, it's a reference.
  print "And Done\n";
  bless ( $self, $class ); 
  #note - the return code of 'bless' is the object reference.
  #perl implicitly returns the result of the last operation
  #so this 'return' below would occur implicitly if bless were the last
  #line in the sub. 
  return $self;

sub print_something
  my ( $self, @args ) = @_;
  print "Printing something (", $self, ") : ", @args, "\n";

sub set_description
  my ( $self, $desc ) = @_;
  $self -> {_description} = $desc; 

sub get_description
  my ( $self ) = @_;
  return $self -> {_description};

   print "Tidying up the object\n";
   print "Args of:".join ( "\n", @_ ),"\n";


Code to drive 'MyObject':

use strict;
use warnings;

use MyObject;

  my $object_for_me = MyObject -> new();
  $object_for_me -> print_something("Cool");
  $object_for_me -> set_description ( "New Description" );
  print $object_for_me -> get_description, "\n";
  print "Doing it 'subroutine style'\n";
  &MyObject::set_description ( $object_for_me, "Different Description" );
  print &MyObject::get_description ( $object_for_me ),"\n";

print "Ending program\n";
Leave a comment