Perl - 调用 class 的实例
Perl - call an instance of a class
有没有办法捕获调用 Perl 实例的事件class?
my $obj = ExampleClass->new();
$obj(); # do something without producing error
我希望能够从 class/module 定义中处理这个问题。类似于 Python 中的 __call__
方法或 Lua.
中的 __call
元方法
我仍然不确定用例是什么,但您可以 overload
class 来处理代码取消引用。
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->()
典型输出:
$ perl 44956235.pl
calling an instance event at 44956235.pl line 7.
calling an instance event at 44956235.pl line 7.
显然是要走的路,但您可以将对象基于子而不是通常首选的哈希。
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;
主程序:
#!/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();
}
输出:
value
__call__(a, b, c)
value1
value2
这基本上就是所谓的 "inside-out" 对象。
你要找的是函子。您可以创建一个基础 class 来更轻松地实现您的函子。例如:
package AbstractFunctorObject;
use strict;
use warnings;
use overload '&{}' => sub { $_[0]->can( '__invoke' ) };
sub new
{
my $class = shift;
bless { @_ }, $class;
}
1;
__END__
然后,您可以按如下方式实现仿函数:
package FunctorObject;
use strict;
use warnings;
use parent 'AbstractFunctorObject';
sub __invoke
{
print "Called as a functor with args: @{ [ @_ ? @_ : 'no argument given' ] }\n";
}
1;
__END__
最后,您可以按如下方式调用仿函数:
package main;
use FunctorObject;
my $functor = FunctorObject->new();
$functor->('firstname', 'lastname');
$functor->();
结果将是:
root@jessie:/usr/local/src# perl callable_object.pl
Called as a functor with args: firstname lastname
Called as a functor with args: no argument given
有没有办法捕获调用 Perl 实例的事件class?
my $obj = ExampleClass->new();
$obj(); # do something without producing error
我希望能够从 class/module 定义中处理这个问题。类似于 Python 中的 __call__
方法或 Lua.
__call
元方法
我仍然不确定用例是什么,但您可以 overload
class 来处理代码取消引用。
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->()
典型输出:
$ perl 44956235.pl
calling an instance event at 44956235.pl line 7.
calling an instance event at 44956235.pl line 7.
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;
主程序:
#!/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();
}
输出:
value
__call__(a, b, c)
value1
value2
这基本上就是所谓的 "inside-out" 对象。
你要找的是函子。您可以创建一个基础 class 来更轻松地实现您的函子。例如:
package AbstractFunctorObject;
use strict;
use warnings;
use overload '&{}' => sub { $_[0]->can( '__invoke' ) };
sub new
{
my $class = shift;
bless { @_ }, $class;
}
1;
__END__
然后,您可以按如下方式实现仿函数:
package FunctorObject;
use strict;
use warnings;
use parent 'AbstractFunctorObject';
sub __invoke
{
print "Called as a functor with args: @{ [ @_ ? @_ : 'no argument given' ] }\n";
}
1;
__END__
最后,您可以按如下方式调用仿函数:
package main;
use FunctorObject;
my $functor = FunctorObject->new();
$functor->('firstname', 'lastname');
$functor->();
结果将是:
root@jessie:/usr/local/src# perl callable_object.pl
Called as a functor with args: firstname lastname
Called as a functor with args: no argument given