make github the primary repository
[gitmo/Moose.git] / lib / Moose / Meta / Method / Accessor / Native.pm
CommitLineData
f7fd22b6 1package Moose::Meta::Method::Accessor::Native;
2
3use strict;
4use warnings;
5
6use Carp qw( confess );
7use Scalar::Util qw( blessed weaken );
8
8b9641b8 9use Moose::Role;
f7fd22b6 10
8b9641b8 11around new => sub {
12 my $orig = shift;
f7fd22b6 13 my $class = shift;
14 my %options = @_;
15
1e2c801e 16 $options{curried_arguments} = []
17 unless exists $options{curried_arguments};
f7fd22b6 18
1e2c801e 19 confess 'You must supply a curried_arguments which is an ARRAY reference'
20 unless $options{curried_arguments}
21 && ref($options{curried_arguments}) eq 'ARRAY';
f7fd22b6 22
4e2f0ea7 23 my $attr_context = $options{attribute}->definition_context;
24 my $desc = 'native delegation method ';
25 $desc .= $options{attribute}->associated_class->name;
26 $desc .= '::' . $options{name};
27 $desc .= " ($options{delegate_to_method})";
28 $desc .= " of attribute " . $options{attribute}->name;
29 $options{definition_context} = {
30 %{ $attr_context || {} },
31 description => $desc,
32 };
f5f08b5f 33
8b9641b8 34 $options{accessor_type} = 'native';
f7fd22b6 35
8b9641b8 36 return $class->$orig(%options);
37};
f7fd22b6 38
53a4677c 39sub _new {
f7fd22b6 40 my $class = shift;
41 my $options = @_ == 1 ? $_[0] : {@_};
42
43 return bless $options, $class;
53a4677c 44}
f7fd22b6 45
a6ae7438 46sub root_types { (shift)->{'root_types'} }
47
f7fd22b6 48sub _initialize_body {
49 my $self = shift;
50
53a4677c 51 $self->{'body'} = $self->_compile_code( [$self->_generate_method] );
f7fd22b6 52
53 return;
54}
55
855f4af8 56sub _inline_curried_arguments {
57 my $self = shift;
58
53a4677c 59 return unless @{ $self->curried_arguments };
855f4af8 60
1e2c801e 61 return 'unshift @_, @curried;';
855f4af8 62}
63
64sub _inline_check_argument_count {
65 my $self = shift;
66
53a4677c 67 my @code;
68
69 if (my $min = $self->_minimum_arguments) {
70 push @code, (
71 'if (@_ < ' . $min . ') {',
72 $self->_inline_throw_error(
73 sprintf(
74 '"Cannot call %s without at least %s argument%s"',
75 $self->delegate_to_method,
76 $min,
77 ($min == 1 ? '' : 's'),
78 )
79 ) . ';',
80 '}',
855f4af8 81 );
855f4af8 82 }
83
53a4677c 84 if (defined(my $max = $self->_maximum_arguments)) {
85 push @code, (
86 'if (@_ > ' . $max . ') {',
87 $self->_inline_throw_error(
88 sprintf(
89 '"Cannot call %s with %s argument%s"',
90 $self->delegate_to_method,
91 $max ? "more than $max" : 'any',
92 ($max == 1 ? '' : 's'),
93 )
94 ) . ';',
95 '}',
855f4af8 96 );
855f4af8 97 }
98
53a4677c 99 return @code;
100}
101
102sub _inline_return_value {
103 my $self = shift;
104 my ($slot_access, $for_writer) = @_;
105
1e2c801e 106 return 'return ' . $self->_return_value($slot_access, $for_writer) . ';';
855f4af8 107}
108
109sub _minimum_arguments { 0 }
110sub _maximum_arguments { undef }
111
1e2c801e 112override _get_value => sub {
53a4677c 113 my $self = shift;
114 my ($instance) = @_;
54e259f6 115
116 return $self->_slot_access_can_be_inlined
8b9641b8 117 ? super()
53a4677c 118 : $instance . '->$reader';
8b9641b8 119};
54e259f6 120
a486d5ad 121override _inline_store_value => sub {
53a4677c 122 my $self = shift;
123 my ($instance, $value) = @_;
54e259f6 124
125 return $self->_slot_access_can_be_inlined
8b9641b8 126 ? super()
a486d5ad 127 : $instance . '->$writer(' . $value . ');';
8b9641b8 128};
54e259f6 129
8b9641b8 130override _eval_environment => sub {
54e259f6 131 my $self = shift;
132
8b9641b8 133 my $env = super();
54e259f6 134
135 $env->{'@curried'} = $self->curried_arguments;
136
137 return $env if $self->_slot_access_can_be_inlined;
138
139 my $reader = $self->associated_attribute->get_read_method_ref;
140 $reader = $reader->body if blessed $reader;
141
142 $env->{'$reader'} = \$reader;
143
144 my $writer = $self->associated_attribute->get_write_method_ref;
145 $writer = $writer->body if blessed $writer;
146
147 $env->{'$writer'} = \$writer;
148
149 return $env;
8b9641b8 150};
54e259f6 151
152sub _slot_access_can_be_inlined {
153 my $self = shift;
154
155 return $self->is_inline && $self->_instance_is_inlinable;
156}
157
8b9641b8 158no Moose::Role;
159
f7fd22b6 1601;