Perl - 调用类的实例

6 perl class function call instance

有没有办法捕获调用Perl类的实例的事件?

my $obj = ExampleClass->new();
$obj(); # do something without producing error
Run Code Online (Sandbox Code Playgroud)

我希望能够在类/模块定义中处理这个问题.类似于__call__Python中的方法或__callLua中的metamethod.

mob*_*mob 9

我仍然不确定用例是什么,但是你可以overload让类处理代码解除引用.

package ExampleClass;
use overload '&{}' => \&__call__;   # Or an anon sub.
sub new {
   bless {@_}, shift;
}
sub __call__ {
    sub { warn "calling an instance event" };
}

package main;
my $obj = ExampleClass->new;
$obj->();
&$obj();      # same as $obj->()
Run Code Online (Sandbox Code Playgroud)

典型输出:

$ perl 44956235.pl
calling an instance event at 44956235.pl line 7.
calling an instance event at 44956235.pl line 7.
Run Code Online (Sandbox Code Playgroud)


ike*_*ami 8

重载" &{}"显然是要走的路,但你可以将你的对象基于sub而不是通常首选的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;
Run Code Online (Sandbox Code Playgroud)

主要方案:

#!/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();
}
Run Code Online (Sandbox Code Playgroud)

输出:

value
__call__(a, b, c)
value1
value2
Run Code Online (Sandbox Code Playgroud)

这基本上就是所谓的"由内而外"的对象.