Is there way to catch the event of calling an instance of a Perl class?
my $obj = ExampleClass->new();
$obj(); # do something without producing error
Overloading "&{}" is obviously the way to go, but you could base your object on a sub instead of the commonly-preferred hash.
ExampleClass.pm
:
package ExampleClass;
use strict;
use warnings;
use feature qw( current_sub say );
my %objects;
sub new {
my $class = shift;
my $dummy; # Force each evaluation of sub{} to return a new variable.
my $self = bless(sub { $dummy if 0; __SUB__ ->__call__(@_) }, $class) }, $class);
my $inner = $objects{$self} = {};
return $self;
}
sub DESTROY {
my $self = shift;
delete($objects{$self});
}
sub __call__ {
my $inner = $objects{ my $self = shift };
say "__call__(".join(", ", @_).")";
}
sub some_attribute {
my $inner = $objects{ my $self = shift };
if (@_) { $inner->{some_attribute} = $_[0]; }
return $inner->{some_attribute};
}
1;
The main program:
#!/usr/bin/perl
use strict;
use warnings;
use feature qw( say );
use ExampleClass qw( );
{
my $obj = ExampleClass->new();
$obj->some_attribute("value");
say $obj->some_attribute();
$obj->(qw( a b c ));
}
{
my $obj1 = ExampleClass->new();
$obj1->some_attribute("value1");
my $obj2 = ExampleClass->new();
$obj2->some_attribute("value2");
say $obj1->some_attribute();
say $obj2->some_attribute();
}
Output:
value
__call__(a, b, c)
value1
value2
This is basically what's called an "inside-out" object.