2

I have noticed some Perl modules use a class based structure, but don't manage any data. The class is simply used to access the methods within and nothing more.

Consider the following example:

Class.pm

package Class;

use Moose;

sub do_something {
    print "Hi!\n";
}

1;

test.pl

use Class;

# Instantiate an object from the class
my $obj = Class->new();

$obj->do_something();

In this example you can see that you would first instantiate an instance of the class, then call the method from the created object.


The same end result can be achieved like so:

Module.pm

package Module;

use strict;
use warnings;

sub do_something {
    print "Hi!\n";
}

1;

test.pl

use Module;

Module::do_something();

I am wondering why people write modules using the first approach, and if there is some benefit that it provides. To me it seems like it adds an extra step, because in order to use the methods, you first need to instantiate an object of the class.

I don't understand why people would program like this unless it has some benefit that I am not seeing.

Borodin
  • 126,100
  • 9
  • 70
  • 144
tjwrona1992
  • 8,614
  • 8
  • 35
  • 98
  • 2
    I can think of several reasons, but if you give an example of one of these Perl modules it will be more useful; to explain in context. – Borodin Oct 12 '17 at 16:06
  • The first thing that came to mind was the `CGI` module, but upon closer investigation it looks like it does store data in some circumstances. – tjwrona1992 Oct 12 '17 at 16:10
  • One benefit is inheritance. You can use a subclass of `Module` only if it is object-oriented. – mob Oct 12 '17 at 16:13
  • @mob, actually that may be technically untrue. I was digging through my Perl library directory and it looks like the `DB` module effectively uses inheritance without technically being object oriented. It is very strange though. – tjwrona1992 Oct 12 '17 at 16:15
  • You can add attributes at runtime (unless the class is mutable). See for instance [posts here](https://stackoverflow.com/questions/3996067/how-can-i-flexibly-add-data-to-moose-objects). Quite possible to think of use cases. – zdim Oct 12 '17 at 16:22

1 Answers1

5

One benefit is inheritance. You can subclass behavior of an existing class if it supports the -> style subroutine calls (which is a weaker statement than saying the class is object-oriented, as I said in a comment above).

package Class;
sub new { bless \__PACKAGE__,__PACKAGE__ }
sub do_something { "foo" }
sub do_something_else { 42 }
1;


package Subclass;
@Sublcass::ISA = qw(Class);
sub new { bless \__PACKAGE__,__PACKAGE__ }
sub do_something_else { 19 }


package main;
use feature 'say';
$o1 = Class->new;
$o2 = Subclass->new;

say $o1->do_something;          # foo
say $o2->do_something;          # foo
say $o1->do_something_else;     # 42
say $o2->do_something_else;     # 19

A prominent use of this technique is the UNIVERSAL class, that all blessed references implicitly subclass. The methods defined in the UNIVERSAL namespace generally take a package name as the first argument (or resolve a reference in the first argument to its package name), are return some package information. The DB class also does something like this (though the DB package also maintains plenty of state).

mob
  • 117,087
  • 18
  • 149
  • 283