0

I'm trying to understand better how the Currying in Moose works.

I have used the example in the documentation above, but it doesn't look to work as it is.

If I call

set_user_agent('MyClient');

I get the following error:

Cannot delegate set_user_agent to header because the value of request is not defined at /opt/xt/xt-perl/lib/site_perl/5.18/x86_64-linux/Moose/Exception.pm line 37
Moose::Exception::_build_trace('Moose::Exception::AttributeValueIsNotDefined=HASH(0x7f5f108)') called at reader Moose::Exception::trace (defined at /opt/xt/xt-perl/lib/site_perl/5.18/x86_64-linux/Moose/Exception.pm line 9) line 7
Moose::Exception::trace('Moose::Exception::AttributeValueIsNotDefined=HASH(0x7f5f108)') called at /opt/xt/xt-perl/lib/site_perl/5.18/x86_64-linux/Moose/Exception.pm line 49
Moose::Exception::BUILD('Moose::Exception::AttributeValueIsNotDefined=HASH(0x7f5f108)', 'HASH(0x7f945a8)') called at /opt/xt/xt-perl/lib/site_perl/5.18/x86_64-linux/Class/MOP/Method.pm line 128
Class::MOP::Method::execute('Moose::Meta::Method=HASH(0x8ed3200)', 'Moose::Exception::AttributeValueIsNotDefined=HASH(0x7f5f108)', 'HASH(0x7f945a8)') called at /opt/xt/xt-perl/lib/site_perl/5.18/x86_64-linux/Moose/Object.pm line 56
Moose::Object::BUILDALL('Moose::Exception::AttributeValueIsNotDefined=HASH(0x7f5f108)', 'HASH(0x7f945a8)') called at /opt/xt/xt-perl/lib/site_perl/5.18/x86_64-linux/Moose/Meta/Class.pm line 290
Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x8e192e8)', 'HASH(0x7f945a8)') called at /opt/xt/xt-perl/lib/site_perl/5.18/x86_64-linux/Moose/Object.pm line 27
Moose::Object::new('Moose::Exception::AttributeValueIsNotDefined', 'method', 'Moose::Meta::Method::Delegation=HASH(0x887cd78)', 'instance', 'Spider=HASH(0x7f4c910)', 'attribute', 'Moose::Meta::Attribute=HASH(0x8cbc7f8)') called at /opt/xt/xt-perl/lib/site_perl/5.18/x86_64-linux/Moose/Util.pm line 52
Moose::Util::throw_exception('AttributeValueIsNotDefined', 'method', 'Moose::Meta::Method::Delegation=HASH(0x887cd78)', 'instance', 'Spider=HASH(0x7f4c910)', 'attribute', 'Moose::Meta::Attribute=HASH(0x8cbc7f8)') called at /opt/xt/xt-perl/lib/site_perl/5.18/x86_64-linux/Moose/Meta/Method/Delegation.pm line 98
Spider::set_user_agent('Spider=HASH(0x7f4c910)', 'MyClient') called at main.pl line 9
barbasa
  • 675
  • 4
  • 22

2 Answers2

5

It looks like the example need to be slightly modified.

Apparently the request attribute needs to have a default:

package Spider;

use Moose;
use HTTP::Request;

has request => (
    is      => 'ro',
    isa     => 'HTTP::Request',
    default => sub { HTTP::Request->new },
    handles => {
        set_user_agent => [ header => 'UserAgent' ],
    },
);
barbasa
  • 675
  • 4
  • 22
  • 1
    To work without passing one into the constructor, yes. From the doc you quoted: "MISSING ATTRIBUTES - It is perfectly valid to delegate methods to an attribute which is not required or can be undefined. When a delegated method is called, Moose will throw a runtime error if the attribute does not contain an object." This is what you experienced. – Oesor Jul 15 '14 at 15:57
1

Thanks @Oesor for the clarification.

Just to translate your comment into code:

package Spider;

use Moose;
use HTTP::Request;

sub BUILD {
    my $self = shift;
    $self->request(HTTP::Request->new() );
}

has request => (
    is      => 'rw',
    isa     => 'HTTP::Request',
    handles => {
        set_user_agent => [ header => 'UserAgent' ],
    },
);
barbasa
  • 675
  • 4
  • 22