Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Moose::Role not getting params passed via ->new()

by italdesign (Novice)
on Sep 18, 2013 at 22:49 UTC ( #1054745=perlquestion: print w/replies, xml ) Need Help??

italdesign has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks. Been programming Perl for several years but just stumbled upon Moose. Anyway, I have a script (wget.pl) that instantiates an object of a class (Wget.pm) that uses a role (Transfer.pm). The problem is when I pass a hash ref to Wget->new(), it's not being received correctly. Here is the relevant parts of the code.

wget.pl

use Module::Load; my $class = 'DTF::Wget'; load $class; my $adapter = $class->new( 'input_line' => $input_line, 'dl_base_dir' +=> $dl_base_dir, 'report_file' => $report_file );

Wget.pm

package DTF::Wget; use strict; use warnings; use Moose; with 'DTF::Transfer';

Transfer.pm

package DTF::Transfer; use strict; use warnings; use Moose::Role; sub BUILD {} after 'BUILD' => sub { my $self = shift; die scalar(keys %$self); }

If all worked, the die statement in the role would print 3, since I passed 3 key-value pairs to the constructor of the class that uses the role. However, it prints 0. $self has absolutely nothing. I tried several variations of this, including moving the BUILD to Wget.pm. The result is always the same - $self is empty. I'm probably missing something obvious. Would appreciate any pointers.

Replies are listed 'Best First'.
Re: Moose::Role not getting params passed via ->new()
by tobyink (Canon) on Sep 19, 2013 at 06:26 UTC

    As derby said, $self will only be populated with keys corresponding to any attributes which have beeen defined for the class (including those defined in any roles the class does).

    You could define your role like this:

    package DTF::Transfer; use strict; use warnings; use Moose::Role; has [qw/ input_line dl_base_dir report_file /] => ( is => 'ro', ); sub BUILD {} after 'BUILD' => sub { my $self = shift; die scalar(keys %$self); };

    More importantly, you're making the mistake of treating $self like it's a hashref. It's not. (Actually it is by default, but you're supposed to pretend it's not. Let's pretend it's not...) Because it's not a hashref, keys %$self is meaningless. Instead you should access attributes via the accessors Moose generates:

    after 'BUILD' => sub { my $self = shift; printf STDERR "%s: %s\n", $_, $self->$_ for qw( input_line dl_base_dir report_file ); die; };

    Lastly, have you noticed that BUILD gets passed not one argument, but two?

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
      Thanks guys! It felt like I was missing some fundamentals. I'm glad you set me on the right path.
Re: Moose::Role not getting params passed via ->new()
by derby (Abbot) on Sep 19, 2013 at 01:16 UTC

    Moose will only set arguments passed in via new if the corresponding attributes are declared in the class. Since DTF::Wget has no attributes, after the BUILD, the class is pretty much empty.

    -derby

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1054745]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2023-02-02 01:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer not to run the latest version of Perl because:







    Results (15 votes). Check out past polls.

    Notices?