1 package Moose::Meta::Method::Accessor::Native::Collection;
8 requires qw( _adds_members );
10 sub _inline_coerce_new_values {
13 return unless $self->associated_attribute->should_coerce;
15 return unless $self->_tc_member_type_can_coerce;
18 '(' . $self->_new_members . ') = map { $member_tc_obj->coerce($_) }',
19 $self->_new_members . ';',
23 sub _tc_member_type_can_coerce {
26 my $member_tc = $self->_tc_member_type;
28 return $member_tc && $member_tc->has_coercion;
34 my $tc = $self->associated_attribute->type_constraint;
36 return $tc->type_parameter
37 if $tc->can('type_parameter');
44 sub _writer_value_needs_copy {
47 return $self->_constraint_must_be_checked
48 && !$self->_check_new_members_only;
54 return unless $self->_constraint_must_be_checked;
56 if ($self->_check_new_members_only) {
57 return unless $self->_adds_members;
59 return $self->_inline_check_member_constraint($self->_new_members);
63 $self->_inline_check_coercion(@_),
64 $self->_inline_check_constraint(@_),
69 sub _check_new_members_only {
72 my $attr = $self->associated_attribute;
74 my $tc = $attr->type_constraint;
76 # If we have a coercion, we could come up with an entirely new value after
77 # coercing, so we need to check everything,
78 return 0 if $attr->should_coerce && $tc->has_coercion;
80 # If the parent is our root type (ArrayRef, HashRef, etc), that means we
81 # can just check the new members of the collection, because we know that
82 # we will always be generating an appropriate collection type.
84 # However, if this type has its own constraint (it's Parameteriz_able_,
85 # not Paramet_erized_), we don't know what is being checked by the
86 # constraint, so we need to check the whole value, not just the members.
88 if $self->_is_root_type( $tc->parent )
89 && $tc->isa('Moose::Meta::TypeConstraint::Parameterized');
94 sub _inline_check_member_constraint {
98 my $attr_name = $self->associated_attribute->name;
101 = $self->_tc_member_type->can_be_inlined
102 ? '! (' . $self->_tc_member_type->_inline_check('$new_val') . ')'
103 : ' !$member_tc->($new_val) ';
106 'for my $new_val (' . $new_value . ') {',
108 $self->_inline_throw_error(
109 '"A new member value for ' . $attr_name
110 . ' does not pass its type constraint because: "'
111 . ' . $member_tc_obj->get_message($new_val)',
119 sub _inline_get_old_value_for_trigger {
121 my ($instance, $old) = @_;
123 my $attr = $self->associated_attribute;
124 return unless $attr->has_trigger;
127 'my ' . $old . ' = ' . $self->_has_value($instance),
128 '? ' . $self->_copy_old_value($self->_get_value($instance)),
133 around _eval_environment => sub {
137 my $env = $self->$orig(@_);
139 my $member_tc = $self->_tc_member_type;
141 return $env unless $member_tc;
143 $env->{'$member_tc_obj'} = \($member_tc);
145 $env->{'$member_tc'} = \( $member_tc->_compiled_type_constraint );
147 my $tc_env = $member_tc->inline_environment();
149 $env = { %{$env}, %{$tc_env} };