Toby Inkster avatar Toby Inkster committed 3704567 Draft

initial version

Comments (0)

Files changed (11)

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

lib/MooseX/Declare/Context/WithOptions/Patch/Extensible.pm

+package MooseX::Declare::Context::WithOptions::Patch::Extensible;
+
+use 5.010;
+use strict;
+use warnings;
+use utf8;
+
+BEGIN {
+	$MooseX::Declare::Context::WithOptions::Patch::Extensible::AUTHORITY = 'cpan:TOBYINK';
+	$MooseX::Declare::Context::WithOptions::Patch::Extensible::VERSION   = '0.001';
+}
+
+# I had hoped to do this with Module::Patch, but it seems that Module::Patch
+# doesn't work especially well with Moose roles. Patching a sub in the role
+# does not necessarily affect the classes that the role has been composed with.
+
+use Carp;
+use MooseX::Declare::Context::WithOptions 0.22;
+
+sub import
+{
+	carp "MooseX::Declare::Context::WithOptions->VERSION gt '0.35'"
+		if MooseX::Declare::Context::WithOptions->VERSION gt '0.35';
+}
+
+{
+	package  # hide from CPAN indexer
+	MooseX::Declare::Context::WithOptions;
+	
+	use Moose::Role;
+	use Carp qw(croak);
+	
+	no warnings 'redefine';
+	
+	has allowed_option_names => (
+		is       => 'rw',
+		isa      => 'ArrayRef',
+		lazy     => 1,
+		default  => sub { [qw[ extends with is ]] },
+	);
+	
+	sub strip_options {
+		my ($self) = @_;
+		my %ret;
+		
+		# Make errors get reported from right place in source file
+		local $Carp::Internal{'MooseX::Declare'} = 1;
+		local $Carp::Internal{'Devel::Declare'} = 1;
+		
+		$self->skipspace;
+		my $linestr = $self->get_linestr;
+		
+		while (substr($linestr, $self->offset, 1) !~ /[{;]/) {
+			my $key = $self->strip_name;
+			if (!defined $key) {
+				croak 'expected option name'
+					if keys %ret;
+				return; # This is the case when { class => 'foo' } happens
+			}
+			
+			croak "unknown option name '$key'"
+				unless grep { $key eq $_ } @{ $self->allowed_option_names }; ##DIFF
+			
+			my $val = $self->strip_name;
+			if (!defined $val) {
+				if (defined($val = $self->strip_proto)) {
+					$val = [split /\s*,\s*/, $val];
+				}
+				else {
+					 croak "expected option value after $key";
+				}
+			}
+			
+			$ret{$key} ||= [];
+			push @{ $ret{$key} }, ref $val ? @{ $val } : $val;
+		 } continue {
+			$self->skipspace;
+			$linestr = $self->get_linestr();
+		 }
+		
+		my $options = { map {
+			my $key = $_;
+			$key eq 'is'
+				? ($key => { map { ($_ => 1) } @{ $ret{$key} } })
+				: ($key => $ret{$key})
+		} keys %ret };
+		
+		$self->options($options);
+		
+		 return $options;
+	}
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+MooseX::Declare::Context::WithOptions::Patch::Extensible - patch MooseX::Declare for extensibility
+
+=head1 SYNOPSIS
+
+ use MooseX::Declare::Context::WithOptions::Patch::Extensible;
+
+=head1 DESCRIPTION
+
+This module extends MooseX::Declare::Context::WithOptions to add a new
+attribute C<allowed_option_names> containing an arrayref of option names
+that it can parse. The default is the standard MooseX::Declare list of
+'extends', 'with' and 'is'.
+
+It also patches the C<strip_options> method so that it pays attention to
+that arrayref.
+
+If you don't understand why you'd need to do this, then you probably don't
+need to do this.
+
+=head1 BUGS
+
+Please report any bugs to
+L<http://rt.cpan.org/Dist/Display.html?Queue=MooseX-Declare-Context-WithOptions-Patch-Extensible>.
+
+=head1 SEE ALSO
+
+C<MooseX::Declare>.
+
+=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-Declare-Context-WithOptions-Patch-Extensible 0.001 cpan:TOBYINK`
+	issued  2012-08-20;
+	label   "Initial release".
+
+# This file contains general metadata about the project.
+
+@prefix : <http://usefulinc.com/ns/doap#>.
+
+`MooseX-Declare-Context-WithOptions-Patch-Extensible`
+	:programming-language "Perl" ;
+	:shortdesc            "patch MooseX::Declare for extensibility";
+	:homepage             <https://metacpan.org/release/MooseX-Declare-Context-WithOptions-Patch-Extensible>;
+	:download-page        <https://metacpan.org/release/MooseX-Declare-Context-WithOptions-Patch-Extensible>;
+	:bug-database         <http://rt.cpan.org/Dist/Display.html?Queue=MooseX-Declare-Context-WithOptions-Patch-Extensible>;
+	:repository           [a :HgRepository; :browse <http://bitbucket.org/tobyink/p5-moosex-declare-context-withoptions-patch-extensible>];
+	:created              2012-08-20;
+	: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".
+
+cpan:TOBYINK
+	foaf:name  "Toby Inkster";
+	foaf:mbox  <mailto:tobyink@cpan.org>.
+

meta/makefile.pret

+# This file provides instructions for packaging.
+
+`MooseX-Declare-Context-WithOptions-Patch-Extensible`
+	perl_version_from m`MooseX::Declare::Context::WithOptions::Patch::Extensible`;
+	version_from      m`MooseX::Declare::Context::WithOptions::Patch::Extensible`;
+	readme_from       m`MooseX::Declare::Context::WithOptions::Patch::Extensible`;
+	requires          p`MooseX::Declare 0.30`;
+	test_requires     p`Test::More 0.61`.
+
+use Test::More tests => 1;
+BEGIN { use_ok('MooseX::Declare::Context::WithOptions::Patch::Extensible') };
+
+use MooseX::Declare;
+use MooseX::Declare::Context::WithOptions::Patch::Extensible;
+use Test::More tests => 5;
+
+{
+	package Local::Declare::Syntax::HavingApplication;
+	use Moose::Role;
+	
+	sub add_having_option_customizations
+	{
+		my ($self, $ctx, $package, $attribs) = @_;
+		my @code_parts;
+		push @code_parts, sprintf(
+			"has [%s] => (is => q/rw/, isa => q/Str/)\n",
+			join ', ',
+				map { "q/$_/" }
+				@{ ref $attribs ? $attribs : [$attribs] }
+			);
+		$ctx->add_scope_code_parts(@code_parts);
+		return 1;
+	}
+}
+
+BEGIN {
+	use Moose::Util qw/apply_all_roles/;
+	apply_all_roles('MooseX::Declare::Syntax::Keyword::Class',
+		'Local::Declare::Syntax::HavingApplication');
+	
+	MooseX::Declare::Context::WithOptions->meta->add_around_method_modifier(
+		allowed_option_names => sub
+			{
+				my ($orig, $self, $x) = @_;
+				if ($x)
+				{
+					push @$x, 'having';
+					return $self->$orig($x);
+				}
+				else
+				{
+					$x = $self->$orig();
+					push @$x, 'having';
+					return $x;
+				}
+			}
+		);
+}
+
+class Local::MyClass
+	having foo
+	having bar
+{
+	has baz => (is => 'rw', isa => 'Str');
+}
+
+can_ok('Local::MyClass', 'new');
+
+my $obj = Local::MyClass->new;
+can_ok($obj, 'foo');
+can_ok($obj, 'baz');
+can_ok($obj, 'bar');
+ok(!$obj->can('bat'), "Local::MyClass->can't('bat')");
+
+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 Test::More;
+use Test::Pod::Coverage;
+
+my @modules = qw(MooseX::Declare::Context::WithOptions::Patch::Extensible);
+pod_coverage_ok($_, "$_ is covered") for @modules;
+done_testing(scalar @modules);
+

xt/03meta_uptodate.t

+use Test::More tests => 1;
+use Test::RDF::DOAP::Version;
+doap_version_ok('MooseX-Declare-Context-WithOptions-Patch-Extensible', 'MooseX::Declare::Context::WithOptions::Patch::Extensible');
+
+use Test::EOL;
+all_perl_files_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.