我在调用BUILDARGS时无法正确使用MooseX :: Declaration。

我正在尝试创建一个对象作为文件的接口。 (具体来说,我想要一个二进制文件的接口,该接口可以让我窥视文件中的下几个字节,然后将其切断以进行进一步处理。)

我希望能够像这样创建这些对象之一

my $f = binary_file_buffer->new( $file_name );


然后像这样使用它

while( my $block_id = $f->peek( $id_offset, $id_length ) ) {
    $block_id = unpack_block_id( $block_id );
    $munge_block{ $block_id }->(
        $f->pop( $block_size[ $block_id ] )
    );
}


我的binary_file_buffer类定义/声明看起来像这样

use MooseX::Declare;
class binary_file_buffer {
    use FileHandle;
    use Carp;

    has _file      => ( is => 'ro', isa => 'FileHandle' );
    has _file_name => ( is => 'ro', isa => 'Str' );
    has _buff      => ( is => 'rw', isa => 'Str',  default => '' );

    method BUILDARGS ( Str $file_name ) {
      my $file = FileHandle->new( $file_name );
      carp "unable to open $file_name : $!" unless defined $file;
      $file->binmode;
      return (
        _file_name => $file_name,
        _file      => $file,
      );
    }

    # get the next n bytes from the buffer.
    method pop ( Int $len ) {
        # ... Make sure there is data in _buff
        return substr( $self->{_buff}, 0, $len, '' );
    }

    # Look around inside the buffer without changing the location for pop
    method peek ( Int $offset, Int $len ) {
        # ... Make sure there is data in _buff
        return substr( $self->{_buff}, $offset, $len );
    }
}


(这里没有包含缓冲区加载和管理代码,这很简单。)

问题是,我在method声明中使用了关键字BUILDARGS。因此,MooseX :: Declare期望binary_file_buffer对象作为BUILDARGS的第一个参数。但是BUILDARGS获取传递给new的参数,因此第一个参数是字符串a 'binary_file_buffer',即包的名称。结果,它无法进行类型检查,并且在使用new创建对象时死亡,就像我在第一个代码段中所做的那样。 (至少那是我对正在发生的事情的理解。)

我收到的错误消息是:

Validation failed for 'MooseX::Types::Structured::Tuple[MooseX::Types::Structured::Tuple[Object,Str,Bool],MooseX::Types::Structured::Dict[]]' failed with value [ [ "binary_file_buffer", "drap_iono_t1.log", 0 ], {  } ], Internal Validation Error is: Validation failed for 'MooseX::Types::Structured::Tuple[Object,Str,Bool]' failed with value [ "binary_file_buffer", "drap_iono_t1.log", 0 ] at C:/bin/perl/site/lib/MooseX/Method/Signatures/Meta/Method.pm line 445
 MooseX::Method::Signatures::Meta::Method::validate('MooseX::Method::Signatures::Meta::Method=HASH(0x2a623b4)', 'ARRAY(0x2a62764)') called at C:/bin/perl/site/lib/MooseX/Method/Signatures/Meta/Method.pm line 145
 binary_file_buffer::BUILDARGS('binary_file_buffer', 'drap_iono_t1.log') called at generated method (unknown origin) line 5
 binary_file_buffer::new('binary_file_buffer', 'drap_iono_t1.log') called at logshred.pl line 13


我喜欢method关键字为$ file_name提供的类型检查糖,但是我不知道如何获取它,因为BUILDARGS从技术上讲不是一种方法。

MooseX :: Declare是否可以跳过$self创建或类似的方法?

我这样做是正确的MooseX :: Declare方法吗?还是我错过了什么?

最佳答案

我认为您想要类似method BUILDARGS (ClassName $class: Str $filename) { ... }的东西,在其中您将倡导者明确定义为ClassName $class

08-26 22:27