Perl, Haskell, stuff
use MooseX::Declare;
class MyApp::Status {
has 'user' => (
isa => Maybe[ MyApp::User ],
predicate => 'is_logged_in',
is => 'rw',
coerce => 1,
);
coerce 'MyApp::User'
=> from 'Str'
=> via { return MyApp::User->from_name($_) };
coerce 'MyApp::User'
=> from 'Int'
=> via { return MyApp::User->from_id($_) };
... # other global status things
}
This way we get lots of modern/enlightened/whatever Perl OO niceties
like coercion, and methods built for free, like is_logged_in.
We could also provide a custom accessor that didn't allow the user to be
updated if it's already been set, etc.
/client1/documents/invoices/23might build a chain like this:
method handle client1_documents_invoices ($invoice_number) {
$self->login or return;
$self->check_is_admin or return;
my %client_args = $self->do_client1_customizations;
my %template_args = (
$self->document_template_setup(%client_args),
$self->invoice_template_setup (%client_args),
$self->fetch_invoice( $invoice_number ),
);
$self->process_template( %template_args );
}
That would be ridiculous, as you'd have hundreds of such methods... one
of the major selling points of a framework is to allow you to combine
these little pieces flexibly and elegantly. So you end up with the
elements in the chain as separate actions... But how do we manage the
flow of data between these items (the %template_args and %client_args in
my contrived example above, for example) ?
We use the stash of course! So each action can read the values it needs
from the stash, and write things later actions will need back into it.
method an_action_in_a_long_chain () {
my $foo = $c->stash->{foo};
my $bar = do_something_to( $foo );
$c->stash->bar( $bar );
}
Hurray! Except that you may have noticed that we've reinvented passing
formal parameters and return values using global data. Welcome to 1959,
enjoy your stay in COBOL!
And of course, if we get parameters via the stash, we lose the benefits
of typing. And we have to be really certain that the bit of global data
we want has been set by the time our action gets called. And, because
we have a global namespace, we have to hope that some other action in
the meantime hasn't set the value to the wrong sort of data.
It also leads to us thinking about our data as singletons. When we
realise later that we need to call an action on two separate objects,
what do we do? We only have one global slot for the parameter name, so
we now have to set it twice (or localize it), and we have to squirrel
away the first return value before it gets overwritten (yuck)!
Spaghetti and action-at-a-distance may not be the intent of the stash,
but they do feel like the logical progression of the concept to me.
$c->stash = {
# set by a navigation component
breadcrumb => [ 'client1', 'documents', 'invoices' ],
menu_items => [ 'save', 'edit', 'delete' ],
# set by the login action
username => 'osfameron',
usertype => 'admin',
# set by the invoice action
invoice_data => $MyApp::Model::Invoice,
...
};
Again though, what's to prevent one action from stomping over the
other's data? Will the template die if it gets a hash for
invoice_data instead of a MyApp::Model::Invoice
object? What happens if some data it was expecting never got set?
What's the alternative? I suspect that a "widget" approach might be
saner, and I have to confess I still haven't looked at Reaction yet:
perhaps that's what I'm looking for?
Osfameron's blog on Haskell, Perl programming, stuff.
Greg
June 5th, 2009 at 2:11 am
Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier '|' in /var/www/blog/wp-content/plugins/text-control/text-control/markdown.php on line 766
Chris Eidhof
June 5th, 2009 at 10:02 am
Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier '|' in /var/www/blog/wp-content/plugins/text-control/text-control/markdown.php on line 766
Programmer
July 9th, 2009 at 4:51 pm
Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier '|' in /var/www/blog/wp-content/plugins/text-control/text-control/markdown.php on line 766
Ash Berlin
July 10th, 2009 at 12:15 pm
Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier '|' in /var/www/blog/wp-content/plugins/text-control/text-control/markdown.php on line 766
Aaron Trevena
July 10th, 2009 at 12:24 pm
Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier '|' in /var/www/blog/wp-content/plugins/text-control/text-control/markdown.php on line 766
dima
January 23rd, 2010 at 8:43 am
Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier '|' in /var/www/blog/wp-content/plugins/text-control/text-control/markdown.php on line 766