Commit | Line | Data |
44babf1f |
1 | package Moose::Meta::Method::Accessor::Native::Hash::set; |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
d3a83c08 |
6 | use List::MoreUtils (); |
44babf1f |
7 | use Scalar::Util qw( looks_like_number ); |
8 | |
8b9641b8 |
9 | use Moose::Role; |
10 | |
00bbc132 |
11 | with 'Moose::Meta::Method::Accessor::Native::Hash::Writer'; |
44babf1f |
12 | |
13 | sub _minimum_arguments { 2 } |
14 | |
15 | sub _maximum_arguments { undef } |
16 | |
8b9641b8 |
17 | around _inline_check_argument_count => sub { |
18 | my $orig = shift; |
44babf1f |
19 | my $self = shift; |
20 | |
53a4677c |
21 | return ( |
22 | $self->$orig(@_), |
23 | 'if (@_ % 2) {', |
24 | $self->_inline_throw_error( |
53f4ad9f |
25 | sprintf( |
26 | '"You must pass an even number of arguments to %s"', |
27 | $self->delegate_to_method, |
28 | ), |
53a4677c |
29 | ) . ';', |
30 | '}', |
31 | ); |
8b9641b8 |
32 | }; |
44babf1f |
33 | |
34 | sub _inline_process_arguments { |
35 | my $self = shift; |
36 | |
53a4677c |
37 | return ( |
38 | 'my @keys_idx = grep { ! ($_ % 2) } 0..$#_;', |
39 | 'my @values_idx = grep { $_ % 2 } 0..$#_;', |
40 | ); |
44babf1f |
41 | } |
42 | |
43 | sub _inline_check_arguments { |
44 | my $self = shift; |
45 | |
53a4677c |
46 | return ( |
47 | 'for (@keys_idx) {', |
48 | 'if (!defined($_[$_])) {', |
49 | $self->_inline_throw_error( |
53f4ad9f |
50 | sprintf( |
51 | '"Hash keys passed to %s must be defined"', |
52 | $self->delegate_to_method, |
53 | ), |
53a4677c |
54 | ) . ';', |
55 | '}', |
56 | '}', |
57 | ); |
44babf1f |
58 | } |
59 | |
60 | sub _adds_members { 1 } |
61 | |
d3a83c08 |
62 | # We need to override this because while @_ can be written to, we cannot write |
63 | # directly to $_[1]. |
53a4677c |
64 | sub _inline_coerce_new_values { |
d3a83c08 |
65 | my $self = shift; |
66 | |
53a4677c |
67 | return unless $self->associated_attribute->should_coerce; |
d3a83c08 |
68 | |
53a4677c |
69 | return unless $self->_tc_member_type_can_coerce; |
d3a83c08 |
70 | |
71 | # Is there a simpler way to do this? |
53a4677c |
72 | return ( |
73 | 'my $iter = List::MoreUtils::natatime(2, @_);', |
74 | '@_ = ();', |
75 | 'while (my ($key, $val) = $iter->()) {', |
ec02b571 |
76 | 'push @_, $key, $member_coercion->($val);', |
53a4677c |
77 | '}', |
78 | ); |
d3a83c08 |
79 | }; |
80 | |
44babf1f |
81 | sub _potential_value { |
53a4677c |
82 | my $self = shift; |
83 | my ($slot_access) = @_; |
44babf1f |
84 | |
53a4677c |
85 | return '{ %{ (' . $slot_access . ') }, @_ }'; |
44babf1f |
86 | } |
87 | |
88 | sub _new_members { '@_[ @values_idx ]' } |
89 | |
a486d5ad |
90 | sub _inline_optimized_set_new_value { |
53a4677c |
91 | my $self = shift; |
92 | my ($inv, $new, $slot_access) = @_; |
44babf1f |
93 | |
a486d5ad |
94 | return '@{ (' . $slot_access . ') }{ @_[@keys_idx] } = @_[@values_idx];'; |
44babf1f |
95 | } |
96 | |
7f5ec80d |
97 | sub _return_value { |
53a4677c |
98 | my $self = shift; |
99 | my ($slot_access) = @_; |
7f5ec80d |
100 | |
53a4677c |
101 | return 'wantarray ' |
102 | . '? @{ (' . $slot_access . ') }{ @_[@keys_idx] } ' |
103 | . ': ' . $slot_access . '->{ $_[$keys_idx[0]] }'; |
7f5ec80d |
104 | } |
105 | |
8b9641b8 |
106 | no Moose::Role; |
107 | |
44babf1f |
108 | 1; |