use strict;
use warnings;
-use Scalar::Util 'weaken';
-use Carp 'confess';
+use Mouse::Util qw(does dump);
sub new {
my $class = shift;
- my $args = $class->BUILDARGS(@_);
+ $class->throw_error('Cannot call new() on an instance') if ref $class;
- my $instance = bless {}, $class;
-
- for my $attribute ($class->meta->compute_all_applicable_attributes) {
- my $from = $attribute->init_arg;
- my $key = $attribute->name;
-
- if (defined($from) && exists($args->{$from})) {
- $args->{$from} = $attribute->coerce_constraint($args->{$from})
- if $attribute->should_coerce;
- $attribute->verify_against_type_constraint($args->{$from});
-
- $instance->{$key} = $args->{$from};
-
- weaken($instance->{$key})
- if ref($instance->{$key}) && $attribute->is_weak_ref;
-
- if ($attribute->has_trigger) {
- $attribute->trigger->($instance, $args->{$from}, $attribute);
- }
- }
- else {
- if ($attribute->has_default || $attribute->has_builder) {
- unless ($attribute->is_lazy) {
- my $default = $attribute->default;
- my $builder = $attribute->builder;
- my $value = $attribute->has_builder
- ? $instance->$builder
- : ref($default) eq 'CODE'
- ? $default->($instance)
- : $default;
-
- $value = $attribute->coerce_constraint($value)
- if $attribute->should_coerce;
- $attribute->verify_against_type_constraint($value);
-
- $instance->{$key} = $value;
-
- weaken($instance->{$key})
- if ref($instance->{$key}) && $attribute->is_weak_ref;
- }
- }
- else {
- if ($attribute->is_required) {
- confess "Attribute (".$attribute->name.") is required";
- }
- }
- }
- }
+ my $args = $class->BUILDARGS(@_);
+ my $instance = Mouse::Meta::Class->initialize($class)->new_object($args);
$instance->BUILDALL($args);
-
return $instance;
}
my $class = shift;
if (scalar @_ == 1) {
- if (defined $_[0]) {
- (ref($_[0]) eq 'HASH')
- || confess "Single parameters to new() must be a HASH ref";
- return {%{$_[0]}};
- } else {
- return {};
- }
+ (ref($_[0]) eq 'HASH')
+ || $class->meta->throw_error("Single parameters to new() must be a HASH ref");
+ return {%{$_[0]}};
}
else {
return {@_};
or next;
$code->($self, @_);
}
+ return;
}
sub DEMOLISHALL {
# short circuit
return unless $self->can('DEMOLISH');
- no strict 'refs';
+ # We cannot count on being able to retrieve a previously made
+ # metaclass, _or_ being able to make a new one during global
+ # destruction. However, we should still be able to use mro at
+ # that time (at least tests suggest so ;)
- for my $class ($self->meta->linearized_isa) {
- my $code = *{ $class . '::DEMOLISH' }{CODE}
- or next;
- $code->($self, @_);
+ foreach my $class (@{ Mouse::Util::get_linear_isa(ref $self) }) {
+ my $demolish = do{ no strict 'refs'; *{"${class}::DEMOLISH"}{CODE} };
+ $self->$demolish()
+ if defined $demolish;
}
+ return;
}
-sub dump {
- my $self = shift;
- require Data::Dumper;
- local $Data::Dumper::Maxdepth = shift if @_;
- Data::Dumper::Dumper $self;
-}
-
-
-sub does {
- my ($self, $role_name) = @_;
- (defined $role_name)
- || confess "You must supply a role name to does()";
- my $meta = $self->meta;
- foreach my $class ($meta->linearized_isa) {
- my $m = $meta->initialize($class);
- return 1
- if $m->can('does_role') && $m->does_role($role_name);
- }
- return 0;
-};
-
1;
__END__