Get inline slot access snippets from attr, not direct from meta-instance
[gitmo/Moose.git] / lib / Moose / Meta / Attribute.pm
index 818efd1..640d1cc 100644 (file)
@@ -9,9 +9,10 @@ use List::MoreUtils 'any';
 use Try::Tiny;
 use overload     ();
 
-our $VERSION   = '1.08';
+our $VERSION   = '1.14';
 our $AUTHORITY = 'cpan:STEVAN';
 
+use Moose::Deprecated;
 use Moose::Meta::Method::Accessor;
 use Moose::Meta::Method::Delegation;
 use Moose::Util ();
@@ -131,7 +132,10 @@ sub interpolate_class {
 
 # ...
 
-sub illegal_options_for_inheritance { }
+# method-generating options shouldn't be overridden
+sub illegal_options_for_inheritance {
+    qw(reader writer accessor clearer predicate)
+}
 
 # NOTE/TODO
 # This method *must* be able to handle
@@ -150,8 +154,6 @@ sub illegal_options_for_inheritance { }
 sub clone_and_inherit_options {
     my ($self, %options) = @_;
 
-    my %copy = %options;
-
     # NOTE:
     # we may want to extends a Class::MOP::Attribute
     # in which case we need to be able to use the
@@ -163,7 +165,7 @@ sub clone_and_inherit_options {
         ? $self->illegal_options_for_inheritance
         : ();
 
-    my @found_illegal_options = grep { exists $options{$_} ? $_ : undef } @illegal_options;
+    my @found_illegal_options = grep { exists $options{$_} && exists $self->{$_} ? $_ : undef } @illegal_options;
     (scalar @found_illegal_options == 0)
         || $self->throw_error("Illegal inherited options => (" . (join ', ' => @found_illegal_options) . ")", data => \%options);
 
@@ -304,7 +306,12 @@ sub _process_options {
 
         unless ( $options->{type_constraint}->has_coercion ) {
             my $type = $options->{type_constraint}->name;
-            $class->throw_error("You cannot coerce an attribute ($name) unless its type ($type) has a coercion", data => $options);
+
+            Moose::Deprecated::deprecated(
+                feature => 'coerce without coercion',
+                message =>
+                    "You cannot coerce an attribute ($name) unless its type ($type) has a coercion"
+            );
         }
     }
 
@@ -553,6 +560,13 @@ sub _process_accessors {
           . "an accessor"
         );
     }
+    if (!$self->associated_class->has_method($accessor)
+     && $self->associated_class->has_package_symbol('&' . $accessor)) {
+        Carp::cluck(
+            "You are overwriting a locally defined function ($accessor) with "
+          . "an accessor"
+        );
+    }
     $self->SUPER::_process_accessors(@_);
 }
 
@@ -563,6 +577,22 @@ sub remove_accessors {
     return;
 }
 
+sub inline_set {
+    my $self = shift;
+    my ( $instance, $value ) = @_;
+
+    my $mi = $self->associated_class->get_meta_instance;
+
+    my $code
+        = $mi->inline_set_slot_value( $instance, $self->slots, $value ) . ";";
+    $code
+        .= $mi->inline_weaken_slot_value( $instance, $self->slots, $value )
+        . ";"
+        if $self->is_weak_ref;
+
+    return $code;
+}
+
 sub install_delegation {
     my $self = shift;
 
@@ -717,7 +747,7 @@ sub _coerce_and_verify {
     return $val unless $self->has_type_constraint;
 
     $val = $self->type_constraint->coerce($val)
-        if $self->should_coerce;
+        if $self->should_coerce && $self->type_constraint->has_coercion;
 
     $self->verify_against_type_constraint($val, instance => $instance);
 
@@ -822,7 +852,7 @@ object which does the named role.
 =item * coerce => $bool
 
 This option is only valid for objects with a type constraint
-(C<isa>). If this is true, then coercions will be applied whenever
+(C<isa>) that defined a coercion. If this is true, then coercions will be applied whenever
 this attribute is set.
 
 You can make both this and the C<weak_ref> option true.
@@ -949,6 +979,12 @@ methods is almost always an error.)
 
 This method overrides the parent to also remove delegation methods.
 
+=item B<< $attr->inline_set($instance_var, $value_var) >>
+
+This method return a code snippet suitable for inlining the relevant
+operation. It expect strings containing variable names to be used in the
+inlining, like C<'$self'> or C<'$_[1]'>.
+
 =item B<< $attr->install_delegation >>
 
 This method adds its delegation methods to the attribute's associated