Moo

 view release on metacpan or  search on metacpan

lib/Moo/Role.pm  view on Meta::CPAN

  if ($INFO{$role} && $INFO{$role}{inhaled_from_moose}
      or $INC{"Moo.pm"}
      and $m = Moo->_accessor_maker_for($target)
      and ref($m) ne 'Method::Generate::Accessor') {
    $self->_make_accessors($target, $role);
  }
}

sub _make_accessors_if_moose {
  my ($self, $target, $role) = @_;
  if ($INFO{$role} && $INFO{$role}{inhaled_from_moose}) {
    $self->_make_accessors($target, $role);
  }
}

sub _make_accessors {
  my ($self, $target, $role) = @_;
  my $acc_gen = ($Moo::MAKERS{$target}{accessor} ||= do {
    require Method::Generate::Accessor;
    Method::Generate::Accessor->new
  });
  my $con_gen = $Moo::MAKERS{$target}{constructor};
  my @attrs = @{$INFO{$role}{attributes}||[]};
  while (my ($name, $spec) = splice @attrs, 0, 2) {
    # needed to ensure we got an index for an arrayref based generator
    if ($con_gen) {
      $spec = $con_gen->all_attribute_specs->{$name};
    }
    $acc_gen->generate_method($target, $name, $spec);
  }
}

sub _undefer_subs {
  my ($self, $target, $role) = @_;
  if ($INC{'Sub/Defer.pm'}) {
    Sub::Defer::undefer_package($role);
  }
}

sub role_application_steps {
  qw(_handle_constructor _undefer_subs _maybe_make_accessors),
    $_[0]->SUPER::role_application_steps;
}

sub _build_class_with_roles {
  my ($me, $new_name, $superclass, @roles) = @_;
  $Moo::MAKERS{$new_name} = {is_class => 1};
  $me->SUPER::_build_class_with_roles($new_name, $superclass, @roles);

  if ($INC{'Moo/HandleMoose.pm'} && !$Moo::sification::disabled) {
    Moo::HandleMoose::inject_fake_metaclass_for($new_name);
  }

  my $lvl = 0;
  my $file;
  while ((my $pack, $file) = caller($lvl++)) {
    if ($pack ne __PACKAGE__ && $pack ne 'Role::Tiny' && !$pack->isa($me)) {
      last;
    }
  }
  _set_loaded($new_name, $file || (caller)[1]);

  return $new_name;
}

sub _gen_apply_defaults_for {
  my ($me, $class, @roles) = @_;

  my @attrs = map @{$INFO{$_}{attributes}||[]}, @roles;

  my $con_gen;
  my $m;

  return undef
    unless $INC{'Moo.pm'}
    and @attrs
    and $con_gen = Moo->_constructor_maker_for($class)
    and $m = Moo->_accessor_maker_for($class);

  my $specs = $con_gen->all_attribute_specs;

  my %seen;
  my %captures;
  my @set;
  while (my ($name, $spec) = splice @attrs, 0, 2) {
    next
      if $seen{$name}++;

    next
      unless $m->has_eager_default($name, $spec);

    my ($has, $has_cap)
      = $m->generate_simple_has('$_[0]', $name, $spec);
    my ($set, $pop_cap)
      = $m->generate_use_default('$_[0]', $name, $spec, $has);

    @captures{keys %$has_cap, keys %$pop_cap}
      = (values %$has_cap, values %$pop_cap);

    push @set, $set;
  }

  return undef
    if !@set;

  my $code = join '', map "($_),", @set;
  no warnings 'void';
  require Sub::Quote;
  return Sub::Quote::quote_sub(
    "${class}::_apply_defaults",
    $code,
    \%captures,
    {
      package => $class,
      no_install => 1,
      no_defer => 1,
    }
  );
}

sub apply_roles_to_object {
  my ($me, $object, @roles) = @_;
  my $new = $me->SUPER::apply_roles_to_object($object, @roles);
  my $class = ref $new;
  _set_loaded($class, (caller)[1]);

  if (!exists $APPLY_DEFAULTS{$class}) {
    $APPLY_DEFAULTS{$class} = $me->_gen_apply_defaults_for($class, @roles);
  }
  if (my $apply_defaults = $APPLY_DEFAULTS{$class}) {
    local $Carp::Internal{+__PACKAGE__} = 1;
    local $Carp::Internal{$class} = 1;
    $new->$apply_defaults;
  }
  return $new;
}

sub _install_single_modifier {
  my ($me, @args) = @_;
  _install_modifier(@args);
}

sub _install_does {
    my ($me, $to) = @_;

    # If Role::Tiny actually installed the DOES, give it a name
    my $new = $me->SUPER::_install_does($to) or return;
    return _name_coderef("${to}::DOES", $new);
}

sub does_role {
  my ($proto, $role) = @_;
  return 1
    if Role::Tiny::does_role($proto, $role);
  my $meta;
  if ($INC{'Moose.pm'}
      and $meta = Class::MOP::class_of($proto)
      and ref $meta ne 'Moo::HandleMoose::FakeMetaClass'
      and $meta->can('does_role')
  ) {
    return $meta->does_role($role);
  }
  return 0;
}

sub _handle_constructor {
  my ($me, $to, $role) = @_;
  my $attr_info = $INFO{$role} && $INFO{$role}{attributes};
  return unless $attr_info && @$attr_info;
  my $info = $INFO{$to};
  my $con = $INC{"Moo.pm"} && Moo->_constructor_maker_for($to);
  my %existing
    = $info ? @{$info->{attributes} || []}
    : $con  ? %{$con->all_attribute_specs || {}}
    : ();

  my @attr_info =
    map { @{$attr_info}[$_, $_+1] }
    grep { ! $existing{$attr_info->[$_]} }
    map { 2 * $_ } 0..@$attr_info/2-1;

  if ($info) {
    push @{$info->{attributes}||=[]}, @attr_info;
  }
  elsif ($con) {



( run in 0.721 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )