The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
=head1 PURPOSE

Demonstrate subtleties of L<MooX::CaptainHook>'s C<on_application>.

=head1 EXPECTED OUTPUT

 Local::Person
 Local::Document

=head1 AUTHOR

Toby Inkster E<lt>tobyink@cpan.orgE<gt>.

=head1 COPYRIGHT AND LICENCE

This software is copyright (c) 2013 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.

=cut

use 5.010;
use strict;
use warnings;

# This role provides one method (TO_JSON).
# The role keeps a list of what classes compose it.
{
	package Local::Storable;
	use Moo::Role;
	use MooX::CaptainHook -all;
	sub TO_JSON { +{ %{ $_[0] } } }
	on_application {
		push our(@IMPLEMENTATIONS), $_ unless is_role $_;
	};
}

# "Local::Person" gets pushed onto @IMPLEMENTATIONS
# because it composes Local::Storable.
{
	package Local::Person;
	use Moo;
	with 'Local::Storable';
	has name => (is => 'rwp');
}

# "Local::Employee" is NOT pushed onto @IMPLEMENTATIONS
# because it doesn't compose Local::Storable. It just happens
# to inherit from a class that does.
{
	package Local::Employee;
	use Moo;
	extends 'Local::Person';
	has title => (is => 'rwp');
}

# This won't get listed in @IMPLEMENTATIONS because the
# on_application callback checks is_role($_).
{
	package Local::Storable::ToFile;
	use Moo::Role;
	with 'Local::Storable';
	use JSON;
	sub to_file {
		my ($self, $name) = @_;
		open my $fh, '>', $name;
		print {$fh} JSON::to_json($self, { convert_blessed => 1 });
	}
}

# This will get listed in @IMPLEMENTATIONS because it
# consumes Local::Storable (albeit indirectly).
{
	package Local::Document;
	use Moo;
	with 'Local::Storable::ToFile';
	has title => (is => 'rwp');
}

say for @Local::Storable::IMPLEMENTATIONS;