Private Chained Actions?

View: New views
10 Messages — Rating Filter:   Alert me  

Private Chained Actions?

by Marc Sebastian Pelzer-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I'd like to forward and/or detach to private actions which should be  
chained together, like:

sub hello_setup : Privat Chained {
   my ($self, $c) = @_

   $c->stash->{setup} = 'done';
}

sub hello : Private Chained('hello_setup') {
   my ($self, $c) = @_

   $c->res->body('hello! setup is ' . $c->stash->{setup});
}

sub index : Path : Args(0) {
   my ($self, $c) = @_

   $c->detach('hello');
}

This does actually not work. Only hello() is being called.

Has anyone an idea, how to make this work? Or is this just not  
supported (yet)?

Thanks, Marc :)

_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/

Re: Private Chained Actions?

by Aristotle Pagaltzis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

* Marc Sebastian Pelzer <marc@...> [2008-06-20 14:10]:

> I'd like to forward and/or detach to private actions which
> should be chained together, like:
>
> sub hello_setup : Privat Chained {
>   my ($self, $c) = @_
>
>   $c->stash->{setup} = 'done';
> }
>
> sub hello : Private Chained('hello_setup') {
>   my ($self, $c) = @_
>
>   $c->res->body('hello! setup is ' . $c->stash->{setup});
> }
>
> sub index : Path : Args(0) {
>   my ($self, $c) = @_
>
>   $c->detach('hello');
> }
>
> This does actually not work. Only hello() is being called.

You need a screwdriver, not a hammer.

    sub hello_setup : Private {
      my ($self, $c) = @_
      $c->stash->{setup} = 'done';
    }
   
    sub hello : Private {
      my ($self, $c) = @_
      $c->forward('hello_setup'); # <---------
      $c->res->body('hello! setup is ' . $c->stash->{setup});
    }
   
    sub index : Path : Args(0) {
      my ($self, $c) = @_
      $c->detach('hello');
    }

--
*AUTOLOAD=*_;sub _{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1}
&Just->another->Perl->hack;
#Aristotle Pagaltzis // <http://plasmasturm.org/>

_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/

Re: Re: Private Chained Actions?

by Marc Sebastian Pelzer-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


>> You need a screwdriver, not a hammer.
>
>    sub hello_setup : Private {
>      my ($self, $c) = @_
>      $c->stash->{setup} = 'done';
>    }
>
>    sub hello : Private {
>      my ($self, $c) = @_
>      $c->forward('hello_setup'); # <---------
>      $c->res->body('hello! setup is ' . $c->stash->{setup});
>    }
>
>    sub index : Path : Args(0) {
>      my ($self, $c) = @_
>      $c->detach('hello');
>    }


thanks for the hint. Thats what I'm doing right now. I thought that  
there may be a more elegant way of doing this. Especially for a longer/
more complex chained setup :) Also, doing it this way it does not look  
not too nice in the dispatcher path in the debug logfile - hello()  
comes before hello_setup() :-|

Thanks! Marc


_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/

Re: Private Chained Actions?

by Aristotle Pagaltzis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Marc,

* Marc Sebastian Pelzer <marc@...> [2008-06-20 18:25]:
> I thought that there may be a more elegant way of doing this.

it’s not very nice, no. But at least it works.

Maybe when the dispatcher is finally rewritten :-), forwarding to
the endpoint of a chain and having the entire chain run will be
possible.

I have tried creating a Catalyst::ActionChain and forwarding to
it, but that didn’t work. I have to say that I didn’t try very
hard, but that in turn is because even if it works, every caller
would have to specify the entire chain, making it not very useful
anyway.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>

_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/

Re: Re: Private Chained Actions?

by Jonathan Rockway :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

* On Fri, Jun 20 2008, Marc Sebastian Pelzer wrote:

>>> You need a screwdriver, not a hammer.
>>
>>    sub hello_setup : Private {
>>      my ($self, $c) = @_
>>      $c->stash->{setup} = 'done';
>>    }
>>
>>    sub hello : Private {
>>      my ($self, $c) = @_
>>      $c->forward('hello_setup'); # <---------
>>      $c->res->body('hello! setup is ' . $c->stash->{setup});
>>    }
>>
>>    sub index : Path : Args(0) {
>>      my ($self, $c) = @_
>>      $c->detach('hello');
>>    }
>
>
> thanks for the hint. Thats what I'm doing right now. I thought that
> there may be a more elegant way of doing this. Especially for a
> longer/ more complex chained setup :) Also, doing it this way it does
> not look  not too nice in the dispatcher path in the debug logfile -
> hello()  comes before hello_setup() :-|

Yeah, that's ugly.  What you really want are method modifiers:

    package MyApp::Controller::Foo;
    use Moose;
    BEGIN { extends 'Catalyst::Controller' };
   
    sub main_page :Path Args(0) {
        my ($self, $c) = @_;
        $self->hello($c);
    }
   
    sub hello {
        my ($self, $c) = @_;
        $c->res->body('hello! setup is'. $c->stash->{setup});
    }
   
    before hello => sub {
        my ($self, $c) = @_;
        $c->stash->{setup} = 'done';    
    };
   
    1;

You can also say:

   before [qw/method1 method2 method3 .../] => sub { ... }

to do something before a bunch of methods at once.  See "perldoc Moose"
for details.

Regards,
Jonathan Rockway

--
print just => another => perl => hacker => if $,=$"

_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/

Re: Private Chained Actions?

by Aristotle Pagaltzis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

* Jonathan Rockway <jon@...> [2008-06-20 22:20]:

> >>    sub hello_setup : Private {
> >>      my ($self, $c) = @_
> >>      $c->stash->{setup} = 'done';
> >>    }
> >>
> >>    sub hello : Private {
> >>      my ($self, $c) = @_
> >>      $c->forward('hello_setup'); # <---------
> >>      $c->res->body('hello! setup is ' . $c->stash->{setup});
> >>    }
> >>
> >>    sub index : Path : Args(0) {
> >>      my ($self, $c) = @_
> >>      $c->detach('hello');
> >>    }
>
> Yeah, that's ugly.  What you really want are method modifiers:
>
>     package MyApp::Controller::Foo;
>     use Moose;
>     BEGIN { extends 'Catalyst::Controller' };
>    
>     sub main_page :Path Args(0) {
>         my ($self, $c) = @_;
>         $self->hello($c);
>     }
>    
>     sub hello {
>         my ($self, $c) = @_;
>         $c->res->body('hello! setup is'. $c->stash->{setup});
>     }
>    
>     before hello => sub {
>         my ($self, $c) = @_;
>         $c->stash->{setup} = 'done';    
>     };
>    
>     1;

That’s even uglier. Imagine there isn’t just `hello` but half a
dozen other methods all sharing the same setup. So the setup code
is one or two screens down the source file. Now when you look at
`hello` you have absolutely no indication whatsoever that there
might be other code running before it. The only sane way to do
this would go something like this:

    package MyApp::Controller::Foo;
    use Moose;
    BEGIN { extends 'Catalyst::Controller' };
   
    sub main_page :Path Args(0) {
        my ($self, $c) = @_;
        $self->hello($c);
    }

    sub hello_setup {
        my ($self, $c) = @_;
        $c->stash->{setup} = 'done';    
    }
   
    before hello => \&hello_setup;
    sub hello {
        my ($self, $c) = @_;
        $c->res->body('hello! setup is'. $c->stash->{setup});
    }
   
    1;

By naming the setup method you can also avoid having to apply
the modifier to all of the methods at once.

Note that using method modifiers instead of Cat dispatch means
that the Catalyst::Stats breakdown of a request will be coarser.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>

_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/

Re: Re: Private Chained Actions?

by Jonathan Rockway :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

* On Fri, Jun 20 2008, Aristotle Pagaltzis wrote:
> * Jonathan Rockway <jon@...> [2008-06-20 22:20]:

>> Yeah, that's ugly.  What you really want are method modifiers:
>>
>>     package MyApp::Controller::Foo;
>>     use Moose;
>>     BEGIN { extends 'Catalyst::Controller' };
>>    
>>     sub main_page :Path Args(0) {
>>         my ($self, $c) = @_;
>>         $self->hello($c);
>>     }
>>    
>>     sub hello {
>>         my ($self, $c) = @_;
>>         $c->res->body('hello! setup is'. $c->stash->{setup});
>>     }
>>    
>>     before hello => sub {
>>         my ($self, $c) = @_;
>>         $c->stash->{setup} = 'done';    
>>     };
>>    
>>     1;
>
> That’s even uglier. Imagine there isn’t just `hello` but half a
> dozen other methods all sharing the same setup. So the setup code
> is one or two screens down the source file. Now when you look at
> `hello` you have absolutely no indication whatsoever that there
> might be other code running before it.

I guess.  But this is Perl, there's never any indication of anything.
There's no indication that my function is receiving arguments of a
particular type.  There's no indication that my function throws
exceptions.  There's no indication that "use Foo" has side effects.
Even in Catalyst, there is a ton of implicit behavior.  There is no
indication that begin/end/auto applies to my action (at least until the
action runs).

So in other words, I disagree with you.  I use method modifiers all the
time, and I (and others) have no problem maintaining code.  If you want
ultimate verbosity, just call hello_setup from hello.  If you think you
can keep a few method modifiers straight in your head, then use the
Moose approach.

TMTOWTDI.

> Note that using method modifiers instead of Cat dispatch means
> that the Catalyst::Stats breakdown of a request will be coarser.

The less my web framework does for me, the better.  If I want profiling,
I'll use DashProfiler.

Regards,
Jonathan Rockway

--
print just => another => perl => hacker => if $,=$"

_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/

Re: Private Chained Actions?

by Aristotle Pagaltzis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

* Jonathan Rockway <jon@...> [2008-06-22 15:35]:

> * On Fri, Jun 20 2008, Aristotle Pagaltzis wrote:
>> That’s even uglier. Imagine there isn’t just `hello` but half
>> a dozen other methods all sharing the same setup. So the setup
>> code is one or two screens down the source file. Now when you
>> look at `hello` you have absolutely no indication whatsoever
>> that there might be other code running before it.
>
> I guess. But this is Perl, there's never any indication of
> anything. There's no indication that my function is receiving
> arguments of a particular type.

Except, y’know, the code in the method body that’s *right there*.

> There's no indication that my function throws exceptions.

I hope you’re not using exceptions for standard control flow.

> There's no indication that "use Foo" has side effects.

Yes, and that causes no end of intermittent trouble. Ovid had
some recent posts on use.perl about getting bitten hard.

> Even in Catalyst, there is a ton of implicit behavior. There is
> no indication that begin/end/auto applies to my action (at
> least until the action runs).

Except, method modifiers are explicit, not implicit – just
defined at a distance, the way you wrote it. In contrast, if you
use Catalyst you know that there may always be begin/end/auto
actions.

I mean, if you have to write out your intent to modify a method
anyway, why not also put that next to the code that will actually
be affected?

I recommend Schwern’s recent “Skimmable Code” talk.

Note well, I’m not arguing against method modifiers in general.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>

_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/

Re: Re: Private Chained Actions?

by Ash Berlin-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 22 Jun 2008, at 18:56, Aristotle Pagaltzis wrote:

> * Jonathan Rockway <jon@...> [2008-06-22 15:35]:
>> * On Fri, Jun 20 2008, Aristotle Pagaltzis wrote:
>>> That’s even uglier. Imagine there isn’t just `hello` but half
>>> a dozen other methods all sharing the same setup. So the setup
>>> code is one or two screens down the source file. Now when you
>>> look at `hello` you have absolutely no indication whatsoever
>>> that there might be other code running before it.
>>
>> I guess. But this is Perl, there's never any indication of
>> anything. There's no indication that my function is receiving
>> arguments of a particular type.
>
> Except, y’know, the code in the method body that’s *right there*.
>
>> There's no indication that my function throws exceptions.
>
> I hope you’re not using exceptions for standard control flow.
>
>> There's no indication that "use Foo" has side effects.
>
> Yes, and that causes no end of intermittent trouble. Ovid had
> some recent posts on use.perl about getting bitten hard.
>
>> Even in Catalyst, there is a ton of implicit behavior. There is
>> no indication that begin/end/auto applies to my action (at
>> least until the action runs).
>
> Except, method modifiers are explicit, not implicit – just
> defined at a distance, the way you wrote it. In contrast, if you
> use Catalyst you know that there may always be begin/end/auto
> actions.
>
> I mean, if you have to write out your intent to modify a method
> anyway, why not also put that next to the code that will actually
> be affected?
>
> I recommend Schwern’s recent “Skimmable Code” talk.
>
> Note well, I’m not arguing against method modifiers in general.
>
> Regards,

FWIW I also think that the method modifiers makes it harder to skim  
the code, since most of the time you find the end action then look up  
the chain to see what is happening (at least I do) - method modifiers  
make this a much harder thing to find.

-ash


_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/

Re: Re: Private Chained Actions?

by Marc Sebastian Pelzer-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hola,

to catch up with this topic, I'd like to mention that using moose  
seems to eat some extra CPU cycles. I'm not sure how good this  
performs in a high-load situation. So I'm going to stick with the $c-
 >forward('hello_setup'); way. Nevertheless, it would be great if,  
some day, chained private actions would be implemented within the  
appropriate chain-module.

Thanks, Marc


> * Jonathan Rockway <jon@...> [2008-06-20 22:20]:
>>>>   sub hello_setup : Private {
>>>>     my ($self, $c) = @_
>>>>     $c->stash->{setup} = 'done';
>>>>   }
>>>>
>>>>   sub hello : Private {
>>>>     my ($self, $c) = @_
>>>>     $c->forward('hello_setup'); # <---------
>>>>     $c->res->body('hello! setup is ' . $c->stash->{setup});
>>>>   }
>>>>
>>>>   sub index : Path : Args(0) {
>>>>     my ($self, $c) = @_
>>>>     $c->detach('hello');
>>>>   }
>>
>> Yeah, that's ugly.  What you really want are method modifiers:
>>
>>    package MyApp::Controller::Foo;
>>    use Moose;
>>    BEGIN { extends 'Catalyst::Controller' };
>>
>>    sub main_page :Path Args(0) {
>>        my ($self, $c) = @_;
>>        $self->hello($c);
>>    }
>>
>>    sub hello {
>>        my ($self, $c) = @_;
>>        $c->res->body('hello! setup is'. $c->stash->{setup});
>>    }
>>
>>    before hello => sub {
>>        my ($self, $c) = @_;
>>        $c->stash->{setup} = 'done';
>>    };
>>
>>    1;
>
> That’s even uglier. Imagine there isn’t just `hello` but half a
> dozen other methods all sharing the same setup. So the setup code
> is one or two screens down the source file. Now when you look at
> `hello` you have absolutely no indication whatsoever that there
> might be other code running before it. The only sane way to do
> this would go something like this:
>
>    package MyApp::Controller::Foo;
>    use Moose;
>    BEGIN { extends 'Catalyst::Controller' };
>
>    sub main_page :Path Args(0) {
>        my ($self, $c) = @_;
>        $self->hello($c);
>    }
>
>    sub hello_setup {
>        my ($self, $c) = @_;
>        $c->stash->{setup} = 'done';
>    }
>
>    before hello => \&hello_setup;
>    sub hello {
>        my ($self, $c) = @_;
>        $c->res->body('hello! setup is'. $c->stash->{setup});
>    }
>
>    1;
>
> By naming the setup method you can also avoid having to apply
> the modifier to all of the methods at once.
>
> Note that using method modifiers instead of Cat dispatch means
> that the Catalyst::Stats breakdown of a request will be coarser.


_______________________________________________
List: Catalyst@...
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@.../
Dev site: http://dev.catalyst.perl.org/