Commits

Toby Inkster committed 151694f Draft

initial version

Comments (0)

Files changed (15)

+use inc::Module::Package 'RDF:tobyink 0.009';
+

lib/MooseX/Does/Delegated.pm

+package MooseX::Does::Delegated;
+
+use 5.008;
+use strict;
+use warnings;
+use if $] < 5.010, 'UNIVERSAL::DOES';
+
+BEGIN {
+	$MooseX::Does::Delegated::AUTHORITY = 'cpan:TOBYINK';
+	$MooseX::Does::Delegated::VERSION   = '0.001';
+}
+
+use Moose::Role;
+
+around DOES => sub {
+	my ($orig, $self, $role) = @_;
+	return 1 if $self->$orig($role);
+	return unless blessed($self);
+	for my $attr ($self->meta->get_all_attributes) {
+		next unless $attr->has_handles;
+		my $handles = $attr->handles;
+		next if ref $handles;
+		next unless $attr->has_value($self) || $attr->is_lazy;
+		return 1 if $role eq $handles;
+		return 1 if Class::MOP::class_of($handles)->does_role($role);
+	}
+	return;
+};
+
+# Allow import method to work, yet hide it from role method list.
+our @ISA = do {
+	package # Hide from CPAN indexer too.
+	MooseX::Does::Delegated::__ANON__::0001;
+	use Moose::Util qw(ensure_all_roles);
+	sub import {
+		no warnings qw(uninitialized);
+		my $class = shift;
+		ensure_all_roles('Moose::Object', $class)
+			if $_[0] =~ /^[-](?:everywhere|rafl)/;
+	}
+	__PACKAGE__;
+};
+
+no Moose::Role;
+
+__PACKAGE__
+__END__
+
+=head1 NAME
+
+MooseX::Does::Delegated - allow your class's DOES method to respond the affirmative to delegated roles
+
+=head1 SYNOPSIS
+
+   use strict;
+   use Test::More;
+   
+   {
+      package HttpGet;
+      use Moose::Role;
+      requires 'get';
+   };
+   
+   {
+      package UserAgent;
+      use Moose;
+      with qw( HttpGet );
+      sub get { ... };
+   };
+   
+   {
+      package Spider;
+      use Moose;
+      has ua => (
+         is         => 'ro',
+         does       => 'HttpGet',
+         handles    => 'HttpGet',
+         lazy_build => 1,
+      );
+      sub _build_ua { UserAgent->new };
+   };
+   
+   my $woolly = Spider->new;
+   
+   # Note that the default Moose implementation of DOES
+   # ignores the fact that Spider has delegated the HttpGet
+   # role to its "ua" attribute.
+   #
+   ok(     $woolly->DOES('Spider') );
+   ok( not $woolly->DOES('HttpGet') );
+   
+   Moose::Util::apply_all_roles(
+      'Spider',
+      'MooseX::Does::Delegated',
+   );
+   
+   # Our reimplemented DOES pays attention to delegated roles.
+   #
+   ok( $woolly->DOES('Spider') );
+   ok( $woolly->DOES('HttpGet') );
+   
+   done_testing;
+
+=head1 DESCRIPTION
+
+According to L<UNIVERSAL> the point of C<DOES> is that it allows you
+to check whether an object does a role without caring about I<how>
+it does the role.
+
+However, the default Moose implementation of C<DOES> (which you can
+of course override!) only checks whether the object does the role via
+inheritance or the application of a role to a class.
+
+This module overrides your object's C<DOES> method, allowing it to
+respond the affirmative to delegated roles. This module is a standard
+Moose role, so it can be used like this:
+
+   with qw( MooseX::Does::Delegated );
+
+Alternatively, if you wish to apply this role ubiqitously (i.e. to all
+Moose objects in your application) - as is your prerogative - you can use:
+
+   use MooseX::Does::Delegated -everywhere;
+
+This will apply the role to the Moose::Object base class.
+
+=head1 BUGS
+
+Please report any bugs to
+L<http://rt.cpan.org/Dist/Display.html?Queue=MooseX-Does-Delegated>.
+
+=head1 SEE ALSO
+
+L<Moose::Manual::Delegation>.
+
+=head1 AUTHOR
+
+Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
+
+=head1 COPYRIGHT AND LICENCE
+
+This software is copyright (c) 2012 by Toby Inkster.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=head1 DISCLAIMER OF WARRANTIES
+
+THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+

meta/changes.pret

+# This file acts as the project's changelog.
+
+`MooseX-Does-Delegated 0.001 cpan:TOBYINK`
+	issued  2012-11-20;
+	label   "Initial release".
+
+# This file contains general metadata about the project.
+
+@prefix : <http://usefulinc.com/ns/doap#>.
+
+`MooseX-Does-Delegated`
+	:programming-language "Perl" ;
+	:shortdesc            "allow your class's DOES method to respond the affirmative to delegated roles";
+	:homepage             <https://metacpan.org/release/MooseX-Does-Delegated>;
+	:download-page        <https://metacpan.org/release/MooseX-Does-Delegated>;
+	:bug-database         <http://rt.cpan.org/Dist/Display.html?Queue=MooseX-Does-Delegated>;
+	:repository           [ a :HgRepository; :browse <https://bitbucket.org/tobyink/p5-moosex-does-delegated> ];
+	:created              2012-11-09;
+	:license              <http://dev.perl.org/licenses/>;
+	:maintainer           cpan:TOBYINK;
+	:developer            cpan:TOBYINK.
+
+<http://dev.perl.org/licenses/>
+	dc:title  "the same terms as the perl 5 programming language system itself".
+

meta/makefile.pret

+# This file provides instructions for packaging.
+
+`MooseX-Does-Delegated`
+	perl_version_from m`MooseX::Does::Delegated`;
+	version_from      m`MooseX::Does::Delegated`;
+	readme_from       m`MooseX::Does::Delegated`;
+	test_requires     p`Test::More 0.61` ;
+	.
+
+# This file contains data about the project developers.
+
+@prefix : <http://xmlns.com/foaf/0.1/>.
+
+cpan:TOBYINK
+	:name  "Toby Inkster";
+	:mbox  <mailto:tobyink@cpan.org>.
+
+use Test::More tests => 1;
+BEGIN { use_ok('MooseX::Does::Delegated') };
+
+use strict;
+use Test::More;
+
+{
+	package HttpGet;
+	use Moose::Role;
+	requires 'get';
+};
+
+{
+	package UserAgent;
+	use Moose;
+	with qw( HttpGet );
+	sub get { ... };
+};
+
+{
+	package Spider;
+	use Moose;
+	has ua => (
+		is         => 'ro',
+		does       => 'HttpGet',
+		handles    => 'HttpGet',
+		lazy_build => 1,
+	);
+	sub _build_ua { UserAgent->new };
+};
+
+my $woolly = Spider->new;
+
+# Note that the default Moose implementation of DOES
+# ignores the fact that Spider has delegated the HttpGet
+# role to its "ua" attribute.
+#
+ok(     $woolly->DOES('Spider') );
+ok( not $woolly->DOES('HttpGet') );
+
+Moose::Util::apply_all_roles(
+	'Spider',
+	'MooseX::Does::Delegated',
+);
+
+# Our reimplemented DOES pays attention to delegated roles.
+#
+ok( $woolly->DOES('Spider') );
+ok( $woolly->DOES('HttpGet') );
+
+done_testing;
+use Test::More;
+eval "use Test::Pod 1.00";
+plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
+all_pod_files_ok();
+

xt/02pod_coverage.t

+use XT::Util;
+use Test::More;
+use Test::Pod::Coverage;
+
+plan skip_all => __CONFIG__->{skip_all}
+	if __CONFIG__->{skip_all};
+
+if ( __CONFIG__->{modules} )
+{
+	my @modules = @{ __CONFIG__->{modules} };
+	pod_coverage_ok($_, "$_ is covered") for @modules;
+	done_testing(scalar @modules);
+}
+else
+{
+	all_pod_coverage_ok();
+}
+

xt/03meta_uptodate.config

+{"package":"MooseX-Does-Delegated"}
+

xt/03meta_uptodate.t

+use XT::Util;
+use Test::More tests => 1;
+use Test::RDF::DOAP::Version;
+doap_version_ok(__CONFIG__->{package}, __CONFIG__->{version_from});
+
+use Test::EOL;
+all_perl_files_ok();
+use Test::Tabs;
+all_perl_files_ok();
+use XT::Util;
+use Test::More;
+use Test::HasVersion;
+
+plan skip_all => __CONFIG__->{skip_all}
+	if __CONFIG__->{skip_all};
+
+if ( __CONFIG__->{modules} )
+{
+	my @modules = @{ __CONFIG__->{modules} };
+	pm_version_ok($_, "$_ is covered") for @modules;
+	done_testing(scalar @modules);
+}
+else
+{
+	all_pm_version_ok();
+}
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.