foo
[gitmo/Moose.git] / lib / Moose / Meta / Method / Destructor.pm
1
2 package Moose::Meta::Method::Destructor;
3
4 use strict;
5 use warnings;
6
7 use Carp         'confess';
8 use Scalar::Util 'blessed', 'weaken';
9
10 our $VERSION   = '0.01';
11 our $AUTHORITY = 'cpan:STEVAN';
12
13 use base 'Moose::Meta::Method';
14
15 sub new {
16     my $class   = shift;
17     my %options = @_;
18     
19     (exists $options{options} && ref $options{options} eq 'HASH')
20         || confess "You must pass a hash of options";    
21     
22     my $self = bless {
23         # from our superclass
24         '&!body'          => undef,        
25         # ...
26         '%!options'              => $options{options},        
27         '$!associated_metaclass' => $options{metaclass},
28     } => $class;
29
30     # we don't want this creating 
31     # a cycle in the code, if not 
32     # needed
33     weaken($self->{'$!associated_metaclass'});    
34
35     $self->intialize_body;
36
37     return $self;    
38 }
39
40 ## accessors 
41
42 sub options              { (shift)->{'%!options'}              }
43 sub associated_metaclass { (shift)->{'$!associated_metaclass'} }
44
45 ## method
46
47 sub is_needed { defined $_[0]->{'&!body'} ? 1 : 0 }
48
49 sub intialize_body {
50     my $self = shift;
51     # TODO:
52     # the %options should also include a both 
53     # a call 'initializer' and call 'SUPER::' 
54     # options, which should cover approx 90% 
55     # of the possible use cases (even if it 
56     # requires some adaption on the part of 
57     # the author, after all, nothing is free)
58     my $source = 'sub {';
59
60     my @DEMOLISH_calls;
61     foreach my $method ($self->associated_metaclass->find_all_methods_by_name('DEMOLISH')) {
62         push @DEMOLISH_calls => '$_[0]->' . $method->{class} . '::DEMOLISH()';    
63     }
64     
65     $source .= join "\n" => @DEMOLISH_calls;
66
67     $source .= ";\n" . '}'; 
68     warn $source if $self->options->{debug};    
69     
70     my $code;
71     {
72         $code = eval $source;
73         confess "Could not eval the destructor :\n\n$source\n\nbecause :\n\n$@" if $@;
74     }
75     $self->{'&!body'} = $code;
76 }
77
78
79 1;
80
81 __END__
82
83 =pod
84
85 =cut