-
-
Save anonymous/10210f643001514b551f6c23fb59e682 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/Mojo/Base.pm b/lib/Mojo/Base.pm | |
index 54acb81d4..490351fd2 100644 | |
--- a/lib/Mojo/Base.pm | |
+++ b/lib/Mojo/Base.pm | |
@@ -6,7 +6,8 @@ use utf8; | |
use feature (); | |
# No imports because we get subclassed, a lot! | |
-use Carp (); | |
+use Carp (); | |
+use Scalar::Util (); | |
# Only Perl 5.14+ requires it on demand | |
use IO::Handle (); | |
@@ -107,9 +108,14 @@ sub tap { | |
sub with_roles { | |
Carp::croak 'Role::Tiny 2.000001+ is required for roles' unless ROLES; | |
- my $class = shift; | |
- return Role::Tiny->create_class_with_roles($class, | |
- map { /^\+(.+)$/ ? "${class}::Role::$1" : $_ } @_); | |
+ my ($self, @roles) = @_; | |
+ | |
+ return Role::Tiny->create_class_with_roles($self, | |
+ map { /^\+(.+)$/ ? "${self}::Role::$1" : $_ } @roles) | |
+ unless my $class = Scalar::Util::blessed $self; | |
+ | |
+ return Role::Tiny->apply_roles_to_object($self, | |
+ map { /^\+(.+)$/ ? "${class}::Role::$1" : $_ } @roles); | |
} | |
1; | |
@@ -249,8 +255,9 @@ spliced or tapped into) a chained set of object method calls. | |
=head2 with_roles | |
- my $new_class = SubClass->with_roles('SubClass::Role::One'); | |
- my $new_class = SubClass->with_roles('+One', '+Two'); | |
+ my $new_class = SubClass->with_roles('SubClass::Role::One'); | |
+ my $new_class = SubClass->with_roles('+One', '+Two'); | |
+ my $new_object = $object->with_roles('+One', '+Two'); | |
Create and return a new class that extends the given class with one or more | |
L<Role::Tiny> roles. For roles following the naming scheme | |
diff --git a/lib/Mojo/ByteStream.pm b/lib/Mojo/ByteStream.pm | |
index 7c5ca8411..647c02aea 100644 | |
--- a/lib/Mojo/ByteStream.pm | |
+++ b/lib/Mojo/ByteStream.pm | |
@@ -332,8 +332,9 @@ L<Mojo::Util/"url_unescape">. | |
=head2 with_roles | |
- my $new_class = Mojo::ByteStream->with_roles('Mojo::ByteStream::Role::One'); | |
- my $new_class = Mojo::ByteStream->with_roles('+One', '+Two'); | |
+ my $new_class = Mojo::ByteStream->with_roles('Mojo::ByteStream::Role::One'); | |
+ my $new_class = Mojo::ByteStream->with_roles('+One', '+Two'); | |
+ my $new_stream = $stream->with_roles('+One', '+Two'); | |
Alias for L<Mojo::Base/"with_roles">. | |
diff --git a/lib/Mojo/Collection.pm b/lib/Mojo/Collection.pm | |
index 39d512300..2c7e2c123 100644 | |
--- a/lib/Mojo/Collection.pm | |
+++ b/lib/Mojo/Collection.pm | |
@@ -373,6 +373,7 @@ callback/method. | |
my $new_class = Mojo::Collection->with_roles('Mojo::Collection::Role::One'); | |
my $new_class = Mojo::Collection->with_roles('+One', '+Two'); | |
+ my $new_collection = $collection->with_roles('+One', '+Two'); | |
Alias for L<Mojo::Base/"with_roles">. | |
diff --git a/lib/Mojo/DOM.pm b/lib/Mojo/DOM.pm | |
index 909aa78e2..0d8fbb95e 100644 | |
--- a/lib/Mojo/DOM.pm | |
+++ b/lib/Mojo/DOM.pm | |
@@ -952,6 +952,7 @@ if none could be found. | |
my $new_class = Mojo::DOM->with_roles('Mojo::DOM::Role::One'); | |
my $new_class = Mojo::DOM->with_roles('+One', '+Two'); | |
+ my $new_dom = $dom->with_roles('+One', '+Two'); | |
Alias for L<Mojo::Base/"with_roles">. | |
diff --git a/lib/Mojo/File.pm b/lib/Mojo/File.pm | |
index 6510ba6c0..39d8e5d3a 100644 | |
--- a/lib/Mojo/File.pm | |
+++ b/lib/Mojo/File.pm | |
@@ -452,6 +452,7 @@ Stringify the path. | |
my $new_class = Mojo::File->with_roles('Mojo::File::Role::One'); | |
my $new_class = Mojo::File->with_roles('+One', '+Two'); | |
+ my $new_path = $path->with_roles('+One', '+Two'); | |
Alias for L<Mojo::Base/"with_roles">. | |
diff --git a/t/mojo/roles.t b/t/mojo/roles.t | |
index 7722a232d..5a9258223 100644 | |
--- a/t/mojo/roles.t | |
+++ b/t/mojo/roles.t | |
@@ -86,6 +86,13 @@ is $obj6->name, 'Joel', 'base attribute'; | |
is $obj6->whisper, 'psst, joel', 'method from first role'; | |
is $obj6->hello, 'HEY! JOEL!!!', 'method from second role'; | |
+# Multiple object roles (mixed) | |
+my $obj7 = Mojo::RoleTest->new(name => 'Joel') | |
+ ->with_roles('Mojo::RoleTest::Role::quiet', '+LOUD'); | |
+is $obj7->name, 'Joel', 'base attribute'; | |
+is $obj7->whisper, 'psst, joel', 'method from first role'; | |
+is $obj7->hello, 'HEY! JOEL!!!', 'method from second role'; | |
+ | |
# Classes that are not subclasses of Mojo::Base | |
my $stream = Mojo::ByteStream->with_roles('Mojo::RoleTest::Hello')->new; | |
is $stream->hello, 'hello mojo!', 'right result'; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment