Interfaces in Perl

In Perl, we don’t have interfaces as a language feature, but we can achieve similar functionality using roles or by implementing methods with the same names in different classes. For this example, we’ll use Perl’s object-oriented features to create a similar structure.

use strict;
use warnings;
use Math::Trig qw(pi);

# Define a base class for geometric shapes
package Geometry {
    sub new {
        my $class = shift;
        bless {}, $class;
    }

    # Abstract methods to be implemented by subclasses
    sub area { die "Not implemented" }
    sub perim { die "Not implemented" }
}

# Implement Rectangle
package Rectangle {
    our @ISA = qw(Geometry);

    sub new {
        my ($class, $width, $height) = @_;
        my $self = $class->SUPER::new();
        $self->{width} = $width;
        $self->{height} = $height;
        return $self;
    }

    sub area {
        my $self = shift;
        return $self->{width} * $self->{height};
    }

    sub perim {
        my $self = shift;
        return 2 * $self->{width} + 2 * $self->{height};
    }
}

# Implement Circle
package Circle {
    our @ISA = qw(Geometry);

    sub new {
        my ($class, $radius) = @_;
        my $self = $class->SUPER::new();
        $self->{radius} = $radius;
        return $self;
    }

    sub area {
        my $self = shift;
        return pi * $self->{radius} ** 2;
    }

    sub perim {
        my $self = shift;
        return 2 * pi * $self->{radius};
    }
}

# Function to measure any geometric shape
sub measure {
    my $shape = shift;
    print "$shape\n";
    print $shape->area(), "\n";
    print $shape->perim(), "\n";
}

# Main execution
package main;

my $r = Rectangle->new(3, 4);
my $c = Circle->new(5);

measure($r);
measure($c);

In this Perl implementation:

  1. We define a base Geometry class with abstract area and perim methods.

  2. We create Rectangle and Circle classes that inherit from Geometry and implement the area and perim methods.

  3. The measure function takes any object that responds to area and perim methods, similar to how the Go version accepts any type implementing the geometry interface.

  4. In the main execution, we create instances of Rectangle and Circle and pass them to the measure function.

To run this program, save it as geometry.pl and execute it with:

$ perl geometry.pl
Rectangle=HASH(0x55b5f0a93e48)
12
14
Circle=HASH(0x55b5f0a93e60)
78.5398163397448
31.4159265358979

This Perl implementation demonstrates how we can achieve interface-like behavior using inheritance and method overriding. While Perl doesn’t have explicit interfaces, this approach allows us to work with different shapes in a polymorphic manner.