Skip to content

Instantly share code, notes, and snippets.

@jjn1056
Created August 2, 2010 14:22
Show Gist options
  • Save jjn1056/504711 to your computer and use it in GitHub Desktop.
Save jjn1056/504711 to your computer and use it in GitHub Desktop.
John-Napiorkowski-MacBook-Pro:~ johnn$ diff -r -x .DS_Store -x.git ~/Desktop/catalyst-controller-actionrole/ ~/Desktop/bobtfish/catalyst-controller-actionrole/
diff -r -x .DS_Store -x.git /Users/johnn/Desktop/catalyst-controller-actionrole/Changes /Users/johnn/Desktop/bobtfish/catalyst-controller-actionrole/Changes
1,2d0
< 0.15 TBD
< * Added action_args support and Does parameterization
diff -r -x .DS_Store -x.git /Users/johnn/Desktop/catalyst-controller-actionrole/lib/Catalyst/Controller/ActionRole.pm /Users/johnn/Desktop/bobtfish/catalyst-controller-actionrole/lib/Catalyst/Controller/ActionRole.pm
40c40
< package MyApp::Controller::Bar;
---
> package MyApp::Controller::Bar
53d52
<
56,97d54
< Additionally roles could be applied to selected actions without specifying
< C<Does> using L<Catalyst::Controller/action> and configured with
< L<Catalyst::Controller/action_args>:
<
< package MyApp::Controller::Baz;
<
< use parent qw/Catalyst::Controller::ActionRole/;
<
< __PACKAGE__->config(
< action_roles => [qw( Foo )],
< action => {
< some_action => { Does => [qw( ~Bar )] },
< another_action => { Does => [qw( +MyActionRole::Baz )] },
< },
< action_args => {
< another_action => { custom_arg => 'arg1' },
< }
< );
<
< # has Catalyst::ActionRole::Foo and MyApp::ActionRole::Bar applied
< sub some_action : Local { ... }
<
< # has Catalyst::ActionRole::Foo and MyActionRole::Baz applied
< # and associated action class would get additional arguments passed
< sub another_action : Local { ... }
<
< Lastly, action_args can be applied on the action method level, if you prefer:
<
< package MyApp::Controller::Baz;
<
< use parent qw/Catalyst::Controller::ActionRole/;
<
< ## When the action is create, "custom_arg" is passed to the created
< ## action class. This is similar to the above example, except you can't
< ## centralize your configuration. You may prefer this for some cases.
< sub another_action
< :Local
< :Does(Foo[custom_arg=>'arg1'])
< {
< ## stuff to do ...
< }
<
126c83
< is => 'ro',
---
> traits => [qw(Array)],
128,129c85,89
< init_arg => undef,
< lazy_build => 1,
---
> init_arg => 'action_roles',
> default => sub { [] },
> handles => {
> _action_role_args => 'elements',
> },
144,156c104,105
< return $self->_action_role_args;
< }
<
< sub _build__action_role_args {
< my $self = shift;
< my @roles;
< if ( my $config = $self->config ) {
< if ( my $action_roles = $config->{action_roles} ) {
< @roles = $self->_expand_role_shortname(@$action_roles);
< Class::MOP::load_class($_) for @roles;
< }
< }
<
---
> my @roles = $self->_expand_role_shortname($self->_action_role_args);
> Class::MOP::load_class($_) for @roles;
163,164d111
< $self->_action_role_args;
< # check if action_roles are RoleNames
168,181d114
< sub _apply_action_class_roles {
< my ($self, $class, @roles) = @_;
<
< Class::MOP::load_class($_) for @roles;
< my $meta = Moose::Meta::Class->initialize($class)->create_anon_class(
< superclasses => [$class],
< roles => \@roles,
< cache => 1,
< );
< $meta->add_method(meta => sub { $meta });
<
< return $meta->name;
< }
<
183,184c116
< my $self = shift;
< my %args = @_;
---
> my ($self, %args) = @_;
186,211c118,134
< my $class = $self->action_class(%args);
< Moose->init_meta( for_class => $class)
< unless Class::MOP::does_metaclass_exist($class);
<
< my @roles = (
< (blessed $self ? $self->_action_roles : ()),
< @{ $args{attributes}->{Does} || [] },
< );
< my %role_args = ();
< @roles = map {
< if(ref $_) {
< %role_args = (%role_args, %{$_->[1]});
< $_->[0];
< } else {
< $_;
< }
< } @roles;
<
< $class = $self->_apply_action_class_roles($class, @roles) if @roles;
<
< my $action_args = $self->config->{action_args};
< my %extra_args = (
< %{ $action_args->{'*'} || {} },
< %{ $action_args->{ $args{name} } || {} },
< %role_args,
< );
---
> my $class = exists $args{attributes}->{ActionClass}
> ? $args{attributes}->{ActionClass}->[0]
> : $self->_action_class;
>
> Class::MOP::load_class($class);
>
> my @roles = ($self->_action_roles, @{ $args{attributes}->{Does} || [] });
> if (@roles) {
> Class::MOP::load_class($_) for @roles;
> my $meta = Moose::Meta::Class->initialize($class)->create_anon_class(
> superclasses => [$class],
> roles => \@roles,
> cache => 1,
> );
> $meta->add_method(meta => sub { $meta });
> $class = $meta->name;
> }
213c136
< return $class->new({ %extra_args, %args });
---
> return $class->new(\%args);
239,264c162
< my ($shortname, $args) = $self->_strip_args($value);
< return Does => [$self->_expand_role_shortname($shortname), $args];
< }
<
< sub _strip_args {
< my ($self, $value) = @_;
<
< ## mostly cargo culted from Moose::Util::TypeConstraints
< use re "eval";
<
< my $valid_chars = qr{[\+\~\w:\.]};
< my $type_atom = qr{ (?>$valid_chars+) }x;
< my $ws = qr{ (?>\s*) }x;
< my $type_capture_parts = qr{ ($type_atom) (?: \[(.+)\] )? }x;
<
< my ($shortname, $arg_str) = ($value =~ m{$type_capture_parts});
< my @args = $arg_str ? eval $arg_str : ();
< my %args;
< if(ref $args[0]) {
< ## deref if they did Does(Moo({a=>1}) or Moo([b=>2])
< %args = ref $args[0] eq 'HASH' ? %{$args[0]} : @{$args[0]};
< } else {
< %args = @args;
< }
<
< return ($shortname, \%args);
---
> return Does => $self->_expand_role_shortname($value);
Only in /Users/johnn/Desktop/catalyst-controller-actionrole/t: action-args.t
Only in /Users/johnn/Desktop/catalyst-controller-actionrole/t/lib/TestApp/ActionRole: Boo.pm
Only in /Users/johnn/Desktop/catalyst-controller-actionrole/t/lib/TestApp/Controller: Boo.pm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment