2023 twenty-four merry days of Perl Feed

Introduction to class feature

use experimental 'class' - 2023-12-14

Background

I have followed the last 2 releases of Perl i.e. Perl v5.36 and Perl v5.38 very closely. Perl v5.36 was released on 2022-05-28 with much fanfare as it had so much nice new features introduced. If you haven't had chance to play with then I have compiled some for you. Please check out this collection for quick introduction.

Following the release of Perl v5.36, the discussion of new object system Corinna took the limelight as it was one of the main features to be introduced with Perl v5.38. Then finally on 2023-07-02, we had Perl v5.38 released.

After the release, I wanted to try new class feature but never got the opportunity to play with it.

I have played with Design Patterns using the Moo based object in the past. So I thought why not pick one of the design pattern and try with the new class feature.

Singleton using Moo

As you see the code below, it is such a lightweight implementation of Singleton using Moo with MooX::Singleton. The only issue I have is the dependency on non-core module.

package SingleObject;

use Moo;
with 'MooX::Singleton';

has 'count' => (is => 'rw', default => sub { 0 });

sub counter {
    my ($self) = @_;

    return $self->count($self->count + 1);
}

print SingleObject->instance->counter, "\n";
print SingleObject->instance->counter, "\n";
print SingleObject->instance->counter, "\n";
print SingleObject->instance->counter, "\n";
print SingleObject->instance->counter, "\n";

This gives us the following output:

    1
    2
    3
    4
    5

Implementation of Singleton using new class feature

With the Perl v5.38 release, we no longer have the dependency on external modules as seen in the code below:

use v5.38;
use experimental 'class';

class Singleton 0.01 {
    my $instance;
    sub instance($class) { $instance //= $class->new }
}

class SingleObject :isa(Singleton) {
    field $count :param = 0;
    method counter { ++$count }
}

say SingleObject->instance->counter;
say SingleObject->instance->counter;
say SingleObject->instance->counter;
say SingleObject->instance->counter;
say SingleObject->instance->counter;

This gives us exactly the same output as above.

How about some more?

Well, I then tried to show inheritance using new class feature. It looks amazingly compact and clean.

use v5.38;
use experimental 'class';

class Animal {
    method eat { say "I can eat!" }
}

class Dog :isa(Animal) {
    method bark { say "Woof Woof!" }
}

my $dog = Dog->new;
$dog->eat();
$dog->bark();

This gives us the following output:

    I can eat!
    Woof Woof!

That's it for now until we meet again.

Gravatar Image This article contributed by: Mohammad Anwar <mohammad.anwar@yahoo.com>