Merge branch 'master' into refactor-immutable
Dave Rolsky [Sun, 22 Mar 2009 14:00:58 +0000 (09:00 -0500)]
Conflicts:

lib/Class/MOP/Immutable.pm
lib/Class/MOP/Instance.pm
lib/Class/MOP/Method/Constructor.pm
xt/pod_coverage.t

1  2 
lib/Class/MOP.pm
lib/Class/MOP/Class.pm
lib/Class/MOP/Immutable.pm
xt/pod_coverage.t

diff --combined lib/Class/MOP.pm
@@@ -32,7 -32,7 +32,7 @@@ BEGIN 
      *check_package_cache_flag = \&mro::get_pkg_gen;
  }
  
- our $VERSION   = '0.78';
+ our $VERSION   = '0.78_01';
  our $XS_VERSION = $VERSION;
  $VERSION = eval $VERSION;
  our $AUTHORITY = 'cpan:STEVAN';    
@@@ -329,17 -329,6 +329,17 @@@ Class::MOP::Class->meta->add_attribute
      ))
  );
  
 +Class::MOP::Class->meta->add_attribute(
 +    Class::MOP::Attribute->new('immutable_transformer' => (
 +        reader   => {
 +            'immutable_transformer' => \&Class::MOP::Class::immutable_transformer
 +        },
 +        writer   => {
 +            '_set_immutable_transformer' => \&Class::MOP::Class::_set_immutable_transformer
 +        },
 +    ))
 +);
 +
  # NOTE:
  # we don't actually need to tie the knot with
  # Class::MOP::Class here, it is actually handled
diff --combined lib/Class/MOP/Class.pm
@@@ -11,7 -11,7 +11,7 @@@ use Class::MOP::Method::Wrapped
  use Carp         'confess';
  use Scalar::Util 'blessed', 'weaken';
  
- our $VERSION   = '0.78';
+ our $VERSION   = '0.78_01';
  $VERSION = eval $VERSION;
  our $AUTHORITY = 'cpan:STEVAN';
  
@@@ -73,7 -73,8 +73,7 @@@ sub construct_class_instance 
      # now create the metaclass
      my $meta;
      if ($class eq 'Class::MOP::Class') {
 -        no strict 'refs';
 -        $meta = $class->_new($options)
 +        $meta = $class->_new($options);
      }
      else {
          # NOTE:
@@@ -972,56 -973,108 +972,56 @@@ sub is_pristine 
  sub is_mutable   { 1 }
  sub is_immutable { 0 }
  
 -# NOTE:
 -# Why I changed this (groditi)
 -#  - One Metaclass may have many Classes through many Metaclass instances
 -#  - One Metaclass should only have one Immutable Transformer instance
 -#  - Each Class may have different Immutabilizing options
 -#  - Therefore each Metaclass instance may have different Immutabilizing options
 -#  - We need to store one Immutable Transformer instance per Metaclass
 -#  - We need to store one set of Immutable Transformer options per Class
 -#  - Upon make_mutable we may delete the Immutabilizing options
 -#  - We could clean the immutable Transformer instance when there is no more
 -#      immutable Classes of that type, but we can also keep it in case
 -#      another class with this same Metaclass becomes immutable. It is a case
 -#      of trading of storing an instance to avoid unnecessary instantiations of
 -#      Immutable Transformers. You may view this as a memory leak, however
 -#      Because we have few Metaclasses, in practice it seems acceptable
 -#  - To allow Immutable Transformers instances to be cleaned up we could weaken
 -#      the reference stored in  $IMMUTABLE_TRANSFORMERS{$class} and ||= should DWIM
 -
 -{
 -
 -    my %IMMUTABLE_TRANSFORMERS;
 -    my %IMMUTABLE_OPTIONS;
 -
 -    sub get_immutable_options {
 -        my $self = shift;
 -        return if $self->is_mutable;
 -        confess "unable to find immutabilizing options"
 -            unless exists $IMMUTABLE_OPTIONS{$self->name};
 -        my %options = %{$IMMUTABLE_OPTIONS{$self->name}};
 -        delete $options{IMMUTABLE_TRANSFORMER};
 -        return \%options;
 -    }
 -
 -    sub get_immutable_transformer {
 -        my $self = shift;
 -        if( $self->is_mutable ){
 -            return $IMMUTABLE_TRANSFORMERS{$self->name} ||= $self->create_immutable_transformer;
 -        }
 -        confess "unable to find transformer for immutable class"
 -            unless exists $IMMUTABLE_OPTIONS{$self->name};
 -        return $IMMUTABLE_OPTIONS{$self->name}->{IMMUTABLE_TRANSFORMER};
 -    }
 +sub immutable_transformer { $_[0]->{immutable_transformer} }
 +sub _set_immutable_transformer { $_[0]->{immutable_transformer} = $_[1] }
  
 -    sub make_immutable {
 -        my $self = shift;
 -        my %options = @_;
 +sub make_immutable {
 +    my $self = shift;
  
 -        my $transformer = $self->get_immutable_transformer;
 -        $transformer->make_metaclass_immutable($self, \%options);
 -        $IMMUTABLE_OPTIONS{$self->name} =
 -            { %options,  IMMUTABLE_TRANSFORMER => $transformer };
 +    return if $self->is_immutable;
  
 -        if( exists $options{debug} && $options{debug} ){
 -            print STDERR "# of Metaclass options:      ", keys %IMMUTABLE_OPTIONS;
 -            print STDERR "# of Immutable transformers: ", keys %IMMUTABLE_TRANSFORMERS;
 -        }
 +    my $transformer = $self->immutable_transformer
 +        || $self->_make_immutable_transformer(@_);
  
 -        1;
 -    }
 +    $self->_set_immutable_transformer($transformer);
  
 -    sub make_mutable{
 -        my $self = shift;
 -        return if $self->is_mutable;
 -        my $options = delete $IMMUTABLE_OPTIONS{$self->name};
 -        confess "unable to find immutabilizing options" unless ref $options;
 -        my $transformer = delete $options->{IMMUTABLE_TRANSFORMER};
 -        $transformer->make_metaclass_mutable($self, $options);
 -        1;
 -    }
 +    $transformer->make_metaclass_immutable;
  }
  
 -sub create_immutable_transformer {
 -    my $self = shift;
 -    my $class = Class::MOP::Immutable->new($self, {
 +{
 +    my %Default_Immutable_Options = (
          read_only   => [qw/superclasses/],
 -        cannot_call => [qw/
 -           add_method
 -           alias_method
 -           remove_method
 -           add_attribute
 -           remove_attribute
 -           remove_package_symbol
 -        /],
 -        memoize     => {
 -           class_precedence_list             => 'ARRAY',
 -           linearized_isa                    => 'ARRAY', # FIXME perl 5.10 memoizes this on its own, no need?
 -           get_all_methods                   => 'ARRAY',
 -           get_all_method_names              => 'ARRAY',
 -           #get_all_attributes               => 'ARRAY', # it's an alias, no need, but maybe in the future
 -           compute_all_applicable_attributes => 'ARRAY',
 -           get_meta_instance                 => 'SCALAR',
 -           get_method_map                    => 'SCALAR',
 +        cannot_call => [
 +            qw(
 +                add_method
 +                alias_method
 +                remove_method
 +                add_attribute
 +                remove_attribute
 +                remove_package_symbol
 +                )
 +        ],
 +        memoize => {
 +            class_precedence_list => 'ARRAY',
 +            # FIXME perl 5.10 memoizes this on its own, no need?
 +            linearized_isa                    => 'ARRAY',
 +            get_all_methods                   => 'ARRAY',
 +            get_all_method_names              => 'ARRAY',
 +            compute_all_applicable_attributes => 'ARRAY',
 +            get_meta_instance                 => 'SCALAR',
 +            get_method_map                    => 'SCALAR',
          },
 +
          # NOTE:
 -        # this is ugly, but so are typeglobs, 
 +        # this is ugly, but so are typeglobs,
          # so whattayahgonnadoboutit
          # - SL
 -        wrapped => { 
 +        wrapped => {
              add_package_symbol => sub {
                  my $original = shift;
 -                confess "Cannot add package symbols to an immutable metaclass" 
 -                    unless (caller(2))[3] eq 'Class::MOP::Package::get_package_symbol'; 
 +                confess "Cannot add package symbols to an immutable metaclass"
 +                    unless ( caller(2) )[3] eq
 +                    'Class::MOP::Package::get_package_symbol';
  
                  # This is a workaround for a bug in 5.8.1 which thinks that
                  # goto $original->body
                  goto $body;
              },
          },
 -    });
 -    return $class;
 +    );
 +
 +    sub _default_immutable_transformer_options {
 +        return %Default_Immutable_Options;
 +    }
 +}
 +
 +sub _make_immutable_transformer {
 +    my $self = shift;
 +
 +    Class::MOP::Immutable->new(
 +        $self,
 +        $self->_default_immutable_transformer_options,
 +        @_
 +    );
 +}
 +
 +sub make_mutable {
 +    my $self = shift;
 +
 +    return if $self->is_mutable;
 +
 +    $self->immutable_transformer->make_metaclass_mutable;
  }
  
  1;
@@@ -1528,7 -1560,7 +1528,7 @@@ documentation
  
  Calling this method reverse the immutabilization transformation.
  
 -=item B<< $metaclass->get_immutable_transformer >>
 +=item B<< $metaclass->immutable_transformer >>
  
  If the class has been made immutable previously, this returns the
  L<Class::MOP::Immutable> object that was created to do the
@@@ -9,7 -9,7 +9,7 @@@ use Class::MOP::Method::Constructor
  use Carp         'confess';
  use Scalar::Util 'blessed';
  
- our $VERSION   = '0.78';
+ our $VERSION   = '0.78_01';
  $VERSION = eval $VERSION;
  our $AUTHORITY = 'cpan:STEVAN';
  
@@@ -18,21 -18,23 +18,21 @@@ use base 'Class::MOP::Object'
  sub new {
      my ($class, @args) = @_;
  
 -    my ( $metaclass, $options );
 -
 -    if ( @args == 2 ) {
 -        # compatibility args
 -        ( $metaclass, $options ) = @args;
 -    } else {
 -        unshift @args, "metaclass" if @args % 2 == 1;
 -
 -        # default named args
 -        my %options = @args;
 -        $options = \%options;
 -        $metaclass = $options{metaclass};
 -    }
 +    unshift @args, 'metaclass' if @args % 2 == 1;
 +
 +    my %options = (
 +        inline_accessors   => 1,
 +        inline_constructor => 1,
 +        inline_destructor  => 0,
 +        constructor_name   => 'new',
 +        constructor_class  => 'Class::MOP::Method::Constructor',
 +        debug              => 0,
 +        @args,
 +    );
  
      my $self = $class->_new(
 -        'metaclass'           => $metaclass,
 -        'options'             => $options,
 +        'metaclass'           => delete $options{metaclass},
 +        'options'             => \%options,
          'immutable_metaclass' => undef,
          'inlined_constructor' => undef,
      );
@@@ -50,167 -52,186 +50,165 @@@ sub _new 
  sub immutable_metaclass {
      my $self = shift;
  
 -    $self->create_immutable_metaclass unless $self->{'immutable_metaclass'};
 -
 -    return $self->{'immutable_metaclass'};
 +    return $self->{'immutable_metaclass'} ||= $self->_create_immutable_metaclass;
  }
  
  sub metaclass           { (shift)->{'metaclass'}           }
  sub options             { (shift)->{'options'}             }
  sub inlined_constructor { (shift)->{'inlined_constructor'} }
  
 -sub create_immutable_metaclass {
 +sub _create_immutable_metaclass {
      my $self = shift;
  
 -    # NOTE:
 -    # The immutable version of the
 -    # metaclass is just a anon-class
 -    # which shadows the methods
 -    # appropriately
 -    $self->{'immutable_metaclass'} = Class::MOP::Class->create_anon_class(
 +    # NOTE: The immutable version of the metaclass is just a
 +    # anon-class which shadows the methods appropriately
 +    return Class::MOP::Class->create_anon_class(
          superclasses => [ blessed($self->metaclass) ],
 -        methods      => $self->create_methods_for_immutable_metaclass,
 +        methods      => $self->_create_methods_for_immutable_metaclass,
      );
  }
  
 -
 -my %DEFAULT_METHODS = (
 -    # I don't really understand this, but removing it breaks tests (groditi)
 -    meta => sub {
 -        my $self = shift;
 -        # if it is not blessed, then someone is asking
 -        # for the meta of Class::MOP::Immutable
 -        return Class::MOP::Class->initialize($self) unless blessed($self);
 -        # otherwise, they are asking for the metaclass
 -        # which has been made immutable, which is itself
 -        # except in the cases where it is a metaclass itself
 -        # that has been made immutable and for that we need 
 -        # to dig a bit ...
 -        if ($self->isa('Class::MOP::Class')) {
 -            return $self->{'___original_class'}->meta;
 -        }
 -        else {
 -            return $self;
 -        }
 -    },
 -    is_mutable     => sub { 0  },
 -    is_immutable   => sub { 1  },
 -    make_immutable => sub { () },
 -);
 -
 -# NOTE:
 -# this will actually convert the
 -# existing metaclass to an immutable
 -# version of itself
  sub make_metaclass_immutable {
 -    my ($self, $metaclass, $options) = @_;
 -
 -    my %options = (
 -        inline_accessors   => 1,
 -        inline_constructor => 1,
 -        inline_destructor  => 0,
 -        constructor_name   => 'new',
 -        debug              => 0,
 -        %$options,
 -    );
 +    my $self = shift;
  
 -    %$options = %options; # FIXME who the hell is relying on this?!? tests fail =(
 +    $self->_inline_accessors;
 +    $self->_inline_constructor;
 +    $self->_inline_destructor;
 +    $self->_check_memoized_methods;
  
 -    $self->_inline_accessors( $metaclass, \%options );
 -    $self->_inline_constructor( $metaclass, \%options );
 -    $self->_inline_destructor( $metaclass, \%options );
 -    $self->_check_memoized_methods( $metaclass, \%options );
 +    my $metaclass = $self->metaclass;
  
      $metaclass->{'___original_class'} = blessed($metaclass);
      bless $metaclass => $self->immutable_metaclass->name;
  }
  
  sub _inline_accessors {
 -    my ( $self, $metaclass, $options ) = @_;
 +    my $self = shift;
  
 -    return unless $options->{inline_accessors};
 +    return unless $self->options->{inline_accessors};
  
 -    foreach my $attr_name ( $metaclass->get_attribute_list ) {
 -        $metaclass->get_attribute($attr_name)->install_accessors(1);
 +    foreach my $attr_name ( $self->metaclass->get_attribute_list ) {
 +        $self->metaclass->get_attribute($attr_name)->install_accessors(1);
      }
  }
  
  sub _inline_constructor {
 -    my ( $self, $metaclass, $options ) = @_;
 +    my $self = shift;
  
 -    return unless $options->{inline_constructor};
 +    return unless $self->options->{inline_constructor};
  
      return
 -        unless $options->{replace_constructor}
 -            or !$metaclass->has_method( $options->{constructor_name} );
 +        unless $self->options->{replace_constructor}
 +            or !$self->metaclass->has_method(
 +                $self->options->{constructor_name}
 +            );
  
 -    my $constructor_class = $options->{constructor_class}
 -        || 'Class::MOP::Method::Constructor';
 +    my $constructor_class = $self->options->{constructor_class};
  
      my $constructor = $constructor_class->new(
 -        options      => $options,
 -        metaclass    => $metaclass,
 +        options      => $self->options,
 +        metaclass    => $self->metaclass,
          is_inline    => 1,
 -        package_name => $metaclass->name,
 -        name         => $options->{constructor_name},
 +        package_name => $self->metaclass->name,
 +        name         => $self->options->{constructor_name},
      );
  
 -    if ( $options->{replace_constructor} or $constructor->can_be_inlined ) {
 -        $metaclass->add_method( $options->{constructor_name} => $constructor );
 +    if (   $self->options->{replace_constructor}
 +        or $constructor->can_be_inlined ) {
 +        $self->metaclass->add_method(
 +            $self->options->{constructor_name} => $constructor );
          $self->{inlined_constructor} = $constructor;
      }
  }
  
  sub _inline_destructor {
 -    my ( $self, $metaclass, $options ) = @_;
 +    my $self = shift;
  
 -    return unless $options->{inline_destructor};
 +    return unless $self->options->{inline_destructor};
  
 -    ( exists $options->{destructor_class} )
 +    ( exists $self->options->{destructor_class} )
          || confess "The 'inline_destructor' option is present, but "
          . "no destructor class was specified";
  
 -    my $destructor_class = $options->{destructor_class};
 +    my $destructor_class = $self->options->{destructor_class};
  
 -    return unless $destructor_class->is_needed($metaclass);
 +    return unless $destructor_class->is_needed( $self->metaclass );
  
      my $destructor = $destructor_class->new(
 -        options      => $options,
 -        metaclass    => $metaclass,
 -        package_name => $metaclass->name,
 +        options      => $self->options,
 +        metaclass    => $self->metaclass,
 +        package_name => $self->metaclass->name,
          name         => 'DESTROY'
      );
  
-     return unless $destructor->is_needed;
 -    $metaclass->add_method( 'DESTROY' => $destructor )
 +    $self->metaclass->add_method( 'DESTROY' => $destructor );
  }
  
  sub _check_memoized_methods {
 -    my ( $self, $metaclass, $options ) = @_;
 +    my $self = shift;
  
      my $memoized_methods = $self->options->{memoize};
      foreach my $method_name ( keys %{$memoized_methods} ) {
          my $type = $memoized_methods->{$method_name};
  
 -        ( $metaclass->can($method_name) )
 +        ( $self->metaclass->can($method_name) )
              || confess "Could not find the method '$method_name' in "
 -            . $metaclass->name;
 +            . $self->metaclass->name;
      }
  }
 +my %DEFAULT_METHODS = (
 +    # I don't really understand this, but removing it breaks tests (groditi)
 +    meta => sub {
 +        my $self = shift;
 +        # if it is not blessed, then someone is asking
 +        # for the meta of Class::MOP::Immutable
 +        return Class::MOP::Class->initialize($self) unless blessed($self);
 +        # otherwise, they are asking for the metaclass
 +        # which has been made immutable, which is itself
 +        # except in the cases where it is a metaclass itself
 +        # that has been made immutable and for that we need 
 +        # to dig a bit ...
 +        if ($self->isa('Class::MOP::Class')) {
 +            return $self->{'___original_class'}->meta;
 +        }
 +        else {
 +            return $self;
 +        }
 +    },
 +    is_mutable     => sub { 0  },
 +    is_immutable   => sub { 1  },
 +    make_immutable => sub { () },
 +);
  
 -sub create_methods_for_immutable_metaclass {
 +sub _create_methods_for_immutable_metaclass {
      my $self = shift;
  
      my $metaclass = $self->metaclass;
      my $meta      = $metaclass->meta;
  
 -    $methods{get_mutable_metaclass_name}
 -        = sub { (shift)->{'___original_class'} };
 -
 -    $methods{immutable_transformer} = sub {$self};
 -
      return {
          %DEFAULT_METHODS,
 -        $self->_make_read_only_methods( $metaclass, $meta ),
 -        $self->_make_uncallable_methods( $metaclass, $meta ),
 -        $self->_make_memoized_methods( $metaclass, $meta ),
 -        $self->_make_wrapped_methods( $metaclass, $meta ),
 +        $self->_make_read_only_methods,
 +        $self->_make_uncallable_methods,
 +        $self->_make_memoized_methods,
 +        $self->_make_wrapped_methods,
          get_mutable_metaclass_name => sub { (shift)->{'___original_class'} },
          immutable_transformer      => sub {$self},
      };
  }
  
  sub _make_read_only_methods {
 -    my ( $self, $metaclass, $meta ) = @_;
 +    my $self = shift;
 +
 +    my $metameta = $self->metaclass->meta;
  
      my %methods;
      foreach my $read_only_method ( @{ $self->options->{read_only} } ) {
 -        my $method = $meta->find_method_by_name($read_only_method);
 +        my $method = $metameta->find_method_by_name($read_only_method);
  
          ( defined $method )
              || confess "Could not find the method '$read_only_method' in "
 -            . $metaclass->name;
 +            . $self->metaclass->name;
  
          $methods{$read_only_method} = sub {
              confess "This method is read-only" if scalar @_ > 1;
  }
  
  sub _make_uncallable_methods {
 -    my ( $self, $metaclass, $meta ) = @_;
 +    my $self = shift;
  
      my %methods;
      foreach my $cannot_call_method ( @{ $self->options->{cannot_call} } ) {
  }
  
  sub _make_memoized_methods {
 -    my ( $self, $metaclass, $meta ) = @_;
 +    my $self = shift;
  
      my %methods;
  
 +    my $metameta = $self->metaclass->meta;
 +
      my $memoized_methods = $self->options->{memoize};
      foreach my $method_name ( keys %{$memoized_methods} ) {
          my $type   = $memoized_methods->{$method_name};
          my $key    = '___' . $method_name;
 -        my $method = $meta->find_method_by_name($method_name);
 +        my $method = $metameta->find_method_by_name($method_name);
  
          if ( $type eq 'ARRAY' ) {
              $methods{$method_name} = sub {
  }
  
  sub _make_wrapped_methods {
 -    my ( $self, $metaclass, $meta ) = @_;
 +    my $self = shift;
  
      my %methods;
  
      my $wrapped_methods = $self->options->{wrapped};
  
 +    my $metameta = $self->metaclass->meta;
 +
      foreach my $method_name ( keys %{$wrapped_methods} ) {
 -        my $method = $meta->find_method_by_name($method_name);
 +        my $method = $metameta->find_method_by_name($method_name);
  
          ( defined $method )
              || confess "Could not find the method '$method_name' in "
 -            . $metaclass->name;
 +            . $self->metaclass->name;
  
          my $wrapper = $wrapped_methods->{$method_name};
  
  }
  
  sub make_metaclass_mutable {
 -    my ($self, $immutable, $options) = @_;
 +    my $self = shift;
  
 -    my %options = %$options;
 +    my $metaclass = $self->metaclass;
  
 -    my $original_class = $immutable->get_mutable_metaclass_name;
 -    delete $immutable->{'___original_class'} ;
 -    bless $immutable => $original_class;
 +    my $original_class = $metaclass->get_mutable_metaclass_name;
 +    delete $metaclass->{'___original_class'};
 +    bless $metaclass => $original_class;
  
      my $memoized_methods = $self->options->{memoize};
 -    foreach my $method_name (keys %{$memoized_methods}) {
 +    foreach my $method_name ( keys %{$memoized_methods} ) {
          my $type = $memoized_methods->{$method_name};
  
 -        ($immutable->can($method_name))
 -          || confess "Could not find the method '$method_name' in " . $immutable->name;
 -        if ($type eq 'SCALAR' || $type eq 'ARRAY' ||  $type eq 'HASH' ) {
 -            delete $immutable->{'___' . $method_name};
 +        ( $metaclass->can($method_name) )
 +            || confess "Could not find the method '$method_name' in "
 +            . $metaclass->name;
 +        if ( $type eq 'SCALAR' || $type eq 'ARRAY' || $type eq 'HASH' ) {
 +            delete $metaclass->{ '___' . $method_name };
          }
      }
  
 -    if ($options{inline_destructor} && $immutable->has_method('DESTROY')) {
 -        $immutable->remove_method('DESTROY')
 -          if blessed($immutable->get_method('DESTROY')) eq $options{destructor_class};
 +    if (   $self->options->{inline_destructor}
 +        && $metaclass->has_method('DESTROY') ) {
 +        $metaclass->remove_method('DESTROY')
 +            if blessed( $metaclass->get_method('DESTROY') ) eq
 +                $self->options->{destructor_class};
      }
  
      # NOTE:
      # 14:26 <@stevan> the only user of ::Method::Constructor is immutable
      # 14:27 <@stevan> if someone uses it outside of immutable,.. they are either: mst or groditi
      # 14:27 <@stevan> so I am not worried
 -    if ($options{inline_constructor}  && $immutable->has_method($options{constructor_name})) {
 -        my $constructor_class = $options{constructor_class} || 'Class::MOP::Method::Constructor';
 -
 -        if ( blessed($immutable->get_method($options{constructor_name})) eq $constructor_class ) {
 -            $immutable->remove_method( $options{constructor_name}  );
 +    if (   $self->options->{inline_constructor}
 +        && $metaclass->has_method( $self->options->{constructor_name} ) ) {
 +        my $constructor_class = $self->options->{constructor_class}
 +            || 'Class::MOP::Method::Constructor';
 +
 +        if (
 +            blessed(
 +                $metaclass->get_method( $self->options->{constructor_name} )
 +            ) eq $constructor_class
 +            ) {
 +            $metaclass->remove_method( $self->options->{constructor_name} );
              $self->{inlined_constructor} = undef;
          }
      }
@@@ -392,7 -400,7 +390,7 @@@ Class::MOP::Immutable - A class to tran
          }
      });
  
 -    $immutable_metaclass->make_metaclass_immutable(@_)
 +    $immutable_metaclass->make_metaclass_immutable;
  
  =head1 DESCRIPTION
  
@@@ -502,14 -510,6 +500,14 @@@ transformation process
  If the constructor was inlined, this returns the constructor method
  object that was created to do this.
  
 +=item B<< $transformer->make_metaclass_immutable >>
 +
 +Makes the transformer's metaclass immutable.
 +
 +=item B<< $transformer->make_metaclass_mutable >>
 +
 +Makes the transformer's metaclass mutable.
 +
  =back
  
  =head1 AUTHORS
diff --combined xt/pod_coverage.t
@@@ -46,12 -46,19 +46,18 @@@ my %trustme = 
  
      ],
  
 -    'Class::MOP::Immutable' => [
 -        qw( create_immutable_metaclass
 -            create_methods_for_immutable_metaclass
 -            make_metaclass_immutable
 -            make_metaclass_mutable )
 +    'Class::MOP::Instance' => [
 +        qw( BUILDARGS
 +            bless_instance_structure
 +            is_dependent_on_superclasses ),
      ],
  
+     'Class::MOP::Instance' => [
+         qw( BUILDARGS
+             bless_instance_structure
+             is_dependent_on_superclasses ),
+     ],
      'Class::MOP::Method::Accessor' => [
          qw( generate_accessor_method
              generate_accessor_method_inline
@@@ -73,6 -80,7 +79,7 @@@
              generate_constructor_method_inline
              initialize_body
              meta_instance
+             options
              )
      ],
  
@@@ -91,7 -99,7 +98,7 @@@ for my $module ( sort @modules ) 
      my $trustme = [];
      if ( $trustme{$module} ) {
          my $methods = join '|', @{ $trustme{$module} };
-         $trustme = [qr/$methods/];
+         $trustme = [qr/^(?:$methods)$/];
      }
  
      pod_coverage_ok(