make class data unlock and relock classes if immutable
[catagits/Catalyst-Runtime.git] / lib / Catalyst / ClassData.pm
1 package Catalyst::ClassData;
2
3 use Moose::Role;
4 use Class::MOP;
5 use Scalar::Util 'blessed';
6
7 sub mk_classdata {
8   my ($class, $attribute) = @_;
9   confess("mk_classdata() is a class method, not an object method")
10     if blessed $class;
11
12   my $slot = '$'.$attribute;
13   my $accessor =  sub {
14     my $meta = $_[0]->meta;
15     if(@_ > 1){
16       $meta->namespace->{$attribute} = \$_[1];
17       return $_[1];
18     }
19
20     if( $meta->has_package_symbol($slot) ){
21       return ${ $meta->get_package_symbol($slot) };
22     } else {
23       foreach my $super ( $meta->linearized_isa ) {
24         my $super_meta = Moose::Meta::Class->initialize($super);
25         if( $super_meta->has_package_symbol($slot) ){
26           return ${ $super_meta->get_package_symbol($slot) };
27         }
28       }
29     }
30     return;
31   };
32
33   confess("Failed to create accessor: $@ ")
34     unless ref $accessor eq 'CODE';
35
36   my $meta = $class->meta;
37   my $immutable_options;
38   if( $meta->is_immutable ){
39     $immutable_options = $meta->get_immutable_options;
40     $meta->make_mutable;
41   }
42   my $alias = "_${attribute}_accessor";
43   $meta->add_method($alias, $accessor);
44   $meta->add_method($attribute, $accessor);
45   if(defined $immutable_options){
46     $meta->make_immutable($immutable_options);
47   }
48   $class->$attribute($_[2]) if(@_ > 2);
49   return $accessor;
50 }
51
52 1;
53
54 __END__
55
56
57 =head1 NAME
58
59 Catalyst::ClassData - Class data acessors
60
61 =head1 METHODS
62
63 =head2 mk_classdata $name, $optional_value
64
65 A moose-safe clone of L<Class::Data::Inheritable> that borrows some ideas from
66 L<Class::Accessor::Grouped>;
67
68 =head1 AUTHOR
69
70 Guillermo Roditi
71
72 =head1 COPYRIGHT
73
74 This program is free software, you can redistribute it and/or modify it under
75 the same terms as Perl itself.
76
77 =cut