From: Yuval Kogman Date: Thu, 26 Jun 2008 08:42:40 +0000 (+0000) Subject: BUILDARGS, but no tests yet X-Git-Tag: 0_55~91^2~1 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=7bec196c5513eab13177370e65889ac9af4489de;p=gitmo%2FMoose.git BUILDARGS, but no tests yet --- diff --git a/lib/Moose/Meta/Method/Constructor.pm b/lib/Moose/Meta/Method/Constructor.pm index 54921cd..1012d08 100644 --- a/lib/Moose/Meta/Method/Constructor.pm +++ b/lib/Moose/Meta/Method/Constructor.pm @@ -75,12 +75,9 @@ sub initialize_body { $source .= "\n" . 'return $class->Moose::Object::new(@_)'; $source .= "\n" . ' if $class ne \'' . $self->associated_metaclass->name . '\';'; - $source .= "\n" . 'confess "Single parameters to new() must be a HASH ref"'; - $source .= "\n" . ' if scalar @_ == 1 && defined $_[0] && ref($_[0]) ne q{HASH};'; + $source .= "\n" . 'my $params = ' . $self->_generate_BUILDARGS('$class', '@_'); - $source .= "\n" . 'my %params = (scalar @_ == 1) ? %{$_[0]} : @_;'; - - $source .= "\n" . 'my $instance = ' . $self->meta_instance->inline_create_instance('$class'); + $source .= ";\n" . 'my $instance = ' . $self->meta_instance->inline_create_instance('$class'); $source .= ";\n" . (join ";\n" => map { $self->_generate_slot_initializer($_) @@ -123,11 +120,29 @@ sub initialize_body { $self->{'&!body'} = $code; } +sub _generate_BUILDARGS { + my ( $self, $class, $args ) = @_; + + my $buildargs = $self->associated_metaclass->find_method_by_name("BUILDARGS"); + + if ( !$buildargs || $buildargs->body == \&Moose::Object::BUILDARGS and $args eq '@_') { + return join("\n", + 'do {', + 'confess "Single parameters to new() must be a HASH ref"', + ' if scalar @_ == 1 && defined $_[0] && ref($_[0]) ne q{HASH};', + '(scalar @_ == 1) ? {%{$_[0]}} : {@_};', + '}', + ); + } else { + return $class . "->BUILDARGS($args)"; + } +} + sub _generate_BUILDALL { my $self = shift; my @BUILD_calls; foreach my $method (reverse $self->associated_metaclass->find_all_methods_by_name('BUILD')) { - push @BUILD_calls => '$instance->' . $method->{class} . '::BUILD(\%params)'; + push @BUILD_calls => '$instance->' . $method->{class} . '::BUILD($params)'; } return join ";\n" => @BUILD_calls; } @@ -140,7 +155,7 @@ sub _generate_triggers { if ($attr->can('has_trigger') && $attr->has_trigger) { if (defined(my $init_arg = $attr->init_arg)) { push @trigger_calls => ( - '(exists $params{\'' . $init_arg . '\'}) && do {' . "\n " + '(exists $params->{\'' . $init_arg . '\'}) && do {' . "\n " . '$attrs->[' . $i . ']->trigger->(' . '$instance, ' . $self->meta_instance->inline_get_slot_value( @@ -169,16 +184,16 @@ sub _generate_slot_initializer { my $is_moose = $attr->isa('Moose::Meta::Attribute'); # XXX FIXME if ($is_moose && defined($attr->init_arg) && $attr->is_required && !$attr->has_default && !$attr->has_builder) { - push @source => ('(exists $params{\'' . $attr->init_arg . '\'}) ' . + push @source => ('(exists $params->{\'' . $attr->init_arg . '\'}) ' . '|| confess "Attribute (' . $attr->name . ') is required";'); } if (($attr->has_default || $attr->has_builder) && !($is_moose && $attr->is_lazy)) { if ( defined( my $init_arg = $attr->init_arg ) ) { - push @source => 'if (exists $params{\'' . $init_arg . '\'}) {'; + push @source => 'if (exists $params->{\'' . $init_arg . '\'}) {'; - push @source => ('my $val = $params{\'' . $init_arg . '\'};'); + push @source => ('my $val = $params->{\'' . $init_arg . '\'};'); if ($is_moose && $attr->has_type_constraint) { if ($attr->should_coerce && $attr->type_constraint->has_coercion) { @@ -224,9 +239,9 @@ sub _generate_slot_initializer { push @source => "}" if defined $attr->init_arg; } elsif ( defined( my $init_arg = $attr->init_arg ) ) { - push @source => '(exists $params{\'' . $init_arg . '\'}) && do {'; + push @source => '(exists $params->{\'' . $init_arg . '\'}) && do {'; - push @source => ('my $val = $params{\'' . $init_arg . '\'};'); + push @source => ('my $val = $params->{\'' . $init_arg . '\'};'); if ($is_moose && $attr->has_type_constraint) { if ($attr->should_coerce && $attr->type_constraint->has_coercion) { push @source => $self->_generate_type_coercion( diff --git a/lib/Moose/Object.pm b/lib/Moose/Object.pm index d0a1555..7fc09a7 100644 --- a/lib/Moose/Object.pm +++ b/lib/Moose/Object.pm @@ -14,20 +14,26 @@ our $AUTHORITY = 'cpan:STEVAN'; sub new { my $class = shift; - my %params; + my $params = $class->BUILDARGS(@_); + my $self = $class->meta->new_object(%$params); + $self->BUILDALL($params); + return $self; +} + +sub BUILDARGS { + my $class = shift; + if (scalar @_ == 1) { if (defined $_[0]) { (ref($_[0]) eq 'HASH') || confess "Single parameters to new() must be a HASH ref"; - %params = %{$_[0]}; + return {%{$_[0]}}; } + + return {}; # FIXME this is compat behavior, but is it correct? + } else { + return {@_}; } - else { - %params = @_; - } - my $self = $class->meta->new_object(%params); - $self->BUILDALL(\%params); - return $self; } sub BUILDALL { @@ -128,7 +134,12 @@ This will return the metaclass associated with the given class. =item B -This will create a new instance and call C. +This will call C, create a new instance and call C. + +=item B + +This method processes an argument list into a hash reference. It is used by +C. =item B