fix indentation in generated constructor
[gitmo/Role-Tiny.git] / lib / Method / Generate / Constructor.pm
CommitLineData
6f68f022 1package Method::Generate::Constructor;
2
3use strictures 1;
4use Sub::Quote;
5use 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
14sub 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);
4053679e 24 $body .= ' return $new;'."\n";
6f68f022 25 quote_sub
4053679e 26 "${into}::${name}" => $body,
6f68f022 27 (ref($quote_opts) ? ({}, $quote_opts) : ())
28 ;
29}
30
31sub _generate_args {
32 my ($self) = @_;
33 q{ my $args = ref($_[0]) eq 'HASH' ? $_[0] : { @_ };}."\n";
34}
35
36sub _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
51sub _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
641;