package Mouse::Util;
use Mouse::Exporter; # enables strict and warnings
+# Note that those which don't exist here are defined in XS or Mouse::PurePerl
+
# must be here because it will be refered by other modules loaded
sub get_linear_isa($;$); ## no critic
not_supported
- does meta dump
+ does meta throw_error dump
)],
groups => {
default => [], # export no functions by default
# The ':meta' group is 'use metaclass' for Mouse
- meta => [qw(does meta dump)],
+ meta => [qw(does meta dump throw_error)],
},
);
- our $VERSION = '0.70';
+ our $VERSION = '0.95';
my $xs = !(defined(&is_valid_class_name) || $ENV{MOUSE_PUREPERL} || $ENV{PERL_ONLY});
Mouse::Util->import({ into => 'Mouse::Meta::Method::Accessor::XS' }, ':meta');
return 1;
} || 0;
- #warn $@ if $@;
+ warn $@ if $@ && $ENV{MOUSE_XS};
}
if(!$xs){
}
*MOUSE_XS = sub(){ $xs };
+
+ # definition of mro::get_linear_isa()
+ my $get_linear_isa;
+ if ($] >= 5.010_000) {
+ require mro;
+ $get_linear_isa = \&mro::get_linear_isa;
+ }
+ else {
+ # this code is based on MRO::Compat::__get_linear_isa
+ my $_get_linear_isa_dfs; # this recurses so it isn't pretty
+ $_get_linear_isa_dfs = sub {
+ my($classname) = @_;
+
+ my @lin = ($classname);
+ my %stored;
+
+ no strict 'refs';
+ foreach my $parent (@{"$classname\::ISA"}) {
+ foreach my $p(@{ $_get_linear_isa_dfs->($parent) }) {
+ next if exists $stored{$p};
+ push(@lin, $p);
+ $stored{$p} = 1;
+ }
+ }
+ return \@lin;
+ };
+
+ {
+ package # hide from PAUSE
+ Class::C3;
+ our %MRO; # avoid 'once' warnings
+ }
+
+ # MRO::Compat::__get_linear_isa has no prototype, so
+ # we define a prototyped version for compatibility with core's
+ # See also MRO::Compat::__get_linear_isa.
+ $get_linear_isa = sub ($;$){
+ my($classname, $type) = @_;
+
+ if(!defined $type){
+ $type = exists $Class::C3::MRO{$classname} ? 'c3' : 'dfs';
+ }
+ if($type eq 'c3'){
+ require Class::C3;
+ return [Class::C3::calculateMRO($classname)];
+ }
+ else{
+ return $_get_linear_isa_dfs->($classname);
+ }
+ };
+ }
+
+ *get_linear_isa = $get_linear_isa;
}
use Carp ();
return class_of( $_[0] );
}
-sub does_role{
+sub _does_role_impl {
my ($class_or_obj, $role_name) = @_;
my $meta = class_of($class_or_obj);
return defined($meta) && $meta->does_role($role_name);
}
-BEGIN {
- my $get_linear_isa;
- if ($] >= 5.009_005) {
- require mro;
- $get_linear_isa = \&mro::get_linear_isa;
- } else {
- # this code is based on MRO::Compat::__get_linear_isa
- my $_get_linear_isa_dfs; # this recurses so it isn't pretty
- $_get_linear_isa_dfs = sub {
- my($classname) = @_;
-
- my @lin = ($classname);
- my %stored;
-
- no strict 'refs';
- foreach my $parent (@{"$classname\::ISA"}) {
- foreach my $p(@{ $_get_linear_isa_dfs->($parent) }) {
- next if exists $stored{$p};
- push(@lin, $p);
- $stored{$p} = 1;
- }
- }
- return \@lin;
- };
-
- {
- package # hide from PAUSE
- Class::C3;
- our %MRO; # avoid 'once' warnings
- }
-
- # MRO::Compat::__get_linear_isa has no prototype, so
- # we define a prototyped version for compatibility with core's
- # See also MRO::Compat::__get_linear_isa.
- $get_linear_isa = sub ($;$){
- my($classname, $type) = @_;
+sub does_role {
+ my($thing, $role_name) = @_;
- if(!defined $type){
- $type = exists $Class::C3::MRO{$classname} ? 'c3' : 'dfs';
- }
- if($type eq 'c3'){
- require Class::C3;
- return [Class::C3::calculateMRO($classname)];
- }
- else{
- return $_get_linear_isa_dfs->($classname);
- }
- };
+ if( (Scalar::Util::blessed($thing) || is_class_loaded($thing))
+ && $thing->can('does')) {
+ return $thing->does($role_name);
}
-
- *get_linear_isa = $get_linear_isa;
+ goto &_does_role_impl;
}
-
# taken from Mouse::Util (0.90)
{
my %cache;
sub get_code_package;
sub is_valid_class_name;
+sub is_class_loaded;
# taken from Class/MOP.pm
sub load_first_existing_class {
return $class;
}
-sub is_class_loaded;
sub apply_all_roles {
my $consumer = Scalar::Util::blessed($_[0])
- ? shift # instance
- : Mouse::Meta::Class->initialize(shift); # class or role name
+ ? $_[0] # instance
+ : Mouse::Meta::Class->initialize($_[0]); # class or role name
my @roles;
# Basis of Data::OptList
my $max = scalar(@_);
- for (my $i = 0; $i < $max ; $i++) {
- if ($i + 1 < $max && ref($_[$i + 1])) {
- push @roles, [ $_[$i] => $_[++$i] ];
- } else {
- push @roles, [ $_[$i] => undef ];
+ for (my $i = 1; $i < $max ; $i++) {
+ my $role = $_[$i];
+ my $role_name;
+ if(ref $role) {
+ $role_name = $role->name;
+ }
+ else {
+ $role_name = $role;
+ load_class($role_name);
+ $role = get_metaclass_by_name($role_name);
}
- my $role_name = $roles[-1][0];
- load_class($role_name);
- is_a_metarole( get_metaclass_by_name($role_name) )
+ if ($i + 1 < $max && ref($_[$i + 1]) eq 'HASH') {
+ push @roles, [ $role => $_[++$i] ];
+ } else {
+ push @roles, [ $role => undef ];
+ }
+ is_a_metarole($role)
|| $consumer->meta->throw_error("You can only consume roles, $role_name is not a Mouse role");
}
if ( scalar @roles == 1 ) {
- my ( $role_name, $params ) = @{ $roles[0] };
- get_metaclass_by_name($role_name)->apply( $consumer, defined $params ? $params : () );
+ my ( $role, $params ) = @{ $roles[0] };
+ $role->apply( $consumer, defined $params ? $params : () );
}
else {
Mouse::Meta::Role->combine(@roles)->apply($consumer);
sub not_supported{
my($feature) = @_;
- $feature ||= ( caller(1) )[3]; # subroutine name
+ $feature ||= ( caller(1) )[3] . '()'; # subroutine name
local $Carp::CarpLevel = $Carp::CarpLevel + 1;
Carp::confess("Mouse does not currently support $feature");
return Mouse::Meta::Class->initialize(ref($_[0]) || $_[0]);
}
+# general throw_error() method
+# $o->throw_error($msg, depth => $leve, longmess => $croak_or_confess)
+sub throw_error :method {
+ my($self, $message, %args) = @_;
+
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1 + ($args{depth} || 0);
+ local $Carp::MaxArgNums = 20; # default is 8, usually we use named args which gets messier though
+
+ if(exists $args{longmess} && !$args{longmess}) {
+ Carp::croak($message);
+ }
+ else{
+ Carp::confess($message);
+ }
+}
+
# general dump() method
sub dump :method {
my($self, $maxdepth) = @_;
# general does() method
sub does :method {
- goto &does_role;
+ goto &_does_role_impl;
}
1;
=head1 VERSION
-This document describes Mouse version 0.70
+This document describes Mouse version 0.95
=head1 SYNOPSIS
=head3 C<< Mouse::Util::get_all_metaclass_names() -> (ClassNames) >>
-=head2 MRO::Compat
+=head2 mro (or MRO::Compat)
=head3 C<get_linear_isa>
L<Sub::Identify>
+L<mro>
+
L<MRO::Compat>
=cut