J'ai du mal à utiliser MooseX :: Declare correctement lorsque j'appelle BUILDARGS. J'essaie de créer un objet en tant qu'interface pour un fichier. (Spécifiquement, je veux une interface à un fichier binaire qui me laisse jeter un coup d'oeil aux quelques octets suivants dans le fichier puis les chompez pour un traitement ultérieur.)Quelle est la bonne façon de créer une méthode BUILDARGS en utilisant MooseX :: Declare?
Je veux être capable de créer un de ces objets
my $f = binary_file_buffer->new($file_name);
puis l'utiliser comme ceci
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 ])
);
}
Mon de binary_file_buffer définition de classe/déclaration se présente comme suit
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);
}
}
(Il y a un chargement de tampon et un code de gestion que je n'ai pas inclus ici. C'est assez simple.)
Le problème est que j'utilise le mot-clé method
dans la déclaration BUILDARGS
. Par conséquent, MooseX :: Declare attend un objetbinary_file_buffer
comme premier argument à BUILDARGS
. Mais BUILDARGS
obtient les arguments passés à nouveau, de sorte que le premier argument est la chaîne un 'binary_file_buffer'
, le nom du package. Par conséquent, il échoue à la vérification de type et meurt lors de la création d'un objet en utilisant new, comme je l'ai fait dans le premier extrait de code. (Au moins, c'est ma compréhension de ce qui se passe.)
Le message d'erreur que je reçois est:
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
J'aime le type de vérification sucre les fournitures de mots clés method
pour file_name $, mais je ne sais pas comment l'obtenir puisque BUILDARGS
n'est pas techniquement une méthode.
MooseX :: Declare peut-il ignorer la création $self
, ou quelque chose comme ça? Est-ce que je fais cela la bonne façon MooseX :: Declare? Ou est-ce que je manque quelque chose?
Bingo! Cela fait exactement ce que je veux. J'ai raté 2 choses dans les docs, votre réponse a été clarifiée. D'abord, je n'ai pas vu le sous-type ClassName de Str dans Moose :: Manual :: Types docs. Je ne m'attendais pas à un sous-type de chaîne ClassName. Ensuite, je n'ai pas vu les docs MooseX :: Method :: Signatures montrer comment nommer l'invocant d'une méthode et déclarer son type. Je n'ai pas réalisé que la syntaxe de signature de méthode utilisée par MooseX :: Declare provient du paquetage MooseX :: Method :: Signatures. Jusqu'ici, j'adore MooseX :: Declare. Je savais qu'il y avait une façon Moose de faire ce que je voulais. Je ne pouvais pas comprendre comment. Merci. – meta4
L'utilisation de ClassName au lieu de Object pour method/around devrait vraiment être écrite quelque part dans le manuel de MooseX :: Declare ... a été mordu par ça aussi – anydot