Reputation: 1617
The way I'm doing it is:
package 'My::FH';
use Moose;
has 'csv' => (
is => 'ro',
isa => 'Text::CSV',
);
sub store_data {
my $self = shift;
... read lines...
$self->csv->parse($line);
}
__PACKAGE__->meta->make_immutable;
1;
but when calling $self->csv->parse
in the subroutine I get the following error:
cant call method 'parse' on an undefined value
It's not entirely clear to me how OOP works with Moose; is has
a replacement for use
? If so, I'm not sure why the module specified isn't instantiated (or maybe it is??).
Upvotes: 0
Views: 338
Reputation: 6798
has
is not a replacement for use
; it is completely different. has
declares an attribute in your class.
Your declaration:
has 'csv' => (
is => 'ro',
isa => 'Text::CSV',
);
simply declares an attribute called csv
that is readonly ro
and is of the type Text::CSV
. But the type declaration does not import the module for you. You will need to use Text::CSV
separately.
An object instance of My::FH will also need a reference to an instance of Text::CSV. Somewhere in your code you need to instantiate Text::CSV and assign it to your csv
attribute. Moose does not initialise the attribute automatically for you (unless you include some extra options in your attribute declaration). You could do it using the default
or builder
(with lazy
) options:
has csv => (
is => 'ro',
isa => 'Text::CSV',
default => sub { Text::CSV->new( { your => 'options' } ) },
);
Alternatively, you could pass it to the constructor (though I'm guessing this is not what you're looking for):
my $fh = My::FH->new( csv => Text::CSV->new );
Have a read of this section of the Moose manual: https://metacpan.org/pod/Moose::Manual::Attributes.
Upvotes: 1