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