3

如何将函数传递给构造函数,以便类可以在内部使用它?

测试.pl

use Class;
use Loger;

my $loger = Loger->new();
$loger->log('I have logger now, I can log messages!');

my $class = Class->new(\&{ $loger->log }); # here we pass the function (the method of other class) to contructor of a new  Class

$class->do_something();  # class uses loger->log internally to report errors

Class.pm 包类;

sub new {

    my $self = {};
    $self->{log} = shift; # we got logger->log function, save it for future use

    return bless $self;
}

sub do_something {
     my $self = shift;

     open_file or $self->{log}->('Cant open file'); # we can use gotten logger in class 
}


1;
4

3 回答 3

3

你快到了。

While$loger->log是一个函数调用,您可以使用它\&Loger::log来引用该函数。

\&{ref($loger)."::log"}可能也有效。

结合@simbabques 点,您应该在传递函数之前对函数进行curry,即预先提供第一个参数。您可以通过调用构造函数来做到这一点

sub {$loger->log(@_)}

或者

sub {unshift @_, $loger; goto \&Loger::log} # more efficient

作为论据。

于 2012-09-25T12:44:04.877 回答
3

您正在尝试传递一个方法,而不是一个函数(或子)。单独调用它是行不通的。如果您想要一个对象的方法,请传递该对象并在该对象上调用该方法。

my $loger = Loger->new();
$loger->log('I have logger now, I can log messages!');

my $class = Class->new(logger => $loger); # pass the Loger object

并在Class.pm

package Class;

sub new
{
  my ($class, %args) = @_;
  my $self = {};
  $self->{log} = $args{'logger'}; # store it inside your Class object
  return bless $self;
}

sub do_something
{
   my $self = shift;
   open_file or $self->{log}->log->('Cant open file'); # call its log-method
}
于 2012-09-25T12:44:23.570 回答
0

\引用运算符仅适用于命名符号。

您的线路:

my $class = Class->new(\&{ $loger->log });

实际上是尝试传递匿名子例程。它还缺少将参数传递给 $loger->log() 的方法。

您可以将其更改为:

my $class = Class->new(sub { $loger->log(@_) });

于 2012-09-25T14:16:32.717 回答