Skip to content

Instantly share code, notes, and snippets.

/more_roles.diff Secret

Created August 17, 2017 19:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/10210f643001514b551f6c23fb59e682 to your computer and use it in GitHub Desktop.
Save anonymous/10210f643001514b551f6c23fb59e682 to your computer and use it in GitHub Desktop.
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