Commit | Line | Data |
f7fd22b6 |
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 | |
f4b86ac0 |
9 | our $VERSION = '1.16'; |
f7fd22b6 |
10 | $VERSION = eval $VERSION; |
11 | our $AUTHORITY = 'cpan:STEVAN'; |
12 | |
8b9641b8 |
13 | use Moose::Role; |
f7fd22b6 |
14 | |
8b9641b8 |
15 | around new => sub { |
16 | my $orig = shift; |
f7fd22b6 |
17 | my $class = shift; |
18 | my %options = @_; |
19 | |
f7fd22b6 |
20 | exists $options{curried_arguments} |
21 | || ( $options{curried_arguments} = [] ); |
22 | |
23 | ( $options{curried_arguments} |
24 | && ( 'ARRAY' eq ref $options{curried_arguments} ) ) |
25 | || confess |
26 | 'You must supply a curried_arguments which is an ARRAY reference'; |
27 | |
f5f08b5f |
28 | $options{definition_context} = $options{attribute}->definition_context; |
29 | |
8b9641b8 |
30 | $options{accessor_type} = 'native'; |
f7fd22b6 |
31 | |
8b9641b8 |
32 | return $class->$orig(%options); |
33 | }; |
f7fd22b6 |
34 | |
8b9641b8 |
35 | around _new => sub { |
36 | shift; |
f7fd22b6 |
37 | my $class = shift; |
38 | my $options = @_ == 1 ? $_[0] : {@_}; |
39 | |
40 | return bless $options, $class; |
8b9641b8 |
41 | }; |
f7fd22b6 |
42 | |
a6ae7438 |
43 | sub root_types { (shift)->{'root_types'} } |
44 | |
f7fd22b6 |
45 | sub _initialize_body { |
46 | my $self = shift; |
47 | |
48 | $self->{'body'} = $self->_eval_code( $self->_generate_method ); |
49 | |
50 | return; |
51 | } |
52 | |
855f4af8 |
53 | sub _inline_curried_arguments { |
54 | my $self = shift; |
55 | |
56 | return q{} unless @{ $self->curried_arguments }; |
57 | |
58 | return 'unshift @_, @curried;' |
59 | } |
60 | |
61 | sub _inline_check_argument_count { |
62 | my $self = shift; |
63 | |
64 | my $code = q{}; |
65 | |
66 | if ( my $min = $self->_minimum_arguments ) { |
67 | my $err_msg = sprintf( |
68 | q{"Cannot call %s without at least %s argument%s"}, |
69 | $self->delegate_to_method, |
70 | $min, |
71 | ( $min == 1 ? q{} : 's' ) |
72 | ); |
73 | |
74 | $code |
75 | .= "\n" |
76 | . $self->_inline_throw_error($err_msg) |
77 | . " unless \@_ >= $min;"; |
78 | } |
79 | |
80 | if ( defined( my $max = $self->_maximum_arguments ) ) { |
81 | my $err_msg = sprintf( |
82 | q{"Cannot call %s with %s argument%s"}, |
83 | $self->delegate_to_method, |
84 | ( $max ? "more than $max" : 'any' ), |
85 | ( $max == 1 ? q{} : 's' ) |
86 | ); |
87 | |
88 | $code |
89 | .= "\n" |
90 | . $self->_inline_throw_error($err_msg) |
91 | . " if \@_ > $max;"; |
92 | } |
93 | |
94 | return $code; |
95 | } |
96 | |
97 | sub _minimum_arguments { 0 } |
98 | sub _maximum_arguments { undef } |
99 | |
8b9641b8 |
100 | override _inline_get => sub { |
54e259f6 |
101 | my ( $self, $instance ) = @_; |
102 | |
103 | return $self->_slot_access_can_be_inlined |
8b9641b8 |
104 | ? super() |
54e259f6 |
105 | : "${instance}->\$reader"; |
8b9641b8 |
106 | }; |
54e259f6 |
107 | |
8b9641b8 |
108 | override _inline_store => sub { |
54e259f6 |
109 | my ( $self, $instance, $value ) = @_; |
110 | |
111 | return $self->_slot_access_can_be_inlined |
8b9641b8 |
112 | ? super() |
54e259f6 |
113 | : "${instance}->\$writer($value)"; |
8b9641b8 |
114 | }; |
54e259f6 |
115 | |
8b9641b8 |
116 | override _eval_environment => sub { |
54e259f6 |
117 | my $self = shift; |
118 | |
8b9641b8 |
119 | my $env = super(); |
54e259f6 |
120 | |
121 | $env->{'@curried'} = $self->curried_arguments; |
122 | |
123 | return $env if $self->_slot_access_can_be_inlined; |
124 | |
125 | my $reader = $self->associated_attribute->get_read_method_ref; |
126 | $reader = $reader->body if blessed $reader; |
127 | |
128 | $env->{'$reader'} = \$reader; |
129 | |
130 | my $writer = $self->associated_attribute->get_write_method_ref; |
131 | $writer = $writer->body if blessed $writer; |
132 | |
133 | $env->{'$writer'} = \$writer; |
134 | |
135 | return $env; |
8b9641b8 |
136 | }; |
54e259f6 |
137 | |
138 | sub _slot_access_can_be_inlined { |
139 | my $self = shift; |
140 | |
141 | return $self->is_inline && $self->_instance_is_inlinable; |
142 | } |
143 | |
8b9641b8 |
144 | no Moose::Role; |
145 | |
f7fd22b6 |
146 | 1; |