these can be undef
[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
f5f08b5f 23 $options{definition_context} = $options{attribute}->definition_context;
24
8b9641b8 25 $options{accessor_type} = 'native';
f7fd22b6 26
8b9641b8 27 return $class->$orig(%options);
28};
f7fd22b6 29
53a4677c 30sub _new {
f7fd22b6 31 my $class = shift;
32 my $options = @_ == 1 ? $_[0] : {@_};
33
34 return bless $options, $class;
53a4677c 35}
f7fd22b6 36
a6ae7438 37sub root_types { (shift)->{'root_types'} }
38
f7fd22b6 39sub _initialize_body {
40 my $self = shift;
41
53a4677c 42 $self->{'body'} = $self->_compile_code( [$self->_generate_method] );
f7fd22b6 43
44 return;
45}
46
855f4af8 47sub _inline_curried_arguments {
48 my $self = shift;
49
53a4677c 50 return unless @{ $self->curried_arguments };
855f4af8 51
1e2c801e 52 return 'unshift @_, @curried;';
855f4af8 53}
54
55sub _inline_check_argument_count {
56 my $self = shift;
57
53a4677c 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 '}',
855f4af8 72 );
855f4af8 73 }
74
53a4677c 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 '}',
855f4af8 87 );
855f4af8 88 }
89
53a4677c 90 return @code;
91}
92
93sub _inline_return_value {
94 my $self = shift;
95 my ($slot_access, $for_writer) = @_;
96
1e2c801e 97 return 'return ' . $self->_return_value($slot_access, $for_writer) . ';';
855f4af8 98}
99
100sub _minimum_arguments { 0 }
101sub _maximum_arguments { undef }
102
1e2c801e 103override _get_value => sub {
53a4677c 104 my $self = shift;
105 my ($instance) = @_;
54e259f6 106
107 return $self->_slot_access_can_be_inlined
8b9641b8 108 ? super()
53a4677c 109 : $instance . '->$reader';
8b9641b8 110};
54e259f6 111
a486d5ad 112override _inline_store_value => sub {
53a4677c 113 my $self = shift;
114 my ($instance, $value) = @_;
54e259f6 115
116 return $self->_slot_access_can_be_inlined
8b9641b8 117 ? super()
a486d5ad 118 : $instance . '->$writer(' . $value . ');';
8b9641b8 119};
54e259f6 120
8b9641b8 121override _eval_environment => sub {
54e259f6 122 my $self = shift;
123
8b9641b8 124 my $env = super();
54e259f6 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;
8b9641b8 141};
54e259f6 142
143sub _slot_access_can_be_inlined {
144 my $self = shift;
145
146 return $self->is_inline && $self->_instance_is_inlinable;
147}
148
8b9641b8 149no Moose::Role;
150
f7fd22b6 1511;