Is there a point for Perl object-oriented interfaces if they don't create objects?
First, it's important to remember that Perl implements classes in strange ways, through packages. Packages also serve to generally prevent pollution of the namespace.
package Foo;
sub new {
my ($class) = @_;
my $self = bless {}, $class;
return $self;
}
1;
This way you create a Foo class in Perl (which can be called by the lens by calling Foo-> new or new Foo). Usage new
is just a convention; it could be anything. Actually, what new
is it that C ++ will call the static method call.
You can easily create packages containing only static method calls, and I suspect that is what you are talking about. The advantage here is that you can still use OO features like inheritance:
package Bar;
sub DoSomething {
my ($class, $arg) = @_;
$class->Compute($arg);
}
sub Compute {
my ($class, $arg) = @_;
$arg * 2;
}
1;
package Baz;
@Baz::ISA = qw(Bar);
sub Compute {
my ($class, $arg) = @_;
$arg * 2 - 1
}
1;
Considering that then
say Bar->DoSomething(3) # 6
say Baz->DoSomething(3) # 5
In fact, you can even use variables for the class name, so they can function very powerfully as single ones:
my $obj = "Baz"; # or Baz->new could just return "Baz"
print $obj->DoSomething(3) # 5
[The code is not verified; typos may be present]
source to share
I suspect this is mostly a philosophical choice on the part of authors who prefer OO for imperative programming. Others have mentioned creating a namespace, but it's a package that does it, not an interface. OO is not required.
Personally, I have little value when creating classes that are never instantiated (i.e. when there is no object in the object oriented object). Perl is not Java; you don't need to write a class for everything. Several modules confirm this. For example: File :: Spec has an OO interface, but also provides a functional interface via File :: Spec :: Functions.
The :: Spec file also provides an example of where OO can be useful for uninstalled "utility" interfaces. Essentially, File :: Spec is an abstract base class - an interface with no implementation. When you load File :: Spec, it checks what OS you are using and loads the appropriate implementation. As a programmer, you use an interface (for example File::Spec->catfile
) without worrying about which version catfile
(Unix, Windows, VMS, etc.) is actually being called.
source to share
As others have said, inheritance is a big win if the actual object is not needed. The only thing I have to add here is advice to name your variables well when writing interfaces like this:
package Foo;
# just a static method call
sub func
{
my $class = shift;
my (@args) = @_;
# stuff...
}
I named the variable that contains the class name " $class
" rather than $ this to make it clear to subsequent maintainers that func () will be called as Foo-> func () and not $ foo-> func () (with an object instance Foo
) ... This helps to avoid adding this line later to the method:
my $value = $this->{key};
... which will fail since there is no respect for the key " key
".
If a method can be called both statically and against an instance object (for example, when writing a custom AUTOLOAD method ) you can write this:
my method
{
my $this = shift;
my $class = ref($this) || $this;
my (@args) = @_;
# stuff...
}
source to share