Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 使用BUILDARGS替换角色中的类_Perl_Moose - Fatal编程技术网

Perl 使用BUILDARGS替换角色中的类

Perl 使用BUILDARGS替换角色中的类,perl,moose,Perl,Moose,我使用Perl Moose角色(Import::Git::Role)作为抽象基类,在实际实现功能的类(Import::Git)和执行一些日志记录的类(Import::Git::dryrun)之间共享公共行为 我希望dryrun类是透明的。我想创建一个如下所示的对象: my $git = Import::Git->new( dryrun => $dryrun ); around BUILDARGS => sub {

我使用Perl Moose角色(
Import::Git::Role
)作为抽象基类,在实际实现功能的类(
Import::Git
)和执行一些日志记录的类(
Import::Git::dryrun
)之间共享公共行为

我希望dryrun类是透明的。我想创建一个如下所示的对象:

   my $git = Import::Git->new( dryrun => $dryrun );
around BUILDARGS => sub {                                                                                                                                                                                                                                                           
     my $orig  = shift;
     my $class = shift;

     my %args = ( @_ == 1 ? %{ $_[ 0 ] } : @_ );

     if ( !%args || $args{ 'dryrun' } != 1 ) {
         return $class->$orig( @_ );
     }
     else {
         return Import::Git::dryrun->$orig( @_ );
    }
};
变量dryrun可以是0或1。如果是1,我想构造一个
Import::Git::dryrun
对象,基本上用它替换
Import::Git
对象。这是因为他们通过角色共享所有方法

我尝试在BUILDARGS方法期间交换对象,如下所示:

   my $git = Import::Git->new( dryrun => $dryrun );
around BUILDARGS => sub {                                                                                                                                                                                                                                                           
     my $orig  = shift;
     my $class = shift;

     my %args = ( @_ == 1 ? %{ $_[ 0 ] } : @_ );

     if ( !%args || $args{ 'dryrun' } != 1 ) {
         return $class->$orig( @_ );
     }
     else {
         return Import::Git::dryrun->$orig( @_ );
    }
};
但这并没有实现我想要做的,它构建了旧类:

  DB<1> x Import::Git->new( dryrun => 1 )
0  Import::Git=HASH(0x2fd9210)
   'dryrun' => 1
  DB<2> x Import::Git->new()
0  Import::Git=HASH(0x301dbb8)
   'dryrun' => 0
  DB<3> 
但是它返回
BUILDARGS没有返回哈希引用


我缺少什么?

BUILDARGS
用于在创建对象之前操作传递给对象构造函数的参数列表,因此不会影响新返回的内容。与围绕BUILDARGS的
不同,您可能希望尝试围绕new的
而不是
,然后您可以将new返回的对象替换为您的干运行对象。

让构造函数构建不同于请求的类是令人讨厌的。我不会采取你的方法,即使它确实有效。我会用

sub factory {
   my ($class, %opts) = @_;
   return $opt{dryrun} ? $class.'::dryrun' : $class;
}

Import::Git->factory( dryrun => $dryrun )->new( ... )


不,不需要创建整个类。就用我贴的潜艇吧。(移到回答)有效的论点。这样,如果需要,可以创建Import::Git(dryrun=>1)。我喜欢实例化子例程:)可以,但这样做会失去执行
Import::Git::Subclass->实例化(…)