remove tab. how the fsck did a tab get into my source code? :(
[gitmo/Moo.git] / lib / Method / Generate / Constructor.pm
1 package Method::Generate::Constructor;
2
3 use strictures 1;
4 use Sub::Quote;
5 use base qw(Class::Tiny::Object);
6
7 ##{
8 ##  use Method::Generate::Accessor;
9 ##  my $gen = Method::Generate::Accessor->new;
10 ##  $gen->generate_method(__PACKAGE__, $_, { is => 'ro' })
11 ##    for qw(accessor_generator);
12 ##}
13
14 sub generate_method {
15   my ($self, $into, $name, $spec, $quote_opts) = @_;
16   foreach my $no_init (grep !exists($spec->{$_}{init_arg}), keys %$spec) {
17     $spec->{$no_init}{init_arg} = $no_init;
18   }
19   my $body = '    my $class = shift;'."\n";
20   $body .= $self->_generate_args;
21   $body .= $self->_check_required($spec);
22   $body .= '    my $new = bless({}, $class);'."\n";
23   $body .= $self->_assign_new($spec);
24   $body .= '    return $new;'."\n";
25   quote_sub
26     "${into}::${name}" => $body,
27     (ref($quote_opts) ? ({}, $quote_opts) : ())
28   ;
29 }
30
31 sub _generate_args {
32   my ($self) = @_;
33   q{    my $args = ref($_[0]) eq 'HASH' ? $_[0] : { @_ };}."\n";
34 }
35
36 sub _assign_new {
37   my ($self, $spec) = @_;
38   my (@init, @slots);
39   NAME: foreach my $name (keys %$spec) {
40     my $attr_spec = $spec->{$name};
41     push @init, do {
42       next NAME unless defined(my $i = $attr_spec->{init_arg});
43       $i;
44     };
45     push @slots, $name;
46   }
47   '    @{$new}{qw('.join(' ',@slots).')} = @{$args}{qw('.join(' ',@init).')};'
48     ."\n";
49 }
50
51 sub _check_required {
52   my ($self, $spec) = @_;
53   my @required_init =
54     map $spec->{$_}{init_arg},
55       grep $spec->{$_}{required},
56         keys %$spec;
57   return '' unless @required_init;
58   '    if (my @missing = grep !exists $args->{$_}, qw('
59     .join(' ',@required_init).')) {'."\n"
60     .q{      die "Missing required arguments: ".join(', ', sort @missing);}."\n"
61     ."    }\n";
62 }
63
64 1;