Fix typo in comment
[gitmo/Moose.git] / lib / Moose / Meta / Class.pm
index 7278393..ced2a76 100644 (file)
@@ -8,10 +8,10 @@ use Class::MOP;
 
 use Carp ();
 use List::Util qw( first );
-use List::MoreUtils qw( any all );
+use List::MoreUtils qw( any all uniq );
 use Scalar::Util 'weaken', 'blessed';
 
-our $VERSION   = '0.57';
+our $VERSION   = '0.59';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
@@ -28,12 +28,12 @@ __PACKAGE__->meta->add_attribute('roles' => (
 
 __PACKAGE__->meta->add_attribute('constructor_class' => (
     accessor => 'constructor_class',
-    default  => sub { 'Moose::Meta::Method::Constructor' }
+    default  => 'Moose::Meta::Method::Constructor',
 ));
 
 __PACKAGE__->meta->add_attribute('destructor_class' => (
     accessor => 'destructor_class',
-    default  => sub { 'Moose::Meta::Method::Destructor' }
+    default  => 'Moose::Meta::Method::Destructor',
 ));
 
 __PACKAGE__->meta->add_attribute('error_class' => (
@@ -60,11 +60,12 @@ sub create {
     (ref $options{roles} eq 'ARRAY')
         || $self->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
             if exists $options{roles};
+    my $roles = delete $options{roles};
 
     my $class = $self->SUPER::create($package_name, %options);
 
-    if (exists $options{roles}) {
-        Moose::Util::apply_all_roles($class, @{$options{roles}});
+    if ($roles) {
+        Moose::Util::apply_all_roles( $class, @$roles );
     }
     
     return $class;
@@ -151,33 +152,31 @@ sub excludes_role {
 }
 
 sub new_object {
-    my $class = shift;
+    my $class  = shift;
     my $params = @_ == 1 ? $_[0] : {@_};
-    my $self = $class->SUPER::new_object($params);
-    foreach my $attr ($class->compute_all_applicable_attributes()) {
-        # if we have a trigger, then ...
-        if ($attr->can('has_trigger') && $attr->has_trigger) {
-            # make sure we have an init-arg ...
-            if (defined(my $init_arg = $attr->init_arg)) {
-                # now make sure an init-arg was passes ...
-                if (exists $params->{$init_arg}) {
-                    # and if get here, fire the trigger
-                    $attr->trigger->(
-                        $self, 
-                        # check if there is a coercion
-                        ($attr->should_coerce
-                            # and if so, we need to grab the 
-                            # value that is actually been stored
-                            ? $attr->get_read_method_ref->($self)
-                            # otherwise, just get the value from
-                            # the constructor params
-                            : $params->{$init_arg}), 
-                        $attr
-                    );
-                }
-            }       
-        }
+    my $self   = $class->SUPER::new_object($params);
+
+    foreach my $attr ( $class->compute_all_applicable_attributes() ) {
+
+        next unless $attr->can('has_trigger') && $attr->has_trigger;
+
+        my $init_arg = $attr->init_arg;
+
+        next unless defined $init_arg;
+
+        next unless exists $params->{$init_arg};
+
+        $attr->trigger->(
+            $self,
+            (
+                  $attr->should_coerce
+                ? $attr->get_read_method_ref->($self)
+                : $params->{$init_arg}
+            ),
+            $attr
+        );
     }
+
     return $self;
 }
 
@@ -350,7 +349,8 @@ sub _superclass_meta_is_compatible {
 
 # I don't want to have to type this >1 time
 my @MetaClassTypes =
-    qw( attribute_metaclass method_metaclass instance_metaclass constructor_class destructor_class );
+    qw( attribute_metaclass method_metaclass instance_metaclass
+        constructor_class destructor_class error_class );
 
 sub _reconcile_with_superclass_meta {
     my ($self, $super) = @_;
@@ -385,7 +385,8 @@ sub _reinitialize_with {
         instance_metaclass  => $new_meta->instance_metaclass,
     );
 
-    $new_self->$_( $new_meta->$_ ) for qw( constructor_class destructor_class );
+    $new_self->$_( $new_meta->$_ )
+        for qw( constructor_class destructor_class error_class );
 
     %$self = %$new_self;
 
@@ -515,7 +516,7 @@ sub _all_roles_until {
         push @roles, $meta->calculate_all_roles;
     }
 
-    return @roles;
+    return uniq @roles;
 }
 
 sub _reconcile_role_differences {
@@ -563,7 +564,7 @@ sub _process_attribute {
 
     @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
 
-    if ($name =~ /^\+(.*)/) {
+    if (($name || '') =~ /^\+(.*)/) {
         return $self->_process_inherited_attribute($1, @args);
     }
     else {
@@ -653,8 +654,6 @@ sub make_immutable {
       );
 }
 
-#{ package Moose::Meta::Class::ErrorRoutines; %Carp::Internal?
-
 our $error_level;
 
 sub throw_error {
@@ -685,6 +684,8 @@ sub create_error {
 
     my $class = ref $self ? $self->error_class : "Moose::Error::Default";
 
+    Class::MOP::load_class($class);
+
     $class->new(
         Carp::caller_info($args{depth}),
         %args
@@ -810,6 +811,12 @@ immutable. These default to L<Moose::Meta::Method::Constructor> and
 L<Moose::Meta::Method::Destructor> respectively. These accessors are
 read-write, so you can use them to change the class name.
 
+=item B<error_class ($class_name)>
+
+The name of the class used to throw errors. This default to
+L<Moose::Error::Default>, which generates an error with a stacktrace
+just like C<Carp::confess>.
+
 =item B<check_metaclass_compatibility>
 
 Moose overrides this method from C<Class::MOP::Class> and attempts to