a few tweaks here and there and a new proposal for Immutable classes
Stevan Little [Sat, 28 Oct 2006 18:17:57 +0000 (18:17 +0000)]
lib/Class/MOP/Class.pm
lib/Class/MOP/Class/Immutable.pm
lib/Class/MOP/Immutable.pm [new file with mode: 0644]
lib/Class/MOP/Method/Accessor.pm
lib/Class/MOP/Method/Constructor.pm

index 30760be..2467bbb 100644 (file)
@@ -70,7 +70,6 @@ sub construct_class_instance {
                         : blessed($class))
                     : $class);
 
-    $class = blessed($class) || $class;
     # now create the metaclass
     my $meta;
     if ($class =~ /^Class::MOP::Class$/) {
index 2b020b4..0f58927 100644 (file)
@@ -43,19 +43,6 @@ for my $meth (qw(
     };
 }
 
-sub get_package_symbol {
-    my ($self, $variable) = @_;    
-    my ($name, $sigil, $type) = $self->_deconstruct_variable_name($variable); 
-    return *{$self->namespace->{$name}}{$type}
-        if exists $self->namespace->{$name};
-    # NOTE: 
-    # we have to do this here in order to preserve 
-    # perl's autovivification of variables. However 
-    # we do cut off direct access to add_package_symbol
-    # as shown above.
-    $self->Class::MOP::Package::add_package_symbol($variable);
-}
-
 # NOTE:
 # superclasses is an accessor, so 
 # it just cannot be changed
@@ -109,7 +96,7 @@ sub make_metaclass_immutable {
     }
     
     # now cache the method map ...
-    $metaclass->{'___method_map'} = $metaclass->get_method_map;
+    $metaclass->{'___get_method_map'} = $metaclass->get_method_map;
           
     bless $metaclass => $class;
 }
@@ -120,7 +107,7 @@ sub get_meta_instance                 {   (shift)->{'___get_meta_instance'}
 sub class_precedence_list             { @{(shift)->{'___class_precedence_list'}}             }
 sub compute_all_applicable_attributes { @{(shift)->{'___compute_all_applicable_attributes'}} }
 sub get_mutable_metaclass_name        {   (shift)->{'___original_class'}                     }
-sub get_method_map                    {   (shift)->{'___method_map'}                         }
+sub get_method_map                    {   (shift)->{'___get_method_map'}                     }
 
 1;
 
@@ -241,11 +228,6 @@ to this method, which
 
 This method becomes read-only in an immutable class.
 
-=item B<get_package_symbol>
-
-This method must handle package variable autovivification 
-correctly, while still disallowing C<add_package_symbol>.
-
 =back
 
 =head2 Cached methods
diff --git a/lib/Class/MOP/Immutable.pm b/lib/Class/MOP/Immutable.pm
new file mode 100644 (file)
index 0000000..4e4c33e
--- /dev/null
@@ -0,0 +1,133 @@
+
+package Class::MOP::Immutable;
+
+1;
+
+__END__
+
+=pod
+
+Okay, so here is the basic idea.
+
+First, your metaclass must register with Class::MOP::Immutable
+at which point an anon-class is created which will be the 
+immutable class which your metaclass will be blessed into. 
+
+This allows immutable versions of any metaclass to be created
+on the fly if needed. 
+
+NOTE:
+Remember the immutable version of the metaclass will be used to 
+construct/convert mutable instances into immutable versions. So 
+it itself is a metaclass.
+
+  Class::MOP::Immutable->make_immutable_metaclass(
+      # name of the metaclass we are 
+      # making immutable
+      metaclass => 'Class::MOP::Class',
+      
+      # names of some method metaclasses
+      # which will be useful in the creation
+      # of the immutable versions
+      constructor_class => 'Class::MOP::Method::Constructor',
+      accessor_class    => 'Class::MOP::Method::Accessor',    # ?? maybe
+      
+      # options which the immutable converter
+      # will accept, not exactly sure about 
+      # this one,.. it might have to be hard 
+      # coded in some way.
+      available_options => [qw[
+          inline_accessors
+          inline_constructor
+          constructor_name
+      ]],    
+      
+      # multiple lists of things which can 
+      # be done to the metaclass .. 
+      
+      # make these methods die when called
+      disallow  => [qw[
+          add_method
+          alias_method
+          remove_method
+          add_attribute
+          remove_attribute
+          add_package_symbol
+          remove_package_symbol
+      ]],
+      
+      # memoize the value of these methods
+      memoize   => [qw[
+          class_precedence_list
+          compute_all_applicable_attributes
+          get_meta_instance            
+          get_method_map
+      ]],
+      
+      # make these methods read only
+      readonly  => [qw[
+          superclasses
+      ]],
+  );
+
+Now, this will work just fine for singular metas, but 
+we want this to be able to work for extensions to the 
+metaclasses as well.
+
+Here is how we do that:
+
+  Class::MOP::Immutable->make_immutable_metaclass(
+      # the metaclass name ...
+      metaclass => 'Moose::Meta::Class',
+      
+      # inherit the options from immutable 
+      # parent class (Class::MOP::Class)
+      inherit   => 1
+      
+      constructor_class => 'Moose::Method::Constructor',
+      accessor_class    => 'Moose::Method::Accessor',    # ?? maybe    
+      
+      disallow => [qw[
+          add_roles
+          ...
+      ]],
+      
+      memoize => [qw[
+          roles
+          ...
+      ]]    
+  );
+
+When you specify C<inherit => 1> you are telling 
+Class::MOP::Immutable that you want to inherit your 
+parents options. This means that you get all their
+and yours (perhaps some basic conflict resolution 
+can be added here as well).
+
+It might make sense to also allow a more granular 
+approach such as:
+
+  inherit => {
+      disallow => 'merge',
+      memoize  => 'override',
+      readonly => 'ignore',
+  }
+
+which would allow you to specify in more detail how 
+you would like to handle each change. This might be 
+more than anyone ever needs so we can probably hold 
+off for now.
+
+Ultimately it will be the responsibility of the 
+author to make sure their immutable options make sense.
+
+The reason I say this is that you could easily get 
+carried away in the number of items you choose to 
+memoize or such. This would not make a lot of sense, 
+it would make more sense to memoize at the "topmost"
+level instead, rather than all the intermediate ones.
+
+It's basically gonna be a trade off.
+
+=cut
+
index 1f8eb04..237dd0e 100644 (file)
@@ -232,8 +232,6 @@ Class::MOP::Method::Accessor - Method Meta Object for accessors
 
 Stevan Little E<lt>stevan@iinteractive.comE<gt>
 
-Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
-
 =head1 COPYRIGHT AND LICENSE
 
 Copyright 2006 by Infinity Interactive, Inc.
index 7b7d921..08812bc 100644 (file)
@@ -156,8 +156,6 @@ Class::MOP::Method::Constructor - Method Meta Object for constructors
 
 Stevan Little E<lt>stevan@iinteractive.comE<gt>
 
-Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
-
 =head1 COPYRIGHT AND LICENSE
 
 Copyright 2006 by Infinity Interactive, Inc.